aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@nokia.com>2010-02-04 10:03:41 -0500
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-02-12 05:46:08 -0500
commit8a2cfea8ccb6292dc43c37968fe08475ae7c2576 (patch)
tree880fb2f9e43172f84baa771c7060bb7c473f7816 /drivers/video
parente721032785b72afbc3da14c5525ca570bc2ed108 (diff)
OMAP: DSS2: enable VDDS_DSI when using DPI
It looks like on OMAP3 some DSS pins need VDDS_DSI to function properly. This has not been confirmed from TI, but looking at figure 15-1 "Display subsystem highlight" from the TRM, some data pins come near the DSI and SDI blocks. This is not very hard evidence, but the fact remains that with the power on, pixels are ok, and with the power off, pixels are not ok. It may also be that VDDS_SDI is needed to power some pins, but as normally both VDDS_SDI and VDDS_DSI come from the same power source, this hasn't been shown. It seems that a single driver can only get a regulator once. This patch solves it by getting all the required regulators in one place, and from which the submodules then get the regulators they need. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/core.c66
-rw-r--r--drivers/video/omap2/dss/dpi.c55
-rw-r--r--drivers/video/omap2/dss/dsi.c4
-rw-r--r--drivers/video/omap2/dss/dss.h5
-rw-r--r--drivers/video/omap2/dss/venc.c4
5 files changed, 117 insertions, 17 deletions
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 82918eec6d2e..791e1cb7c0bc 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -31,6 +31,7 @@
31#include <linux/debugfs.h> 31#include <linux/debugfs.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/regulator/consumer.h>
34 35
35#include <plat/display.h> 36#include <plat/display.h>
36#include <plat/clock.h> 37#include <plat/clock.h>
@@ -47,6 +48,10 @@ static struct {
47 struct clk *dss_54m_fck; 48 struct clk *dss_54m_fck;
48 struct clk *dss_96m_fck; 49 struct clk *dss_96m_fck;
49 unsigned num_clks_enabled; 50 unsigned num_clks_enabled;
51
52 struct regulator *vdds_dsi_reg;
53 struct regulator *vdds_sdi_reg;
54 struct regulator *vdda_dac_reg;
50} core; 55} core;
51 56
52static void dss_clk_enable_all_no_ctx(void); 57static void dss_clk_enable_all_no_ctx(void);
@@ -352,6 +357,50 @@ static void dss_clk_disable_all(void)
352 dss_clk_disable(clks); 357 dss_clk_disable(clks);
353} 358}
354 359
360/* REGULATORS */
361
362struct regulator *dss_get_vdds_dsi(void)
363{
364 struct regulator *reg;
365
366 if (core.vdds_dsi_reg != NULL)
367 return core.vdds_dsi_reg;
368
369 reg = regulator_get(&core.pdev->dev, "vdds_dsi");
370 if (!IS_ERR(reg))
371 core.vdds_dsi_reg = reg;
372
373 return reg;
374}
375
376struct regulator *dss_get_vdds_sdi(void)
377{
378 struct regulator *reg;
379
380 if (core.vdds_sdi_reg != NULL)
381 return core.vdds_sdi_reg;
382
383 reg = regulator_get(&core.pdev->dev, "vdds_sdi");
384 if (!IS_ERR(reg))
385 core.vdds_sdi_reg = reg;
386
387 return reg;
388}
389
390struct regulator *dss_get_vdda_dac(void)
391{
392 struct regulator *reg;
393
394 if (core.vdda_dac_reg != NULL)
395 return core.vdda_dac_reg;
396
397 reg = regulator_get(&core.pdev->dev, "vdda_dac");
398 if (!IS_ERR(reg))
399 core.vdda_dac_reg = reg;
400
401 return reg;
402}
403
355/* DEBUGFS */ 404/* DEBUGFS */
356#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 405#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
357static void dss_debug_dump_clocks(struct seq_file *s) 406static void dss_debug_dump_clocks(struct seq_file *s)
@@ -473,7 +522,7 @@ static int omap_dss_probe(struct platform_device *pdev)
473 } 522 }
474#endif 523#endif
475 524
476 r = dpi_init(); 525 r = dpi_init(pdev);
477 if (r) { 526 if (r) {
478 DSSERR("Failed to initialize dpi\n"); 527 DSSERR("Failed to initialize dpi\n");
479 goto fail0; 528 goto fail0;
@@ -901,6 +950,21 @@ static int __init omap_dss_init(void)
901 950
902static void __exit omap_dss_exit(void) 951static void __exit omap_dss_exit(void)
903{ 952{
953 if (core.vdds_dsi_reg != NULL) {
954 regulator_put(core.vdds_dsi_reg);
955 core.vdds_dsi_reg = NULL;
956 }
957
958 if (core.vdds_sdi_reg != NULL) {
959 regulator_put(core.vdds_sdi_reg);
960 core.vdds_sdi_reg = NULL;
961 }
962
963 if (core.vdda_dac_reg != NULL) {
964 regulator_put(core.vdda_dac_reg);
965 core.vdda_dac_reg = NULL;
966 }
967
904 platform_driver_unregister(&omap_dss_driver); 968 platform_driver_unregister(&omap_dss_driver);
905 969
906 omap_dss_bus_unregister(); 970 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 2d71031baa25..69ce31ae2a2f 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -25,7 +25,10 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/err.h>
28#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/platform_device.h>
31#include <linux/regulator/consumer.h>
29 32
30#include <plat/display.h> 33#include <plat/display.h>
31#include <plat/cpu.h> 34#include <plat/cpu.h>
@@ -34,6 +37,7 @@
34 37
35static struct { 38static struct {
36 int update_enabled; 39 int update_enabled;
40 struct regulator *vdds_dsi_reg;
37} dpi; 41} dpi;
38 42
39#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 43#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
@@ -166,21 +170,27 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
166 goto err1; 170 goto err1;
167 } 171 }
168 172
173 if (cpu_is_omap34xx()) {
174 r = regulator_enable(dpi.vdds_dsi_reg);
175 if (r)
176 goto err2;
177 }
178
169 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 179 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
170 180
171 r = dpi_basic_init(dssdev); 181 r = dpi_basic_init(dssdev);
172 if (r) 182 if (r)
173 goto err2; 183 goto err3;
174 184
175#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 185#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
176 dss_clk_enable(DSS_CLK_FCK2); 186 dss_clk_enable(DSS_CLK_FCK2);
177 r = dsi_pll_init(dssdev, 0, 1); 187 r = dsi_pll_init(dssdev, 0, 1);
178 if (r) 188 if (r)
179 goto err3; 189 goto err4;
180#endif 190#endif
181 r = dpi_set_mode(dssdev); 191 r = dpi_set_mode(dssdev);
182 if (r) 192 if (r)
183 goto err4; 193 goto err5;
184 194
185 mdelay(2); 195 mdelay(2);
186 196
@@ -188,22 +198,25 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
188 198
189 r = dssdev->driver->enable(dssdev); 199 r = dssdev->driver->enable(dssdev);
190 if (r) 200 if (r)
191 goto err5; 201 goto err6;
192 202
193 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 203 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
194 204
195 return 0; 205 return 0;
196 206
197err5: 207err6:
198 dispc_enable_lcd_out(0); 208 dispc_enable_lcd_out(0);
199err4: 209err5:
200#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 210#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
201 dsi_pll_uninit(); 211 dsi_pll_uninit();
202err3: 212err4:
203 dss_clk_disable(DSS_CLK_FCK2); 213 dss_clk_disable(DSS_CLK_FCK2);
204#endif 214#endif
205err2: 215err3:
206 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 216 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
217err2:
218 if (cpu_is_omap34xx())
219 regulator_disable(dpi.vdds_dsi_reg);
207err1: 220err1:
208 omap_dss_stop_device(dssdev); 221 omap_dss_stop_device(dssdev);
209err0: 222err0:
@@ -232,6 +245,9 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
232 245
233 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 246 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
234 247
248 if (cpu_is_omap34xx())
249 regulator_disable(dpi.vdds_dsi_reg);
250
235 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 251 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
236 252
237 omap_dss_stop_device(dssdev); 253 omap_dss_stop_device(dssdev);
@@ -251,6 +267,9 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev)
251 267
252 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 268 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
253 269
270 if (cpu_is_omap34xx())
271 regulator_disable(dpi.vdds_dsi_reg);
272
254 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 273 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
255 274
256 return 0; 275 return 0;
@@ -258,11 +277,19 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev)
258 277
259static int dpi_display_resume(struct omap_dss_device *dssdev) 278static int dpi_display_resume(struct omap_dss_device *dssdev)
260{ 279{
280 int r;
281
261 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) 282 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
262 return -EINVAL; 283 return -EINVAL;
263 284
264 DSSDBG("dpi_display_resume\n"); 285 DSSDBG("dpi_display_resume\n");
265 286
287 if (cpu_is_omap34xx()) {
288 r = regulator_enable(dpi.vdds_dsi_reg);
289 if (r)
290 goto err0;
291 }
292
266 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 293 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
267 294
268 dispc_enable_lcd_out(1); 295 dispc_enable_lcd_out(1);
@@ -273,6 +300,8 @@ static int dpi_display_resume(struct omap_dss_device *dssdev)
273 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 300 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
274 301
275 return 0; 302 return 0;
303err0:
304 return r;
276} 305}
277 306
278static void dpi_set_timings(struct omap_dss_device *dssdev, 307static void dpi_set_timings(struct omap_dss_device *dssdev,
@@ -388,8 +417,16 @@ int dpi_init_display(struct omap_dss_device *dssdev)
388 return 0; 417 return 0;
389} 418}
390 419
391int dpi_init(void) 420int dpi_init(struct platform_device *pdev)
392{ 421{
422 if (cpu_is_omap34xx()) {
423 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
424 if (IS_ERR(dpi.vdds_dsi_reg)) {
425 DSSERR("can't get VDDS_DSI regulator\n");
426 return PTR_ERR(dpi.vdds_dsi_reg);
427 }
428 }
429
393 return 0; 430 return 0;
394} 431}
395 432
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6122178f5f85..036f4221e3df 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3799,7 +3799,7 @@ int dsi_init(struct platform_device *pdev)
3799 goto err1; 3799 goto err1;
3800 } 3800 }
3801 3801
3802 dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); 3802 dsi.vdds_dsi_reg = dss_get_vdds_dsi();
3803 if (IS_ERR(dsi.vdds_dsi_reg)) { 3803 if (IS_ERR(dsi.vdds_dsi_reg)) {
3804 iounmap(dsi.base); 3804 iounmap(dsi.base);
3805 DSSERR("can't get VDDS_DSI regulator\n"); 3805 DSSERR("can't get VDDS_DSI regulator\n");
@@ -3830,8 +3830,6 @@ void dsi_exit(void)
3830{ 3830{
3831 kthread_stop(dsi.thread); 3831 kthread_stop(dsi.thread);
3832 3832
3833 regulator_put(dsi.vdds_dsi_reg);
3834
3835 iounmap(dsi.base); 3833 iounmap(dsi.base);
3836 3834
3837 DSSDBG("omap_dsi_exit\n"); 3835 DSSDBG("omap_dsi_exit\n");
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 2bcb1245d6c2..41145af36353 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -169,6 +169,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk);
169int dss_need_ctx_restore(void); 169int dss_need_ctx_restore(void);
170void dss_dump_clocks(struct seq_file *s); 170void dss_dump_clocks(struct seq_file *s);
171struct bus_type *dss_get_bus(void); 171struct bus_type *dss_get_bus(void);
172struct regulator *dss_get_vdds_dsi(void);
173struct regulator *dss_get_vdds_sdi(void);
174struct regulator *dss_get_vdda_dac(void);
172 175
173/* display */ 176/* display */
174int dss_suspend_all_devices(void); 177int dss_suspend_all_devices(void);
@@ -261,7 +264,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
261 u32 *fifo_low, u32 *fifo_high); 264 u32 *fifo_low, u32 *fifo_high);
262 265
263/* DPI */ 266/* DPI */
264int dpi_init(void); 267int dpi_init(struct platform_device *pdev);
265void dpi_exit(void); 268void dpi_exit(void);
266int dpi_init_display(struct omap_dss_device *dssdev); 269int dpi_init_display(struct omap_dss_device *dssdev);
267 270
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 749a5a0f5be4..44b4998c2052 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -482,7 +482,7 @@ int venc_init(struct platform_device *pdev)
482 return -ENOMEM; 482 return -ENOMEM;
483 } 483 }
484 484
485 venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac"); 485 venc.vdda_dac_reg = dss_get_vdda_dac();
486 if (IS_ERR(venc.vdda_dac_reg)) { 486 if (IS_ERR(venc.vdda_dac_reg)) {
487 iounmap(venc.base); 487 iounmap(venc.base);
488 DSSERR("can't get VDDA_DAC regulator\n"); 488 DSSERR("can't get VDDA_DAC regulator\n");
@@ -503,8 +503,6 @@ void venc_exit(void)
503{ 503{
504 omap_dss_unregister_driver(&venc_driver); 504 omap_dss_unregister_driver(&venc_driver);
505 505
506 regulator_put(venc.vdda_dac_reg);
507
508 iounmap(venc.base); 506 iounmap(venc.base);
509} 507}
510 508