diff --git a/drivers/video/fbdev/msm/mdss_dba_utils.c b/drivers/video/fbdev/msm/mdss_dba_utils.c index 3330f8f62b78..c6ff92ed1686 100644 --- a/drivers/video/fbdev/msm/mdss_dba_utils.c +++ b/drivers/video/fbdev/msm/mdss_dba_utils.c @@ -576,7 +576,6 @@ int mdss_dba_utils_video_on(void *data, struct mdss_panel_info *pinfo) video_cfg.h_pulse_width = pinfo->lcdc.h_pulse_width; video_cfg.v_pulse_width = pinfo->lcdc.v_pulse_width; video_cfg.pclk_khz = (unsigned long)pinfo->clk_rate / 1000; - video_cfg.hdmi_mode = !hdmi_edid_is_dvi_mode(ud->edid_data); /* Calculate number of DSI lanes configured */ video_cfg.num_of_input_lanes = 0; @@ -592,6 +591,8 @@ int mdss_dba_utils_video_on(void *data, struct mdss_panel_info *pinfo) /* Get scan information from EDID */ video_cfg.vic = mdss_dba_get_vic_panel_info(ud, pinfo); ud->current_vic = video_cfg.vic; + video_cfg.hdmi_mode = hdmi_edid_get_sink_mode(ud->edid_data, + video_cfg.vic); video_cfg.scaninfo = hdmi_edid_get_sink_scaninfo(ud->edid_data, video_cfg.vic); if (ud->ops.video_on) diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 40a79c4af38e..31cba148ad28 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -3607,6 +3607,16 @@ static void mdss_fb_var_to_panelinfo(struct fb_var_screeninfo *var, */ if (pinfo->is_dba_panel) pinfo->mipi.dsi_pclk_rate = pinfo->clk_rate; + + if (var->sync & FB_SYNC_HOR_HIGH_ACT) + pinfo->lcdc.h_polarity = 0; + else + pinfo->lcdc.h_polarity = 1; + + if (var->sync & FB_SYNC_VERT_HIGH_ACT) + pinfo->lcdc.v_polarity = 0; + else + pinfo->lcdc.v_polarity = 1; } void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index 102c22cba7dd..ddc5edbe010d 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -62,11 +62,6 @@ #define EDID_VENDOR_ID_SIZE 4 #define EDID_IEEE_REG_ID 0x0c03 -enum edid_sink_mode { - SINK_MODE_DVI, - SINK_MODE_HDMI -}; - enum luminance_value { NO_LUMINANCE_DATA = 3, MAXIMUM_LUMINANCE = 4, @@ -2406,7 +2401,7 @@ end: return scaninfo; } /* hdmi_edid_get_sink_scaninfo */ -static u32 hdmi_edid_get_sink_mode(void *input) +u32 hdmi_edid_get_sink_mode(void *input, u32 mode) { struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; bool sink_mode; @@ -2419,8 +2414,13 @@ static u32 hdmi_edid_get_sink_mode(void *input) if (edid_ctrl->edid_override && (edid_ctrl->override_data.sink_mode != -1)) sink_mode = edid_ctrl->override_data.sink_mode; - else - sink_mode = edid_ctrl->sink_mode; + else { + if (edid_ctrl->sink_mode && + (mode > 0 && mode <= HDMI_EVFRMT_END)) + sink_mode = SINK_MODE_HDMI; + else + sink_mode = SINK_MODE_DVI; + } return sink_mode; } /* hdmi_edid_get_sink_mode */ @@ -2435,10 +2435,21 @@ static u32 hdmi_edid_get_sink_mode(void *input) */ bool hdmi_edid_is_dvi_mode(void *input) { - if (hdmi_edid_get_sink_mode(input)) - return false; - else + struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; + int sink_mode; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); return true; + } + + if (edid_ctrl->edid_override && + (edid_ctrl->override_data.sink_mode != -1)) + sink_mode = edid_ctrl->override_data.sink_mode; + else + sink_mode = edid_ctrl->sink_mode; + + return (sink_mode == SINK_MODE_DVI); } /** diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h index af802bb45f89..c604d0fbf7b2 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h @@ -58,10 +58,16 @@ struct hdmi_edid_override_data { int vic; }; +enum edid_sink_mode { + SINK_MODE_DVI, + SINK_MODE_HDMI +}; + int hdmi_edid_parser(void *edid_ctrl); u32 hdmi_edid_get_raw_data(void *edid_ctrl, u8 *buf, u32 size); u8 hdmi_edid_get_sink_scaninfo(void *edid_ctrl, u32 resolution); bool hdmi_edid_is_dvi_mode(void *input); +u32 hdmi_edid_get_sink_mode(void *edid_ctrl, u32 mode); bool hdmi_edid_sink_scramble_override(void *input); bool hdmi_edid_get_sink_scrambler_support(void *input); bool hdmi_edid_get_scdc_support(void *input); diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 07592fa26a49..a9ab970fb4bc 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -66,7 +66,7 @@ #define HDMI_TX_4_MAX_PCLK_RATE 600000 #define hdmi_tx_get_fd(x) ((x && (ffs(x) > 0)) ? \ - hdmi_ctrl->feature_data[ffs(x) - 1] : 0) + hdmi_ctrl->feature_data[ffs(x) - 1] : NULL) #define hdmi_tx_set_fd(x, y) {if (x && (ffs(x) > 0)) \ hdmi_ctrl->feature_data[ffs(x) - 1] = y; } @@ -375,9 +375,12 @@ static void hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl) } } -static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl) +static inline bool hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl) { - return hdmi_edid_is_dvi_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID)); + void *data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); + + return (hdmi_edid_get_sink_mode(data, + hdmi_ctrl->vic) == SINK_MODE_DVI); } /* hdmi_tx_is_dvi_mode */ static inline u32 hdmi_tx_is_in_splash(struct hdmi_tx_ctrl *hdmi_ctrl) @@ -2156,6 +2159,8 @@ static int hdmi_tx_init_panel_info(struct hdmi_tx_ctrl *hdmi_ctrl) pinfo->lcdc.v_front_porch = timing.front_porch_v; pinfo->lcdc.v_pulse_width = timing.pulse_width_v; pinfo->lcdc.frame_rate = timing.refresh_rate; + pinfo->lcdc.h_polarity = timing.active_low_h; + pinfo->lcdc.v_polarity = timing.active_low_v; pinfo->type = DTV_PANEL; pinfo->pdest = DISPLAY_3; @@ -2442,6 +2447,7 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on) struct dss_io_data *io = NULL; /* Defaults: Disable block, HDMI mode */ u32 hdmi_ctrl_reg = BIT(1); + void *data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); if (!hdmi_ctrl) { DEV_ERR("%s: invalid input\n", __func__); @@ -2470,7 +2476,8 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on) hdmi_ctrl_reg |= BIT(2); /* Set transmission mode to DVI based in EDID info */ - if (hdmi_edid_is_dvi_mode(hdmi_tx_get_fd(HDMI_TX_FEAT_EDID))) + if (hdmi_edid_get_sink_mode(data, + hdmi_ctrl->vic) == SINK_MODE_DVI) hdmi_ctrl_reg &= ~BIT(1); /* DVI mode */ /* @@ -2929,7 +2936,6 @@ static int hdmi_tx_audio_info_setup(struct platform_device *pdev, { int rc = 0; struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev); - u32 is_mode_dvi; if (!hdmi_ctrl || !params) { DEV_ERR("%s: invalid input\n", __func__); @@ -2938,9 +2944,8 @@ static int hdmi_tx_audio_info_setup(struct platform_device *pdev, mutex_lock(&hdmi_ctrl->tx_lock); - is_mode_dvi = hdmi_tx_is_dvi_mode(hdmi_ctrl); - - if (!is_mode_dvi && hdmi_tx_is_panel_on(hdmi_ctrl)) { + if (!hdmi_tx_is_dvi_mode(hdmi_ctrl) && + hdmi_tx_is_panel_on(hdmi_ctrl)) { memcpy(&hdmi_ctrl->audio_params, params, sizeof(struct msm_ext_disp_audio_setup_params)); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 587150bbc9fa..d9aaac4526ea 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -58,6 +58,8 @@ struct intf_timing_params { u32 v_front_porch; u32 hsync_pulse_width; u32 vsync_pulse_width; + u32 h_polarity; + u32 v_polarity; u32 border_clr; u32 underflow_clr; @@ -641,13 +643,8 @@ static int mdss_mdp_video_timegen_setup(struct mdss_mdp_ctl *ctl, display_hctl = (hsync_end_x << 16) | hsync_start_x; den_polarity = 0; - if (MDSS_INTF_HDMI == ctx->intf_type) { - hsync_polarity = p->yres >= 720 ? 0 : 1; - vsync_polarity = p->yres >= 720 ? 0 : 1; - } else { - hsync_polarity = 0; - vsync_polarity = 0; - } + hsync_polarity = p->h_polarity; + vsync_polarity = p->v_polarity; polarity_ctl = (den_polarity << 2) | /* DEN Polarity */ (vsync_polarity << 1) | /* VSYNC Polarity */ (hsync_polarity << 0); /* HSYNC Polarity */ @@ -2178,7 +2175,8 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, itp->width = dsc->pclk_per_line; itp->xres = dsc->pclk_per_line; } - + itp->h_polarity = pinfo->lcdc.h_polarity; + itp->v_polarity = pinfo->lcdc.v_polarity; itp->h_back_porch = pinfo->lcdc.h_back_porch; itp->h_front_porch = pinfo->lcdc.h_front_porch; itp->v_back_porch = pinfo->lcdc.v_back_porch; diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 37b0ca7aa44b..e8255ff45726 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -406,9 +406,10 @@ struct lcd_panel_info { /* Pad height */ u32 yres_pad; u32 frame_rate; + u32 h_polarity; + u32 v_polarity; }; - /* DSI PHY configuration */ struct mdss_dsi_phy_ctrl { char regulator[7]; /* 8996, 1 * 5 */