diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-08-29 08:56:04 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-09-30 09:16:35 -0400 |
commit | 9eaaf2076dac213c034c69051dd7a625cd41f56e (patch) | |
tree | 324c8dbe9a8e25c7eb46a986b0b7ac00f4549b59 /drivers/video/omap2 | |
parent | d875f992e9d0b1473ff98845cb3c2a45dcf6aa0f (diff) |
OMAP: DSS2: DISPC: Fix minimum PCD value
The current driver had a hardcoded minimum value of 2 for pixel clock
divisor (PCD). This doesn't seem to be right.
OMAP4 TRM says that PCD can be 1 when not downscaling, and inverted
pixel clock (IPC) is off.
OMAP3 TRM says the same, but also in the register descriptions that PCD
value 1 is invalid.
OMAP2 TRM says PCD 2 is the minimum.
OMAP2 is still untested, but for both OMAP3 and OMAP4 PCD of 1 seems to
work fine.
This patch adds a new DSS feature, FEAT_PARAM_DSS_PCD, which is used to
find the minimum and maximum PCD. The minimum is set to 2 for OMAP2, and
1 for OMAP3/4.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 14 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 3 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 1 |
3 files changed, 14 insertions, 4 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b4a16cf9be1c..4e9f87fc33d8 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -2334,7 +2334,7 @@ static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, | |||
2334 | u16 pck_div) | 2334 | u16 pck_div) |
2335 | { | 2335 | { |
2336 | BUG_ON(lck_div < 1); | 2336 | BUG_ON(lck_div < 1); |
2337 | BUG_ON(pck_div < 2); | 2337 | BUG_ON(pck_div < 1); |
2338 | 2338 | ||
2339 | dispc_write_reg(DISPC_DIVISORo(channel), | 2339 | dispc_write_reg(DISPC_DIVISORo(channel), |
2340 | FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); | 2340 | FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); |
@@ -2721,11 +2721,17 @@ void dispc_mgr_set_pol_freq(enum omap_channel channel, | |||
2721 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 2721 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, |
2722 | struct dispc_clock_info *cinfo) | 2722 | struct dispc_clock_info *cinfo) |
2723 | { | 2723 | { |
2724 | u16 pcd_min = is_tft ? 2 : 3; | 2724 | u16 pcd_min, pcd_max; |
2725 | unsigned long best_pck; | 2725 | unsigned long best_pck; |
2726 | u16 best_ld, cur_ld; | 2726 | u16 best_ld, cur_ld; |
2727 | u16 best_pd, cur_pd; | 2727 | u16 best_pd, cur_pd; |
2728 | 2728 | ||
2729 | pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); | ||
2730 | pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); | ||
2731 | |||
2732 | if (!is_tft) | ||
2733 | pcd_min = 3; | ||
2734 | |||
2729 | best_pck = 0; | 2735 | best_pck = 0; |
2730 | best_ld = 0; | 2736 | best_ld = 0; |
2731 | best_pd = 0; | 2737 | best_pd = 0; |
@@ -2733,7 +2739,7 @@ void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | |||
2733 | for (cur_ld = 1; cur_ld <= 255; ++cur_ld) { | 2739 | for (cur_ld = 1; cur_ld <= 255; ++cur_ld) { |
2734 | unsigned long lck = fck / cur_ld; | 2740 | unsigned long lck = fck / cur_ld; |
2735 | 2741 | ||
2736 | for (cur_pd = pcd_min; cur_pd <= 255; ++cur_pd) { | 2742 | for (cur_pd = pcd_min; cur_pd <= pcd_max; ++cur_pd) { |
2737 | unsigned long pck = lck / cur_pd; | 2743 | unsigned long pck = lck / cur_pd; |
2738 | long old_delta = abs(best_pck - req_pck); | 2744 | long old_delta = abs(best_pck - req_pck); |
2739 | long new_delta = abs(pck - req_pck); | 2745 | long new_delta = abs(pck - req_pck); |
@@ -2768,7 +2774,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | |||
2768 | { | 2774 | { |
2769 | if (cinfo->lck_div > 255 || cinfo->lck_div == 0) | 2775 | if (cinfo->lck_div > 255 || cinfo->lck_div == 0) |
2770 | return -EINVAL; | 2776 | return -EINVAL; |
2771 | if (cinfo->pck_div < 2 || cinfo->pck_div > 255) | 2777 | if (cinfo->pck_div < 1 || cinfo->pck_div > 255) |
2772 | return -EINVAL; | 2778 | return -EINVAL; |
2773 | 2779 | ||
2774 | cinfo->lck = dispc_fclk_rate / cinfo->lck_div; | 2780 | cinfo->lck = dispc_fclk_rate / cinfo->lck_div; |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 86706123a247..076f399a9153 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
@@ -281,6 +281,7 @@ static const char * const omap4_dss_clk_source_names[] = { | |||
281 | 281 | ||
282 | static const struct dss_param_range omap2_dss_param_range[] = { | 282 | static const struct dss_param_range omap2_dss_param_range[] = { |
283 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, | 283 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, |
284 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, | ||
284 | [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 }, | 285 | [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 }, |
285 | [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 }, | 286 | [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 }, |
286 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 }, | 287 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 }, |
@@ -291,6 +292,7 @@ static const struct dss_param_range omap2_dss_param_range[] = { | |||
291 | 292 | ||
292 | static const struct dss_param_range omap3_dss_param_range[] = { | 293 | static const struct dss_param_range omap3_dss_param_range[] = { |
293 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, | 294 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, |
295 | [FEAT_PARAM_DSS_PCD] = { 1, 255 }, | ||
294 | [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 }, | 296 | [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 }, |
295 | [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 }, | 297 | [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 }, |
296 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 }, | 298 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 }, |
@@ -301,6 +303,7 @@ static const struct dss_param_range omap3_dss_param_range[] = { | |||
301 | 303 | ||
302 | static const struct dss_param_range omap4_dss_param_range[] = { | 304 | static const struct dss_param_range omap4_dss_param_range[] = { |
303 | [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, | 305 | [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, |
306 | [FEAT_PARAM_DSS_PCD] = { 1, 255 }, | ||
304 | [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, | 307 | [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, |
305 | [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, | 308 | [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, |
306 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, | 309 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index c4321908f322..f73585e09d27 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
@@ -77,6 +77,7 @@ enum dss_feat_reg_field { | |||
77 | 77 | ||
78 | enum dss_range_param { | 78 | enum dss_range_param { |
79 | FEAT_PARAM_DSS_FCK, | 79 | FEAT_PARAM_DSS_FCK, |
80 | FEAT_PARAM_DSS_PCD, | ||
80 | FEAT_PARAM_DSIPLL_REGN, | 81 | FEAT_PARAM_DSIPLL_REGN, |
81 | FEAT_PARAM_DSIPLL_REGM, | 82 | FEAT_PARAM_DSIPLL_REGM, |
82 | FEAT_PARAM_DSIPLL_REGM_DISPC, | 83 | FEAT_PARAM_DSIPLL_REGM_DISPC, |