diff options
| author | Dhaval Patel <pdhaval@codeaurora.org> | 2015-04-29 15:19:16 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:40:58 -0700 |
| commit | fae000ced6efc79a0c94293509d6e66dbc89f697 (patch) | |
| tree | 3799e5766ca20442ac5a2e059ec64e3d68a4d2af | |
| parent | e863be17edb24e36224bf2ad980bfefc95e0c906 (diff) | |
msm: mdss: use u64 instead of u32 for bitclock rate calculation
Bitclock calculation for high resolution panel overflows the
32bit variable which causes invalid pixel clock and byte clock
setting. Updating it to 64bit fixes the overflow issue.
Change-Id: If1f6fa3200783b87022366580fc18bfe6e3ddd8d
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
| -rw-r--r-- | Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_host_v2.c | 14 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.h | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_host.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_panel.c | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_panel.h | 15 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_mdss_io_8974.c | 24 |
9 files changed, 53 insertions, 34 deletions
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index e50ade24be0f..d76e45298e0a 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -263,7 +263,7 @@ Optional properties: "trigger_sw_te" = Software trigger and TE - qcom,mdss-dsi-panel-framerate: Specifies the frame rate for the panel. 60 = 60 frames per second (default) -- qcom,mdss-dsi-panel-clockrate: Specifies the panel clock speed in Hz. +- qcom,mdss-dsi-panel-clockrate: A 64 bit value specifies the panel clock speed in Hz. 0 = default value. - qcom,mdss-dsi-on-command-state: String that specifies the ctrl state for sending ON commands. "dsi_lp_mode" = DSI low power mode (default) diff --git a/drivers/video/fbdev/msm/dsi_host_v2.c b/drivers/video/fbdev/msm/dsi_host_v2.c index 2fa772a32a57..5d6fb8569716 100644 --- a/drivers/video/fbdev/msm/dsi_host_v2.c +++ b/drivers/video/fbdev/msm/dsi_host_v2.c @@ -1028,7 +1028,7 @@ int msm_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp) } static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata, - u32 *bitclk_rate, + u64 *bitclk_rate, u32 *dsiclk_rate, u32 *byteclk_rate, u32 *pclk_rate) @@ -1037,6 +1037,7 @@ static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata, struct mipi_panel_info *mipi; u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; int lanes; + u64 clk_rate; pinfo = &pdata->panel_info; mipi = &pdata->panel_info.mipi; @@ -1065,9 +1066,11 @@ static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata, *bitclk_rate = (width + hbp + hfp + hspw) * (height + vbp + vfp + vspw); *bitclk_rate *= mipi->frame_rate; *bitclk_rate *= pdata->panel_info.bpp; - *bitclk_rate /= lanes; + do_div(*bitclk_rate, lanes); + clk_rate = *bitclk_rate; - *byteclk_rate = *bitclk_rate / 8; + do_div(clk_rate, 8U); + *byteclk_rate = (u32) clk_rate; *dsiclk_rate = *byteclk_rate * lanes; *pclk_rate = *byteclk_rate * lanes * 8 / pdata->panel_info.bpp; @@ -1079,13 +1082,14 @@ static int msm_dsi_cal_clk_rate(struct mdss_panel_data *pdata, static int msm_dsi_on(struct mdss_panel_data *pdata) { int ret = 0, i; - u32 clk_rate; + u64 clk_rate; struct mdss_panel_info *pinfo; struct mipi_panel_info *mipi; u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; u32 ystride, bpp, data; u32 dummy_xres, dummy_yres; - u32 bitclk_rate = 0, byteclk_rate = 0, pclk_rate = 0, dsiclk_rate = 0; + u64 bitclk_rate = 0 + u32 byteclk_rate = 0, pclk_rate = 0, dsiclk_rate = 0; unsigned char *ctrl_base = dsi_host_private->dsi_base; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index f14ad88e7fe2..4cee97ed3ff8 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -1137,6 +1137,7 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, { int rc = 0; u32 data; + u64 clk_rate; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; if (pdata == NULL) { @@ -1165,8 +1166,9 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, __mdss_dsi_calc_dfps_delay(pdata); ctrl_pdata->pclk_rate = pdata->panel_info.mipi.dsi_pclk_rate; - ctrl_pdata->byte_clk_rate = - pdata->panel_info.clk_rate / 8; + clk_rate = pdata->panel_info.clk_rate; + do_div(clk_rate, 8U); + ctrl_pdata->byte_clk_rate = (u32) clk_rate; pr_debug("byte_rate=%i\n", ctrl_pdata->byte_clk_rate); pr_debug("pclk_rate=%i\n", ctrl_pdata->pclk_rate); @@ -1223,8 +1225,9 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, } else { ctrl_pdata->pclk_rate = pdata->panel_info.mipi.dsi_pclk_rate; - ctrl_pdata->byte_clk_rate = - pdata->panel_info.clk_rate / 8; + clk_rate = pdata->panel_info.clk_rate; + do_div(clk_rate, 8U); + ctrl_pdata->byte_clk_rate = (u32) clk_rate; } return rc; @@ -1922,6 +1925,7 @@ int dsi_panel_device_register(struct device_node *pan_node, struct device_node *dsi_ctrl_np = NULL; struct platform_device *ctrl_pdev = NULL; const char *data; + u64 clk_rate; struct resource *res; mipi = &(pinfo->mipi); @@ -2136,7 +2140,9 @@ int dsi_panel_device_register(struct device_node *pan_node, } ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate; - ctrl_pdata->byte_clk_rate = pinfo->clk_rate / 8; + clk_rate = pinfo->clk_rate; + do_div(clk_rate, 8U); + ctrl_pdata->byte_clk_rate = (u32)clk_rate; pr_debug("%s: pclk=%d, bclk=%d\n", __func__, ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate); diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 133c1790cdb3..7d82b6029866 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -204,7 +204,7 @@ extern u32 dsi_irq; extern struct mdss_dsi_ctrl_pdata *ctrl_list[]; struct dsiphy_pll_divider_config { - u32 clk_rate; + u64 clk_rate; u32 fb_divider; u32 ref_divider_ratio; u32 bit_clk_divider; /* oCLK1 */ diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 918a6e0921c4..c6e251d8e2d4 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -1060,7 +1060,7 @@ static void mdss_dsi_mode_setup(struct mdss_panel_data *pdata) struct mdss_panel_info *pinfo; struct mipi_panel_info *mipi; struct dsc_desc *dsc = NULL; - u32 clk_rate; + u64 clk_rate; u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; u32 ystride, bpp, dst_bpp; u32 stream_ctrl, stream_total; diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 5fccab2c299a..d6e767ecac17 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -2030,8 +2030,9 @@ static int mdss_panel_parse_dt(struct device_node *np, rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-framerate", &tmp); pinfo->mipi.frame_rate = (!rc ? tmp : 60); - rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-clockrate", &tmp); - pinfo->clk_rate = (!rc ? tmp : 0); + pinfo->clk_rate = 0; + of_property_read_u64(np, "qcom,mdss-dsi-panel-clockrate", + &pinfo->clk_rate); data = of_get_property(np, "qcom,mdss-dsi-panel-timings", &len); if ((!data) || (len != 12)) { pr_err("%s:%d, Unable to read Phy timing settings", diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 2cc566981a20..add1b9e332de 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -2012,6 +2012,7 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; int *id; + u64 clk_rate; /* * fb info initialization @@ -2165,7 +2166,9 @@ static int mdss_fb_register(struct msm_fb_data_type *mfd) var->left_margin = panel_info->lcdc.h_back_porch; var->right_margin = panel_info->lcdc.h_front_porch; var->hsync_len = panel_info->lcdc.h_pulse_width; - var->pixclock = panel_info->clk_rate / 1000; + clk_rate = panel_info->clk_rate; + do_div(clk_rate, 1000U); + var->pixclock = (u32) clk_rate; /* * Populate smem length here for uspace to get the @@ -3076,7 +3079,7 @@ static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, var->right_margin = pinfo->lcdc.h_front_porch; var->left_margin = pinfo->lcdc.h_back_porch; var->hsync_len = pinfo->lcdc.h_pulse_width; - var->pixclock = pinfo->clk_rate; + var->pixclock = (u32)pinfo->clk_rate; } /** diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 1b016dc5305d..fc8ecf9545c8 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -465,9 +465,9 @@ struct mdss_panel_info { u32 bl_max; u32 bl_min; u32 fb_num; - u32 clk_rate; + u64 clk_rate; u32 clk_min; - u32 clk_max; + u64 clk_max; u32 frame_count; u32 is_3d_panel; u32 out_format; @@ -571,6 +571,7 @@ struct mdss_panel_debugfs_info { static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info) { u32 frame_rate, pixel_total; + u64 rate; if (panel_info == NULL) return DEFAULT_FRAME_RATE; @@ -595,11 +596,13 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info) panel_info->lcdc.v_front_porch + panel_info->lcdc.v_pulse_width + panel_info->yres); - if (pixel_total) - frame_rate = panel_info->clk_rate / pixel_total; - else + if (pixel_total) { + rate = panel_info->clk_rate; + do_div(rate, pixel_total); + frame_rate = (u32)rate; + } else { frame_rate = DEFAULT_FRAME_RATE; - + } break; } return frame_rate; diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 5da6a0ddcb14..e447cb4f5e5b 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -809,7 +809,7 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, u32 fb_divider, rate, vco; u32 div_ratio = 0; u32 pll_analog_posDiv = 1; - u32 h_period, v_period; + u64 h_period, v_period, clk_rate; u32 dsi_pclk_rate; u8 lanes = 0, bpp; struct dsi_clk_mnd_table const *mnd_entry = mnd_table; @@ -845,24 +845,25 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, panel_info->mipi.frame_rate) || (!panel_info->clk_rate)) { if (lanes > 0) { - panel_info->clk_rate = - ((h_period * v_period * - frame_rate * bpp * 8) - / lanes); + panel_info->clk_rate = h_period * v_period * frame_rate + * bpp * 8; + do_div(panel_info->clk_rate, lanes); } else { pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__); panel_info->clk_rate = - (h_period * v_period * frame_rate * bpp * 8); + h_period * v_period * frame_rate * bpp * 8; } } pll_divider_config.clk_rate = panel_info->clk_rate; - if (pll_divider_config.clk_rate == 0) pll_divider_config.clk_rate = 454000000; - rate = (pll_divider_config.clk_rate / 2) - / 1000000; /* Half Bit Clock In Mhz */ + /* Half Bit Clock In Mhz */ + clk_rate = pll_divider_config.clk_rate; + do_div(clk_rate, 2U); + do_div(clk_rate, 1000000U); + rate = (u32)clk_rate; if (rate < 43) { vco = rate * 16; @@ -921,8 +922,9 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, dsi_pclk.n = mnd_entry->pclk_n; dsi_pclk.d = mnd_entry->pclk_d; } - dsi_pclk_rate = (((pll_divider_config.clk_rate) * lanes) - / (8 * bpp)); + clk_rate = pll_divider_config.clk_rate; + do_div(clk_rate, 8 * bpp); + dsi_pclk_rate = (u32) clk_rate * lanes; if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 250000000)) dsi_pclk_rate = 35000000; |
