aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dss/dispc.c31
-rw-r--r--drivers/video/omap2/dss/dss.c42
-rw-r--r--drivers/video/omap2/dss/dss.h26
-rw-r--r--drivers/video/omap2/dss/dss_features.c13
-rw-r--r--drivers/video/omap2/dss/dss_features.h3
5 files changed, 98 insertions, 17 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 28b690f2447f..b8c576a0bc02 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2365,25 +2365,33 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2365 2365
2366 lcd = FLD_GET(l, 23, 16); 2366 lcd = FLD_GET(l, 23, 16);
2367 2367
2368 r = dispc_fclk_rate(); 2368 switch (dss_get_lcd_clk_source(channel)) {
2369 case DSS_CLK_SRC_FCK:
2370 r = dss_clk_get_rate(DSS_CLK_FCK);
2371 break;
2372 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2373 r = dsi_get_pll_hsdiv_dispc_rate();
2374 break;
2375 default:
2376 BUG();
2377 }
2369 2378
2370 return r / lcd; 2379 return r / lcd;
2371} 2380}
2372 2381
2373unsigned long dispc_pclk_rate(enum omap_channel channel) 2382unsigned long dispc_pclk_rate(enum omap_channel channel)
2374{ 2383{
2375 int lcd, pcd; 2384 int pcd;
2376 unsigned long r; 2385 unsigned long r;
2377 u32 l; 2386 u32 l;
2378 2387
2379 l = dispc_read_reg(DISPC_DIVISORo(channel)); 2388 l = dispc_read_reg(DISPC_DIVISORo(channel));
2380 2389
2381 lcd = FLD_GET(l, 23, 16);
2382 pcd = FLD_GET(l, 7, 0); 2390 pcd = FLD_GET(l, 7, 0);
2383 2391
2384 r = dispc_fclk_rate(); 2392 r = dispc_lclk_rate(channel);
2385 2393
2386 return r / lcd / pcd; 2394 return r / pcd;
2387} 2395}
2388 2396
2389void dispc_dump_clocks(struct seq_file *s) 2397void dispc_dump_clocks(struct seq_file *s)
@@ -2391,6 +2399,7 @@ void dispc_dump_clocks(struct seq_file *s)
2391 int lcd, pcd; 2399 int lcd, pcd;
2392 u32 l; 2400 u32 l;
2393 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 2401 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2402 enum dss_clk_source lcd_clk_src;
2394 2403
2395 enable_clocks(1); 2404 enable_clocks(1);
2396 2405
@@ -2412,6 +2421,12 @@ void dispc_dump_clocks(struct seq_file *s)
2412 } 2421 }
2413 seq_printf(s, "- LCD1 -\n"); 2422 seq_printf(s, "- LCD1 -\n");
2414 2423
2424 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2425
2426 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2427 dss_get_generic_clk_source_name(lcd_clk_src),
2428 dss_feat_get_clk_source_name(lcd_clk_src));
2429
2415 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); 2430 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2416 2431
2417 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2432 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
@@ -2421,6 +2436,12 @@ void dispc_dump_clocks(struct seq_file *s)
2421 if (dss_has_feature(FEAT_MGR_LCD2)) { 2436 if (dss_has_feature(FEAT_MGR_LCD2)) {
2422 seq_printf(s, "- LCD2 -\n"); 2437 seq_printf(s, "- LCD2 -\n");
2423 2438
2439 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2440
2441 seq_printf(s, "lcd2_clk source = %s (%s)\n",
2442 dss_get_generic_clk_source_name(lcd_clk_src),
2443 dss_feat_get_clk_source_name(lcd_clk_src));
2444
2424 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2445 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2425 2446
2426 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2447 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
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
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index fc41b3f0c27e..b845468d9706 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -118,9 +118,12 @@ enum dss_clock {
118}; 118};
119 119
120enum dss_clk_source { 120enum dss_clk_source {
121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* DSI1_PLL_FCLK */ 121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
122 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* DSI2_PLL_FCLK */ 122 * OMAP4: PLL1_CLK1 */
123 DSS_CLK_SRC_FCK, /* DSS1_ALWON_FCLK */ 123 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
124 * OMAP4: PLL1_CLK2 */
125 DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
126 * OMAP4: DSS_FCLK */
124}; 127};
125 128
126/* Correlates clock source name and dss_clk_source member */ 129/* Correlates clock source name and dss_clk_source member */
@@ -152,17 +155,19 @@ struct dsi_clock_info {
152 unsigned long fint; 155 unsigned long fint;
153 unsigned long clkin4ddr; 156 unsigned long clkin4ddr;
154 unsigned long clkin; 157 unsigned long clkin;
155 unsigned long dsi_pll_hsdiv_dispc_clk; /* DSI1_PLL_CLK */ 158 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
156 unsigned long dsi_pll_hsdiv_dsi_clk; /* DSI2_PLL_CLK */ 159 * OMAP4: PLLx_CLK1 */
157 160 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
161 * OMAP4: PLLx_CLK2 */
158 unsigned long lp_clk; 162 unsigned long lp_clk;
159 163
160 /* dividers */ 164 /* dividers */
161 u16 regn; 165 u16 regn;
162 u16 regm; 166 u16 regm;
163 u16 regm_dispc; /* REGM3 */ 167 u16 regm_dispc; /* OMAP3: REGM3
164 u16 regm_dsi; /* REGM4 */ 168 * OMAP4: REGM4 */
165 169 u16 regm_dsi; /* OMAP3: REGM4
170 * OMAP4: REGM5 */
166 u16 lp_clk_div; 171 u16 lp_clk_div;
167 172
168 u8 highfreq; 173 u8 highfreq;
@@ -235,8 +240,11 @@ void dss_sdi_disable(void);
235 240
236void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 241void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
237void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 242void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
243void dss_select_lcd_clk_source(enum omap_channel channel,
244 enum dss_clk_source clk_src);
238enum dss_clk_source dss_get_dispc_clk_source(void); 245enum dss_clk_source dss_get_dispc_clk_source(void);
239enum dss_clk_source dss_get_dsi_clk_source(void); 246enum dss_clk_source dss_get_dsi_clk_source(void);
247enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
240 248
241void dss_set_venc_output(enum omap_dss_venc_type type); 249void dss_set_venc_output(enum omap_dss_venc_type type);
242void dss_set_dac_pwrdn_bgz(bool enable); 250void dss_set_dac_pwrdn_bgz(bool enable);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index dc170ad079f2..6eb6ec62a000 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -59,6 +59,7 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
59 { FEAT_REG_FIFOSIZE, 8, 0 }, 59 { FEAT_REG_FIFOSIZE, 8, 0 },
60 { FEAT_REG_HORIZONTALACCU, 9, 0 }, 60 { FEAT_REG_HORIZONTALACCU, 9, 0 },
61 { FEAT_REG_VERTICALACCU, 25, 16 }, 61 { FEAT_REG_VERTICALACCU, 25, 16 },
62 { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 },
62}; 63};
63 64
64static const struct dss_reg_field omap3_dss_reg_fields[] = { 65static const struct dss_reg_field omap3_dss_reg_fields[] = {
@@ -69,6 +70,7 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
69 { FEAT_REG_FIFOSIZE, 10, 0 }, 70 { FEAT_REG_FIFOSIZE, 10, 0 },
70 { FEAT_REG_HORIZONTALACCU, 9, 0 }, 71 { FEAT_REG_HORIZONTALACCU, 9, 0 },
71 { FEAT_REG_VERTICALACCU, 25, 16 }, 72 { FEAT_REG_VERTICALACCU, 25, 16 },
73 { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 },
72}; 74};
73 75
74static const struct dss_reg_field omap4_dss_reg_fields[] = { 76static const struct dss_reg_field omap4_dss_reg_fields[] = {
@@ -79,6 +81,7 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
79 { FEAT_REG_FIFOSIZE, 15, 0 }, 81 { FEAT_REG_FIFOSIZE, 15, 0 },
80 { FEAT_REG_HORIZONTALACCU, 10, 0 }, 82 { FEAT_REG_HORIZONTALACCU, 10, 0 },
81 { FEAT_REG_VERTICALACCU, 26, 16 }, 83 { FEAT_REG_VERTICALACCU, 26, 16 },
84 { FEAT_REG_DISPC_CLK_SWITCH, 9, 8 },
82}; 85};
83 86
84static const enum omap_display_type omap2_dss_supported_displays[] = { 87static const enum omap_display_type omap2_dss_supported_displays[] = {
@@ -171,6 +174,12 @@ static const struct dss_clk_source_name omap3_dss_clk_source_names[] = {
171 { DSS_CLK_SRC_FCK, "DSS1_ALWON_FCLK" }, 174 { DSS_CLK_SRC_FCK, "DSS1_ALWON_FCLK" },
172}; 175};
173 176
177static const struct dss_clk_source_name omap4_dss_clk_source_names[] = {
178 { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "PLL1_CLK1" },
179 { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "PLL1_CLK2" },
180 { DSS_CLK_SRC_FCK, "DSS_FCLK" },
181};
182
174/* OMAP2 DSS Features */ 183/* OMAP2 DSS Features */
175static struct omap_dss_features omap2_dss_features = { 184static struct omap_dss_features omap2_dss_features = {
176 .reg_fields = omap2_dss_reg_fields, 185 .reg_fields = omap2_dss_reg_fields,
@@ -235,14 +244,14 @@ static struct omap_dss_features omap4_dss_features = {
235 .has_feature = 244 .has_feature =
236 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 245 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
237 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | 246 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
238 FEAT_CORE_CLK_DIV, 247 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC,
239 248
240 .num_mgrs = 3, 249 .num_mgrs = 3,
241 .num_ovls = 3, 250 .num_ovls = 3,
242 .max_dss_fck = 186000000, 251 .max_dss_fck = 186000000,
243 .supported_displays = omap4_dss_supported_displays, 252 .supported_displays = omap4_dss_supported_displays,
244 .supported_color_modes = omap3_dss_supported_color_modes, 253 .supported_color_modes = omap3_dss_supported_color_modes,
245 .clksrc_names = omap3_dss_clk_source_names, 254 .clksrc_names = omap4_dss_clk_source_names,
246}; 255};
247 256
248/* Functions returning values related to a DSS feature */ 257/* Functions returning values related to a DSS feature */
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 569d1b295edd..729b5f19fa2e 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -22,6 +22,7 @@
22 22
23#define MAX_DSS_MANAGERS 3 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2
25 26
26/* DSS has feature id */ 27/* DSS has feature id */
27enum dss_feat_id { 28enum dss_feat_id {
@@ -38,6 +39,7 @@ enum dss_feat_id {
38 FEAT_RESIZECONF = 1 << 10, 39 FEAT_RESIZECONF = 1 << 10,
39 /* Independent core clk divider */ 40 /* Independent core clk divider */
40 FEAT_CORE_CLK_DIV = 1 << 11, 41 FEAT_CORE_CLK_DIV = 1 << 11,
42 FEAT_LCD_CLK_SRC = 1 << 12,
41}; 43};
42 44
43/* DSS register field id */ 45/* DSS register field id */
@@ -49,6 +51,7 @@ enum dss_feat_reg_field {
49 FEAT_REG_FIFOSIZE, 51 FEAT_REG_FIFOSIZE,
50 FEAT_REG_HORIZONTALACCU, 52 FEAT_REG_HORIZONTALACCU,
51 FEAT_REG_VERTICALACCU, 53 FEAT_REG_VERTICALACCU,
54 FEAT_REG_DISPC_CLK_SWITCH,
52}; 55};
53 56
54/* DSS Feature Functions */ 57/* DSS Feature Functions */