aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dss.c
diff options
context:
space:
mode:
authorTaneja, Archit <archit@ti.com>2011-03-08 06:50:35 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-03-11 08:46:31 -0500
commitea75159ee6f00bd809f57a58e5505dc362382cc8 (patch)
tree1774924c5c20dea2be5ee4e9c8907909cec0a81c /drivers/video/omap2/dss/dss.c
parent66534e8e936a0b926863df90054dc59826d70528 (diff)
OMAP4: DSS2: Clock source changes for OMAP4
On OMAP3, the pixel clock for the LCD manager was derived through DISPC_FCLK as: Lcd Pixel clock = DISPC_FCLK / lcd / pcd Where lcd and pcd are divisors in the DISPC_DIVISOR register. On OMAP4, the pixel clocks for LCD1 and LCD2 managers are derived from 2 new clocks named LCD1_CLK and LCD2_CLK. The pixel clocks are calculated as: Lcd_o Pixel clock = LCDo_CLK / lcdo /pcdo, o = 1, 2 Where lcdo and pcdo registers are divisors in DISPC_DIVISORo registers. LCD1_CLK and LCD2_CLK can have DSS_FCLK, and the M4 divider clocks of DSI1 PLL and DSI2 PLL as clock sources respectively. Introduce functions to select and get the clock source for these new clocks. Modify DISPC functions get the correct lck and pck rates based on the clock source of these clocks. Since OMAP2/3 don't have these clocks, force OMAP2/3 to always have the LCD_CLK source as DSS_CLK_SRC_FCK by introducing a dss feature. Introduce clock source names for OMAP4 and some register field changes in DSS_CTRL on OMAP4. Currently, LCD2_CLK can only have DSS_FCLK as its clock source as DSI2 PLL functionality hasn't been introduced yet. BUG for now if DSI2 PLL is selected as clock. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss/dss.c')
-rw-r--r--drivers/video/omap2/dss/dss.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 93813fd626be..aed9345e8ada 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -77,6 +77,7 @@ static struct {
77 77
78 enum dss_clk_source dsi_clk_source; 78 enum dss_clk_source dsi_clk_source;
79 enum dss_clk_source dispc_clk_source; 79 enum dss_clk_source dispc_clk_source;
80 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
80 81
81 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 82 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
82} dss; 83} dss;
@@ -292,6 +293,7 @@ void dss_dump_regs(struct seq_file *s)
292void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 293void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
293{ 294{
294 int b; 295 int b;
296 u8 start, end;
295 297
296 switch (clk_src) { 298 switch (clk_src) {
297 case DSS_CLK_SRC_FCK: 299 case DSS_CLK_SRC_FCK:
@@ -305,7 +307,9 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
305 BUG(); 307 BUG();
306 } 308 }
307 309
308 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 310 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
311
312 REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
309 313
310 dss.dispc_clk_source = clk_src; 314 dss.dispc_clk_source = clk_src;
311} 315}
@@ -331,6 +335,34 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
331 dss.dsi_clk_source = clk_src; 335 dss.dsi_clk_source = clk_src;
332} 336}
333 337
338void dss_select_lcd_clk_source(enum omap_channel channel,
339 enum dss_clk_source clk_src)
340{
341 int b, ix, pos;
342
343 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
344 return;
345
346 switch (clk_src) {
347 case DSS_CLK_SRC_FCK:
348 b = 0;
349 break;
350 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
351 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
352 b = 1;
353 dsi_wait_pll_hsdiv_dispc_active();
354 break;
355 default:
356 BUG();
357 }
358
359 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
360 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
361
362 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
363 dss.lcd_clk_source[ix] = clk_src;
364}
365
334enum dss_clk_source dss_get_dispc_clk_source(void) 366enum dss_clk_source dss_get_dispc_clk_source(void)
335{ 367{
336 return dss.dispc_clk_source; 368 return dss.dispc_clk_source;
@@ -341,6 +373,12 @@ enum dss_clk_source dss_get_dsi_clk_source(void)
341 return dss.dsi_clk_source; 373 return dss.dsi_clk_source;
342} 374}
343 375
376enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
377{
378 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
379 return dss.lcd_clk_source[ix];
380}
381
344/* calculate clock rates using dividers in cinfo */ 382/* calculate clock rates using dividers in cinfo */
345int dss_calc_clock_rates(struct dss_clock_info *cinfo) 383int dss_calc_clock_rates(struct dss_clock_info *cinfo)
346{ 384{
@@ -624,6 +662,8 @@ static int dss_init(void)
624 662
625 dss.dsi_clk_source = DSS_CLK_SRC_FCK; 663 dss.dsi_clk_source = DSS_CLK_SRC_FCK;
626 dss.dispc_clk_source = DSS_CLK_SRC_FCK; 664 dss.dispc_clk_source = DSS_CLK_SRC_FCK;
665 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
666 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
627 667
628 dss_save_context(); 668 dss_save_context();
629 669