OSDN Git Service

msm: mdss: display-port: add support to configure pixel and link rates
authorChandan Uddaraju <chandanu@codeaurora.org>
Fri, 15 Jul 2016 15:13:13 +0000 (08:13 -0700)
committerGerrit - the friendly Code Review server <code-review@localhost>
Fri, 29 Jul 2016 07:16:44 +0000 (00:16 -0700)
Use the DPCD info to configure pixel and link rates
supported by the sink.

Change-Id: Idd7ba4b564b013eda7596a111b9b934f6b6ff84f
Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org>
drivers/video/fbdev/msm/mdss_dp.c
drivers/video/fbdev/msm/mdss_dp.h
drivers/video/fbdev/msm/mdss_dp_aux.c

index 24dacab..c4b2562 100644 (file)
@@ -906,6 +906,26 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
                mdss_dp_irq_enable(dp_drv);
                pr_debug("irq enabled\n");
                mdss_dp_dpcd_cap_read(dp_drv);
+               dp_drv->link_rate =
+                       mdss_dp_gen_link_clk(&dp_drv->panel_data.panel_info,
+                                               dp_drv->dpcd.max_lane_count);
+
+               pr_debug("link_rate=0x%x, Max rate supported by sink=0x%x\n",
+                              dp_drv->link_rate, dp_drv->dpcd.max_link_rate);
+               if (!dp_drv->link_rate) {
+                       pr_err("Unable to configure required link rate\n");
+                       return -EINVAL;
+               }
+
+               pr_debug("link_rate = 0x%x\n", dp_drv->link_rate);
+
+               dp_drv->power_data[DP_CTRL_PM].clk_config[0].rate =
+                               dp_drv->link_rate * DP_LINK_RATE_MULTIPLIER;
+
+               dp_drv->pixel_rate = dp_drv->panel_data.panel_info.clk_rate;
+               dp_drv->power_data[DP_CTRL_PM].clk_config[3].rate =
+                                                       dp_drv->pixel_rate;
+
                ret = mdss_dp_clk_ctrl(dp_drv, DP_CTRL_PM, true);
                if (ret) {
                        mdss_dp_clk_ctrl(dp_drv, DP_CORE_PM, false);
index 9d129d0..6bf4aae 100644 (file)
@@ -164,6 +164,8 @@ enum dp_pm_type {
 #define DP_LINK_RATE_540       20      /* 5.40G = 270M * 20 */
 #define DP_LINK_RATE_MAX       DP_LINK_RATE_540
 
+#define DP_LINK_RATE_MULTIPLIER        27000000
+
 struct dpcd_cap {
        char major;
        char minor;
@@ -388,5 +390,6 @@ void mdss_dp_fill_link_cfg(struct mdss_dp_drv_pdata *ep);
 void mdss_dp_sink_power_down(struct mdss_dp_drv_pdata *ep);
 void mdss_dp_lane_power_ctrl(struct mdss_dp_drv_pdata *ep, int up);
 void mdss_dp_config_ctrl(struct mdss_dp_drv_pdata *ep);
+char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt);
 
 #endif /* MDSS_DP_H */
index b51bf31..ba03ca6 100644 (file)
@@ -484,6 +484,37 @@ void dp_extract_edid_feature(struct edp_edid *edid, char *buf)
                        edid->dpm, edid->color_format);
 };
 
+char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt)
+{
+       const u32 encoding_factx10 = 8;
+       const u32 ln_to_link_ratio = 10;
+       u32 min_link_rate;
+       char calc_link_rate = 0;
+
+       pr_debug("clk_rate=%llu, bpp= %d, lane_cnt=%d\n",
+              pinfo->clk_rate, pinfo->bpp, lane_cnt);
+       min_link_rate = (pinfo->clk_rate * 10) /
+               (lane_cnt * encoding_factx10);
+       min_link_rate = (min_link_rate * pinfo->bpp)
+                               / (DP_LINK_RATE_MULTIPLIER);
+       min_link_rate /= ln_to_link_ratio;
+
+       pr_debug("min_link_rate = %d\n", min_link_rate);
+
+       if (min_link_rate <= DP_LINK_RATE_162)
+               calc_link_rate = DP_LINK_RATE_162;
+       else if (min_link_rate <= DP_LINK_RATE_270)
+               calc_link_rate = DP_LINK_RATE_270;
+       else if (min_link_rate <= DP_LINK_RATE_540)
+               calc_link_rate = DP_LINK_RATE_540;
+       else {
+               pr_err("link_rate = %d is unsupported\n", min_link_rate);
+               calc_link_rate = 0;
+       }
+
+       return calc_link_rate;
+}
+
 void dp_extract_edid_detailed_timing_description(struct edp_edid *edid,
                char *buf)
 {