aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-12 03:37:03 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-12-12 06:34:13 -0500
commit5aaee69d7fe02d1ffb76b6a31a588efa5f2742e3 (patch)
tree888cd43ba85b3baf7741f598f1ddcac30b3a2003 /drivers/video/omap2
parentd10ecc5887a5671f2c71752b1624549a4a48b1fe (diff)
OMAPDSS: DISPC: get dss clock rate from dss driver
Dispc currently gets dispc's fck with clk_get() and uses clk_get_rate() to get the rate for scaling calculations. This causes a problem with common clock framework, as omapdss uses the dispc functions inside a spinlock, and common clock framework uses a mutex in clk_get_rate(). Looking at the DSS clock tree, the above use of the dispc fck is not quite correct. The DSS_FCLK from PRCM goes to DSS core block, which has a mux to select the clock for DISPC from various options, so the current use of dispc fck bypasses that. Fortunately we never change the dispc clock mux for now. To fix the issue with clk_get_rate(), this patch caches the dss clock rate in dss.c when it is set. Dispc will then ask for the clock rate from dss. While this is not very elegant, it does fix the issue, and it's not totally wrong when considering that the dispc fck actually comes via dss. In the future we should probably look into common clock framework and see if that could be used to represent the DSS clock tree properly. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/dss/dispc.c4
-rw-r--r--drivers/video/omap2/dss/dss.c12
-rw-r--r--drivers/video/omap2/dss/dss.h1
3 files changed, 15 insertions, 2 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index fedbd2c8e97a..08137a8a38cb 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2970,7 +2970,7 @@ unsigned long dispc_fclk_rate(void)
2970 2970
2971 switch (dss_get_dispc_clk_source()) { 2971 switch (dss_get_dispc_clk_source()) {
2972 case OMAP_DSS_CLK_SRC_FCK: 2972 case OMAP_DSS_CLK_SRC_FCK:
2973 r = clk_get_rate(dispc.dss_clk); 2973 r = dss_get_dispc_clk_rate();
2974 break; 2974 break;
2975 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2975 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2976 dsidev = dsi_get_dsidev_from_id(0); 2976 dsidev = dsi_get_dsidev_from_id(0);
@@ -3002,7 +3002,7 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
3002 3002
3003 switch (dss_get_lcd_clk_source(channel)) { 3003 switch (dss_get_lcd_clk_source(channel)) {
3004 case OMAP_DSS_CLK_SRC_FCK: 3004 case OMAP_DSS_CLK_SRC_FCK:
3005 r = clk_get_rate(dispc.dss_clk); 3005 r = dss_get_dispc_clk_rate();
3006 break; 3006 break;
3007 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3007 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3008 dsidev = dsi_get_dsidev_from_id(0); 3008 dsidev = dsi_get_dsidev_from_id(0);
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 833f1627dc76..054c2a22b3f1 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -77,6 +77,7 @@ static struct {
77 77
78 struct clk *dpll4_m4_ck; 78 struct clk *dpll4_m4_ck;
79 struct clk *dss_clk; 79 struct clk *dss_clk;
80 unsigned long dss_clk_rate;
80 81
81 unsigned long cache_req_pck; 82 unsigned long cache_req_pck;
82 unsigned long cache_prate; 83 unsigned long cache_prate;
@@ -489,6 +490,10 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
489 return -EINVAL; 490 return -EINVAL;
490 } 491 }
491 492
493 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
494
495 WARN_ONCE(dss.dss_clk_rate != cinfo->fck, "clk rate mismatch");
496
492 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 497 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
493 498
494 return 0; 499 return 0;
@@ -502,6 +507,11 @@ unsigned long dss_get_dpll4_rate(void)
502 return 0; 507 return 0;
503} 508}
504 509
510unsigned long dss_get_dispc_clk_rate(void)
511{
512 return dss.dss_clk_rate;
513}
514
505static int dss_setup_default_clock(void) 515static int dss_setup_default_clock(void)
506{ 516{
507 unsigned long max_dss_fck, prate; 517 unsigned long max_dss_fck, prate;
@@ -953,6 +963,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
953 if (r) 963 if (r)
954 goto err_runtime_get; 964 goto err_runtime_get;
955 965
966 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
967
956 /* Select DPLL */ 968 /* Select DPLL */
957 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); 969 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
958 970
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index ebe9e08b2a91..610c8e563daa 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -237,6 +237,7 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
237int dss_init_platform_driver(void) __init; 237int dss_init_platform_driver(void) __init;
238void dss_uninit_platform_driver(void); 238void dss_uninit_platform_driver(void);
239 239
240unsigned long dss_get_dispc_clk_rate(void);
240int dss_dpi_select_source(enum omap_channel channel); 241int dss_dpi_select_source(enum omap_channel channel);
241void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 242void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
242enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 243enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);