aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-02 13:41:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-02 13:41:26 -0500
commit3a5b27bf6f29574d667230c7e76e4b83fe3014e0 (patch)
treea80892424269083c292d3eee29c4b3e6289d588b
parent5057bfaff82e12f01a2ffd58f55535cbd7c5c3a2 (diff)
parent21df20fcfb4e88f4cd4991e9e67de549e6480adf (diff)
Merge branch 'for-linus' of git://gitorious.org/linux-omap-dss2/linux
* 'for-linus' of git://gitorious.org/linux-omap-dss2/linux: (49 commits) OMAP: DSS2: Taal: Fix TE when resuming OMAP: DSS2: Taal: Fix ESD check OMAP: DSS2: OMAPFB: Constify some function parameters OMAP: DSS2: OMAPFB: install omapfb.h OMAP: DSS2: DSI: add error prints OMAP: DSS2: TPO-TD03MTEA1: fix function names OMAP: DSS2: DSI: add dsi_vc_dcs_read_2() helper OMAP: DSS2: OMAPFB: Remove FB_OMAP2_FORCE_AUTO_UPDATE OMAP: DSS2: DSI: remove external TE support OMAP: DSS2: move timing functions OMAP: DSS2: move set/get_wss() OMAP: DSS2: move enable/disable/suspend/resume OMAP: DSS2: move update() and sync() OMAP: DSS2: move set/get_update_mode() OMAP: DSS2: move enable/get_te() OMAP: DSS2: move get_recommended_bpp() OMAP: DSS2: move get_resolution() OMAP: DSS2: move enable/disable_channel to overlay manager OMAP: DSS2: move wait_vsync() OMAP: DSS2: move get/set_rotate() ...
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c4
-rw-r--r--arch/arm/plat-omap/include/plat/display.h117
-rw-r--r--drivers/video/omap/lcd_ams_delta.c93
-rw-r--r--drivers/video/omap/omapfb_main.c7
-rw-r--r--drivers/video/omap2/displays/Kconfig18
-rw-r--r--drivers/video/omap2/displays/Makefile3
-rw-r--r--drivers/video/omap2/displays/panel-generic.c56
-rw-r--r--drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c159
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c77
-rw-r--r--drivers/video/omap2/displays/panel-taal.c253
-rw-r--r--drivers/video/omap2/displays/panel-toppoly-tdo35s.c154
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c528
-rw-r--r--drivers/video/omap2/dss/Kconfig26
-rw-r--r--drivers/video/omap2/dss/core.c117
-rw-r--r--drivers/video/omap2/dss/dispc.c42
-rw-r--r--drivers/video/omap2/dss/display.c119
-rw-r--r--drivers/video/omap2/dss/dpi.c144
-rw-r--r--drivers/video/omap2/dss/dsi.c1031
-rw-r--r--drivers/video/omap2/dss/dss.c42
-rw-r--r--drivers/video/omap2/dss/dss.h23
-rw-r--r--drivers/video/omap2/dss/manager.c48
-rw-r--r--drivers/video/omap2/dss/overlay.c2
-rw-r--r--drivers/video/omap2/dss/rfbi.c321
-rw-r--r--drivers/video/omap2/dss/sdi.c115
-rw-r--r--drivers/video/omap2/dss/venc.c296
-rw-r--r--drivers/video/omap2/omapfb/Kconfig11
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c68
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c133
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h9
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/omapfb.h9
31 files changed, 2186 insertions, 1840 deletions
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index f312b1513753..a101029ceb6f 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -542,10 +542,6 @@ static struct regulator_init_data sdp3430_vdac = {
542/* VPLL2 for digital video outputs */ 542/* VPLL2 for digital video outputs */
543static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { 543static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
544 { 544 {
545 .supply = "vdvi",
546 .dev = &sdp3430_lcd_device.dev,
547 },
548 {
549 .supply = "vdds_dsi", 545 .supply = "vdds_dsi",
550 .dev = &sdp3430_dss_device.dev, 546 .dev = &sdp3430_dss_device.dev,
551 } 547 }
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index c66e464732df..1c529ce9dc11 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -233,8 +233,12 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
233void dsi_bus_lock(void); 233void dsi_bus_lock(void);
234void dsi_bus_unlock(void); 234void dsi_bus_unlock(void);
235int dsi_vc_dcs_write(int channel, u8 *data, int len); 235int dsi_vc_dcs_write(int channel, u8 *data, int len);
236int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd);
237int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param);
236int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len); 238int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
237int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen); 239int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
240int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data);
241int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data);
238int dsi_vc_set_max_rx_packet_size(int channel, u16 len); 242int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
239int dsi_vc_send_null(int channel); 243int dsi_vc_send_null(int channel);
240int dsi_vc_send_bta_sync(int channel); 244int dsi_vc_send_bta_sync(int channel);
@@ -367,6 +371,10 @@ struct omap_overlay_manager {
367 371
368 int (*apply)(struct omap_overlay_manager *mgr); 372 int (*apply)(struct omap_overlay_manager *mgr);
369 int (*wait_for_go)(struct omap_overlay_manager *mgr); 373 int (*wait_for_go)(struct omap_overlay_manager *mgr);
374 int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
375
376 int (*enable)(struct omap_overlay_manager *mgr);
377 int (*disable)(struct omap_overlay_manager *mgr);
370}; 378};
371 379
372struct omap_dss_device { 380struct omap_dss_device {
@@ -426,16 +434,11 @@ struct omap_dss_device {
426 int acb; /* ac-bias pin frequency */ 434 int acb; /* ac-bias pin frequency */
427 435
428 enum omap_panel_config config; 436 enum omap_panel_config config;
429
430 u8 recommended_bpp;
431
432 struct omap_dss_device *ctrl;
433 } panel; 437 } panel;
434 438
435 struct { 439 struct {
436 u8 pixel_size; 440 u8 pixel_size;
437 struct rfbi_timings rfbi_timings; 441 struct rfbi_timings rfbi_timings;
438 struct omap_dss_device *panel;
439 } ctrl; 442 } ctrl;
440 443
441 int reset_gpio; 444 int reset_gpio;
@@ -460,49 +463,6 @@ struct omap_dss_device {
460 463
461 enum omap_dss_display_state state; 464 enum omap_dss_display_state state;
462 465
463 int (*enable)(struct omap_dss_device *dssdev);
464 void (*disable)(struct omap_dss_device *dssdev);
465
466 int (*suspend)(struct omap_dss_device *dssdev);
467 int (*resume)(struct omap_dss_device *dssdev);
468
469 void (*get_resolution)(struct omap_dss_device *dssdev,
470 u16 *xres, u16 *yres);
471 int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
472
473 int (*check_timings)(struct omap_dss_device *dssdev,
474 struct omap_video_timings *timings);
475 void (*set_timings)(struct omap_dss_device *dssdev,
476 struct omap_video_timings *timings);
477 void (*get_timings)(struct omap_dss_device *dssdev,
478 struct omap_video_timings *timings);
479 int (*update)(struct omap_dss_device *dssdev,
480 u16 x, u16 y, u16 w, u16 h);
481 int (*sync)(struct omap_dss_device *dssdev);
482 int (*wait_vsync)(struct omap_dss_device *dssdev);
483
484 int (*set_update_mode)(struct omap_dss_device *dssdev,
485 enum omap_dss_update_mode);
486 enum omap_dss_update_mode (*get_update_mode)
487 (struct omap_dss_device *dssdev);
488
489 int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
490 int (*get_te)(struct omap_dss_device *dssdev);
491
492 u8 (*get_rotate)(struct omap_dss_device *dssdev);
493 int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
494
495 bool (*get_mirror)(struct omap_dss_device *dssdev);
496 int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
497
498 int (*run_test)(struct omap_dss_device *dssdev, int test);
499 int (*memory_read)(struct omap_dss_device *dssdev,
500 void *buf, size_t size,
501 u16 x, u16 y, u16 w, u16 h);
502
503 int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
504 u32 (*get_wss)(struct omap_dss_device *dssdev);
505
506 /* platform specific */ 466 /* platform specific */
507 int (*platform_enable)(struct omap_dss_device *dssdev); 467 int (*platform_enable)(struct omap_dss_device *dssdev);
508 void (*platform_disable)(struct omap_dss_device *dssdev); 468 void (*platform_disable)(struct omap_dss_device *dssdev);
@@ -522,11 +482,17 @@ struct omap_dss_driver {
522 int (*resume)(struct omap_dss_device *display); 482 int (*resume)(struct omap_dss_device *display);
523 int (*run_test)(struct omap_dss_device *display, int test); 483 int (*run_test)(struct omap_dss_device *display, int test);
524 484
525 void (*setup_update)(struct omap_dss_device *dssdev, 485 int (*set_update_mode)(struct omap_dss_device *dssdev,
526 u16 x, u16 y, u16 w, u16 h); 486 enum omap_dss_update_mode);
487 enum omap_dss_update_mode (*get_update_mode)(
488 struct omap_dss_device *dssdev);
489
490 int (*update)(struct omap_dss_device *dssdev,
491 u16 x, u16 y, u16 w, u16 h);
492 int (*sync)(struct omap_dss_device *dssdev);
527 493
528 int (*enable_te)(struct omap_dss_device *dssdev, bool enable); 494 int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
529 int (*wait_for_te)(struct omap_dss_device *dssdev); 495 int (*get_te)(struct omap_dss_device *dssdev);
530 496
531 u8 (*get_rotate)(struct omap_dss_device *dssdev); 497 u8 (*get_rotate)(struct omap_dss_device *dssdev);
532 int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate); 498 int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
@@ -537,6 +503,20 @@ struct omap_dss_driver {
537 int (*memory_read)(struct omap_dss_device *dssdev, 503 int (*memory_read)(struct omap_dss_device *dssdev,
538 void *buf, size_t size, 504 void *buf, size_t size,
539 u16 x, u16 y, u16 w, u16 h); 505 u16 x, u16 y, u16 w, u16 h);
506
507 void (*get_resolution)(struct omap_dss_device *dssdev,
508 u16 *xres, u16 *yres);
509 int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
510
511 int (*check_timings)(struct omap_dss_device *dssdev,
512 struct omap_video_timings *timings);
513 void (*set_timings)(struct omap_dss_device *dssdev,
514 struct omap_video_timings *timings);
515 void (*get_timings)(struct omap_dss_device *dssdev,
516 struct omap_video_timings *timings);
517
518 int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
519 u32 (*get_wss)(struct omap_dss_device *dssdev);
540}; 520};
541 521
542int omap_dss_register_driver(struct omap_dss_driver *); 522int omap_dss_register_driver(struct omap_dss_driver *);
@@ -561,6 +541,10 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
561int omap_dss_get_num_overlays(void); 541int omap_dss_get_num_overlays(void);
562struct omap_overlay *omap_dss_get_overlay(int num); 542struct omap_overlay *omap_dss_get_overlay(int num);
563 543
544void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
545 u16 *xres, u16 *yres);
546int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
547
564typedef void (*omap_dispc_isr_t) (void *arg, u32 mask); 548typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
565int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask); 549int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
566int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask); 550int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
@@ -572,4 +556,35 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
572#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver) 556#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
573#define to_dss_device(x) container_of((x), struct omap_dss_device, dev) 557#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
574 558
559void omapdss_dsi_vc_enable_hs(int channel, bool enable);
560int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
561
562int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
563 u16 *x, u16 *y, u16 *w, u16 *h);
564int omap_dsi_update(struct omap_dss_device *dssdev,
565 int channel,
566 u16 x, u16 y, u16 w, u16 h,
567 void (*callback)(int, void *), void *data);
568
569int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
570void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
571
572int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
573void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
574void dpi_set_timings(struct omap_dss_device *dssdev,
575 struct omap_video_timings *timings);
576int dpi_check_timings(struct omap_dss_device *dssdev,
577 struct omap_video_timings *timings);
578
579int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
580void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
581
582int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
583void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
584int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
585 u16 *x, u16 *y, u16 *w, u16 *h);
586int omap_rfbi_update(struct omap_dss_device *dssdev,
587 u16 x, u16 y, u16 w, u16 h,
588 void (*callback)(void *), void *data);
589
575#endif 590#endif
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index 567db6ac32c8..6978ae4ef83a 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/lcd.h>
27 28
28#include <plat/board-ams-delta.h> 29#include <plat/board-ams-delta.h>
29#include <mach/hardware.h> 30#include <mach/hardware.h>
@@ -32,6 +33,71 @@
32 33
33#define AMS_DELTA_DEFAULT_CONTRAST 112 34#define AMS_DELTA_DEFAULT_CONTRAST 112
34 35
36#define AMS_DELTA_MAX_CONTRAST 0x00FF
37#define AMS_DELTA_LCD_POWER 0x0100
38
39
40/* LCD class device section */
41
42static int ams_delta_lcd;
43
44static int ams_delta_lcd_set_power(struct lcd_device *dev, int power)
45{
46 if (power == FB_BLANK_UNBLANK) {
47 if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) {
48 omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST,
49 OMAP_PWL_ENABLE);
50 omap_writeb(1, OMAP_PWL_CLK_ENABLE);
51 ams_delta_lcd |= AMS_DELTA_LCD_POWER;
52 }
53 } else {
54 if (ams_delta_lcd & AMS_DELTA_LCD_POWER) {
55 omap_writeb(0, OMAP_PWL_ENABLE);
56 omap_writeb(0, OMAP_PWL_CLK_ENABLE);
57 ams_delta_lcd &= ~AMS_DELTA_LCD_POWER;
58 }
59 }
60 return 0;
61}
62
63static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value)
64{
65 if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) {
66 omap_writeb(value, OMAP_PWL_ENABLE);
67 ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST;
68 ams_delta_lcd |= value;
69 }
70 return 0;
71}
72
73#ifdef CONFIG_LCD_CLASS_DEVICE
74static int ams_delta_lcd_get_power(struct lcd_device *dev)
75{
76 if (ams_delta_lcd & AMS_DELTA_LCD_POWER)
77 return FB_BLANK_UNBLANK;
78 else
79 return FB_BLANK_POWERDOWN;
80}
81
82static int ams_delta_lcd_get_contrast(struct lcd_device *dev)
83{
84 if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER))
85 return 0;
86
87 return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST;
88}
89
90static struct lcd_ops ams_delta_lcd_ops = {
91 .get_power = ams_delta_lcd_get_power,
92 .set_power = ams_delta_lcd_set_power,
93 .get_contrast = ams_delta_lcd_get_contrast,
94 .set_contrast = ams_delta_lcd_set_contrast,
95};
96#endif
97
98
99/* omapfb panel section */
100
35static int ams_delta_panel_init(struct lcd_panel *panel, 101static int ams_delta_panel_init(struct lcd_panel *panel,
36 struct omapfb_device *fbdev) 102 struct omapfb_device *fbdev)
37{ 103{
@@ -48,10 +114,6 @@ static int ams_delta_panel_enable(struct lcd_panel *panel)
48 AMS_DELTA_LATCH2_LCD_NDISP); 114 AMS_DELTA_LATCH2_LCD_NDISP);
49 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 115 ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN,
50 AMS_DELTA_LATCH2_LCD_VBLEN); 116 AMS_DELTA_LATCH2_LCD_VBLEN);
51
52 omap_writeb(1, OMAP_PWL_CLK_ENABLE);
53 omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE);
54
55 return 0; 117 return 0;
56} 118}
57 119
@@ -91,8 +153,31 @@ static struct lcd_panel ams_delta_panel = {
91 .get_caps = ams_delta_panel_get_caps, 153 .get_caps = ams_delta_panel_get_caps,
92}; 154};
93 155
156
157/* platform driver section */
158
94static int ams_delta_panel_probe(struct platform_device *pdev) 159static int ams_delta_panel_probe(struct platform_device *pdev)
95{ 160{
161 struct lcd_device *lcd_device = NULL;
162#ifdef CONFIG_LCD_CLASS_DEVICE
163 int ret;
164
165 lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL,
166 &ams_delta_lcd_ops);
167
168 if (IS_ERR(lcd_device)) {
169 ret = PTR_ERR(lcd_device);
170 dev_err(&pdev->dev, "failed to register device\n");
171 return ret;
172 }
173
174 platform_set_drvdata(pdev, lcd_device);
175 lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST;
176#endif
177
178 ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST);
179 ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
180
96 omapfb_register_panel(&ams_delta_panel); 181 omapfb_register_panel(&ams_delta_panel);
97 return 0; 182 return 0;
98} 183}
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 2c4f470fa086..8ce60e1b220a 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -486,10 +486,11 @@ static int set_color_mode(struct omapfb_plane_struct *plane,
486 return 0; 486 return 0;
487 case 12: 487 case 12:
488 var->bits_per_pixel = 16; 488 var->bits_per_pixel = 16;
489 plane->color_mode = OMAPFB_COLOR_RGB444;
490 return 0;
491 case 16: 489 case 16:
492 plane->color_mode = OMAPFB_COLOR_RGB565; 490 if (plane->fbdev->panel->bpp == 12)
491 plane->color_mode = OMAPFB_COLOR_RGB444;
492 else
493 plane->color_mode = OMAPFB_COLOR_RGB565;
493 return 0; 494 return 0;
494 default: 495 default:
495 return -EINVAL; 496 return -EINVAL;
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index b12a59c9c50a..dfb57ee50861 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -13,10 +13,28 @@ config PANEL_SHARP_LS037V7DW01
13 help 13 help
14 LCD Panel used in TI's SDP3430 and EVM boards 14 LCD Panel used in TI's SDP3430 and EVM boards
15 15
16config PANEL_SHARP_LQ043T1DG01
17 tristate "Sharp LQ043T1DG01 LCD Panel"
18 depends on OMAP2_DSS
19 help
20 LCD Panel used in TI's OMAP3517 EVM boards
21
16config PANEL_TAAL 22config PANEL_TAAL
17 tristate "Taal DSI Panel" 23 tristate "Taal DSI Panel"
18 depends on OMAP2_DSS_DSI 24 depends on OMAP2_DSS_DSI
19 help 25 help
20 Taal DSI command mode panel from TPO. 26 Taal DSI command mode panel from TPO.
21 27
28config PANEL_TOPPOLY_TDO35S
29 tristate "Toppoly TDO35S LCD Panel support"
30 depends on OMAP2_DSS
31 help
32 LCD Panel used in CM-T35
33
34config PANEL_TPO_TD043MTEA1
35 tristate "TPO TD043MTEA1 LCD Panel"
36 depends on OMAP2_DSS && I2C
37 help
38 LCD Panel used in OMAP3 Pandora
39
22endmenu 40endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 955646440b3a..e2bb32168dee 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,4 +1,7 @@
1obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o 1obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o
3 4
4obj-$(CONFIG_PANEL_TAAL) += panel-taal.o 5obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
6obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o
7obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
index eb48d1afd800..c59e4baed8b2 100644
--- a/drivers/video/omap2/displays/panel-generic.c
+++ b/drivers/video/omap2/displays/panel-generic.c
@@ -35,6 +35,35 @@ static struct omap_video_timings generic_panel_timings = {
35 .vbp = 7, 35 .vbp = 7,
36}; 36};
37 37
38static int generic_panel_power_on(struct omap_dss_device *dssdev)
39{
40 int r;
41
42 r = omapdss_dpi_display_enable(dssdev);
43 if (r)
44 goto err0;
45
46 if (dssdev->platform_enable) {
47 r = dssdev->platform_enable(dssdev);
48 if (r)
49 goto err1;
50 }
51
52 return 0;
53err1:
54 omapdss_dpi_display_disable(dssdev);
55err0:
56 return r;
57}
58
59static void generic_panel_power_off(struct omap_dss_device *dssdev)
60{
61 if (dssdev->platform_disable)
62 dssdev->platform_disable(dssdev);
63
64 omapdss_dpi_display_disable(dssdev);
65}
66
38static int generic_panel_probe(struct omap_dss_device *dssdev) 67static int generic_panel_probe(struct omap_dss_device *dssdev)
39{ 68{
40 dssdev->panel.config = OMAP_DSS_LCD_TFT; 69 dssdev->panel.config = OMAP_DSS_LCD_TFT;
@@ -51,27 +80,40 @@ static int generic_panel_enable(struct omap_dss_device *dssdev)
51{ 80{
52 int r = 0; 81 int r = 0;
53 82
54 if (dssdev->platform_enable) 83 r = generic_panel_power_on(dssdev);
55 r = dssdev->platform_enable(dssdev); 84 if (r)
85 return r;
56 86
57 return r; 87 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
88
89 return 0;
58} 90}
59 91
60static void generic_panel_disable(struct omap_dss_device *dssdev) 92static void generic_panel_disable(struct omap_dss_device *dssdev)
61{ 93{
62 if (dssdev->platform_disable) 94 generic_panel_power_off(dssdev);
63 dssdev->platform_disable(dssdev); 95
96 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
64} 97}
65 98
66static int generic_panel_suspend(struct omap_dss_device *dssdev) 99static int generic_panel_suspend(struct omap_dss_device *dssdev)
67{ 100{
68 generic_panel_disable(dssdev); 101 generic_panel_power_off(dssdev);
102 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
69 return 0; 103 return 0;
70} 104}
71 105
72static int generic_panel_resume(struct omap_dss_device *dssdev) 106static int generic_panel_resume(struct omap_dss_device *dssdev)
73{ 107{
74 return generic_panel_enable(dssdev); 108 int r = 0;
109
110 r = generic_panel_power_on(dssdev);
111 if (r)
112 return r;
113
114 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
115
116 return 0;
75} 117}
76 118
77static struct omap_dss_driver generic_driver = { 119static struct omap_dss_driver generic_driver = {
diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
new file mode 100644
index 000000000000..10267461991c
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
@@ -0,0 +1,159 @@
1/*
2 * LCD panel driver for Sharp LQ043T1DG01
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/device.h>
23#include <linux/err.h>
24
25#include <plat/display.h>
26
27static struct omap_video_timings sharp_lq_timings = {
28 .x_res = 480,
29 .y_res = 272,
30
31 .pixel_clock = 9000,
32
33 .hsw = 42,
34 .hfp = 3,
35 .hbp = 2,
36
37 .vsw = 11,
38 .vfp = 3,
39 .vbp = 2,
40};
41
42static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev)
43{
44 int r;
45
46 r = omapdss_dpi_display_enable(dssdev);
47 if (r)
48 goto err0;
49
50 /* wait couple of vsyncs until enabling the LCD */
51 msleep(50);
52
53 if (dssdev->platform_enable) {
54 r = dssdev->platform_enable(dssdev);
55 if (r)
56 goto err1;
57 }
58
59 return 0;
60err1:
61 omapdss_dpi_display_disable(dssdev);
62err0:
63 return r;
64}
65
66static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev)
67{
68 if (dssdev->platform_disable)
69 dssdev->platform_disable(dssdev);
70
71 /* wait at least 5 vsyncs after disabling the LCD */
72 msleep(100);
73
74 omapdss_dpi_display_disable(dssdev);
75}
76
77static int sharp_lq_panel_probe(struct omap_dss_device *dssdev)
78{
79
80 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
81 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO;
82 dssdev->panel.acb = 0x0;
83 dssdev->panel.timings = sharp_lq_timings;
84
85 return 0;
86}
87
88static void sharp_lq_panel_remove(struct omap_dss_device *dssdev)
89{
90}
91
92static int sharp_lq_panel_enable(struct omap_dss_device *dssdev)
93{
94 int r = 0;
95
96 r = sharp_lq_panel_power_on(dssdev);
97 if (r)
98 return r;
99
100 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
101
102 return 0;
103}
104
105static void sharp_lq_panel_disable(struct omap_dss_device *dssdev)
106{
107 sharp_lq_panel_power_off(dssdev);
108
109 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
110}
111
112static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev)
113{
114 sharp_lq_panel_power_off(dssdev);
115 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
116 return 0;
117}
118
119static int sharp_lq_panel_resume(struct omap_dss_device *dssdev)
120{
121 int r = 0;
122
123 r = sharp_lq_panel_power_on(dssdev);
124 if (r)
125 return r;
126
127 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
128
129 return 0;
130}
131
132static struct omap_dss_driver sharp_lq_driver = {
133 .probe = sharp_lq_panel_probe,
134 .remove = sharp_lq_panel_remove,
135
136 .enable = sharp_lq_panel_enable,
137 .disable = sharp_lq_panel_disable,
138 .suspend = sharp_lq_panel_suspend,
139 .resume = sharp_lq_panel_resume,
140
141 .driver = {
142 .name = "sharp_lq_panel",
143 .owner = THIS_MODULE,
144 },
145};
146
147static int __init sharp_lq_panel_drv_init(void)
148{
149 return omap_dss_register_driver(&sharp_lq_driver);
150}
151
152static void __exit sharp_lq_panel_drv_exit(void)
153{
154 omap_dss_unregister_driver(&sharp_lq_driver);
155}
156
157module_init(sharp_lq_panel_drv_init);
158module_exit(sharp_lq_panel_drv_exit);
159MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bbe880bbe795..8d51a5e6341c 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -20,19 +20,10 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/regulator/consumer.h>
24#include <linux/err.h> 23#include <linux/err.h>
25 24
26#include <plat/display.h> 25#include <plat/display.h>
27 26
28struct sharp_data {
29 /* XXX This regulator should actually be in SDP board file, not here,
30 * as it doesn't actually power the LCD, but something else that
31 * affects the output to LCD (I think. Somebody clarify). It doesn't do
32 * harm here, as SDP is the only board using this currently */
33 struct regulator *vdvi_reg;
34};
35
36static struct omap_video_timings sharp_ls_timings = { 27static struct omap_video_timings sharp_ls_timings = {
37 .x_res = 480, 28 .x_res = 480,
38 .y_res = 640, 29 .y_res = 640,
@@ -50,77 +41,81 @@ static struct omap_video_timings sharp_ls_timings = {
50 41
51static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) 42static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
52{ 43{
53 struct sharp_data *sd;
54
55 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 44 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
56 OMAP_DSS_LCD_IHS; 45 OMAP_DSS_LCD_IHS;
57 dssdev->panel.acb = 0x28; 46 dssdev->panel.acb = 0x28;
58 dssdev->panel.timings = sharp_ls_timings; 47 dssdev->panel.timings = sharp_ls_timings;
59 48
60 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
61 if (!sd)
62 return -ENOMEM;
63
64 dev_set_drvdata(&dssdev->dev, sd);
65
66 sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi");
67 if (IS_ERR(sd->vdvi_reg)) {
68 kfree(sd);
69 pr_err("failed to get VDVI regulator\n");
70 return PTR_ERR(sd->vdvi_reg);
71 }
72
73 return 0; 49 return 0;
74} 50}
75 51
76static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) 52static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
77{ 53{
78 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
79
80 regulator_put(sd->vdvi_reg);
81
82 kfree(sd);
83} 54}
84 55
85static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) 56static int sharp_ls_power_on(struct omap_dss_device *dssdev)
86{ 57{
87 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
88 int r = 0; 58 int r = 0;
89 59
60 r = omapdss_dpi_display_enable(dssdev);
61 if (r)
62 goto err0;
63
90 /* wait couple of vsyncs until enabling the LCD */ 64 /* wait couple of vsyncs until enabling the LCD */
91 msleep(50); 65 msleep(50);
92 66
93 regulator_enable(sd->vdvi_reg); 67 if (dssdev->platform_enable) {
94
95 if (dssdev->platform_enable)
96 r = dssdev->platform_enable(dssdev); 68 r = dssdev->platform_enable(dssdev);
69 if (r)
70 goto err1;
71 }
97 72
73 return 0;
74err1:
75 omapdss_dpi_display_disable(dssdev);
76err0:
98 return r; 77 return r;
99} 78}
100 79
101static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) 80static void sharp_ls_power_off(struct omap_dss_device *dssdev)
102{ 81{
103 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
104
105 if (dssdev->platform_disable) 82 if (dssdev->platform_disable)
106 dssdev->platform_disable(dssdev); 83 dssdev->platform_disable(dssdev);
107 84
108 regulator_disable(sd->vdvi_reg);
109
110 /* wait at least 5 vsyncs after disabling the LCD */ 85 /* wait at least 5 vsyncs after disabling the LCD */
111 86
112 msleep(100); 87 msleep(100);
88
89 omapdss_dpi_display_disable(dssdev);
90}
91
92static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
93{
94 int r;
95 r = sharp_ls_power_on(dssdev);
96 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
97 return r;
98}
99
100static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
101{
102 sharp_ls_power_off(dssdev);
103 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
113} 104}
114 105
115static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev) 106static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
116{ 107{
117 sharp_ls_panel_disable(dssdev); 108 sharp_ls_power_off(dssdev);
109 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
118 return 0; 110 return 0;
119} 111}
120 112
121static int sharp_ls_panel_resume(struct omap_dss_device *dssdev) 113static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
122{ 114{
123 return sharp_ls_panel_enable(dssdev); 115 int r;
116 r = sharp_ls_power_on(dssdev);
117 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
118 return r;
124} 119}
125 120
126static struct omap_dss_driver sharp_ls_driver = { 121static struct omap_dss_driver sharp_ls_driver = {
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 1f01dfc5e52e..fcd6a61a91eb 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -63,6 +63,8 @@
63/* #define TAAL_USE_ESD_CHECK */ 63/* #define TAAL_USE_ESD_CHECK */
64#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000) 64#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
65 65
66static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
67
66struct taal_data { 68struct taal_data {
67 struct backlight_device *bldev; 69 struct backlight_device *bldev;
68 70
@@ -510,15 +512,12 @@ static int taal_probe(struct omap_dss_device *dssdev)
510 if (td->esd_wq == NULL) { 512 if (td->esd_wq == NULL) {
511 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 513 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
512 r = -ENOMEM; 514 r = -ENOMEM;
513 goto err2; 515 goto err1;
514 } 516 }
515 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); 517 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
516 518
517 dev_set_drvdata(&dssdev->dev, td); 519 dev_set_drvdata(&dssdev->dev, td);
518 520
519 dssdev->get_timings = taal_get_timings;
520 dssdev->get_resolution = taal_get_resolution;
521
522 /* if no platform set_backlight() defined, presume DSI backlight 521 /* if no platform set_backlight() defined, presume DSI backlight
523 * control */ 522 * control */
524 if (!dssdev->set_backlight) 523 if (!dssdev->set_backlight)
@@ -528,7 +527,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
528 &taal_bl_ops); 527 &taal_bl_ops);
529 if (IS_ERR(bldev)) { 528 if (IS_ERR(bldev)) {
530 r = PTR_ERR(bldev); 529 r = PTR_ERR(bldev);
531 goto err1; 530 goto err2;
532 } 531 }
533 532
534 td->bldev = bldev; 533 td->bldev = bldev;
@@ -621,14 +620,12 @@ static void taal_remove(struct omap_dss_device *dssdev)
621 kfree(td); 620 kfree(td);
622} 621}
623 622
624static int taal_enable(struct omap_dss_device *dssdev) 623static int taal_power_on(struct omap_dss_device *dssdev)
625{ 624{
626 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 625 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
627 u8 id1, id2, id3; 626 u8 id1, id2, id3;
628 int r; 627 int r;
629 628
630 dev_dbg(&dssdev->dev, "enable\n");
631
632 if (dssdev->platform_enable) { 629 if (dssdev->platform_enable) {
633 r = dssdev->platform_enable(dssdev); 630 r = dssdev->platform_enable(dssdev);
634 if (r) 631 if (r)
@@ -638,6 +635,16 @@ static int taal_enable(struct omap_dss_device *dssdev)
638 /* it seems we have to wait a bit until taal is ready */ 635 /* it seems we have to wait a bit until taal is ready */
639 msleep(5); 636 msleep(5);
640 637
638 dsi_bus_lock();
639
640 r = omapdss_dsi_display_enable(dssdev);
641 if (r) {
642 dev_err(&dssdev->dev, "failed to enable DSI\n");
643 goto err0;
644 }
645
646 omapdss_dsi_vc_enable_hs(TCH, false);
647
641 r = taal_sleep_out(td); 648 r = taal_sleep_out(td);
642 if (r) 649 if (r)
643 goto err; 650 goto err;
@@ -661,6 +668,10 @@ static int taal_enable(struct omap_dss_device *dssdev)
661 668
662 taal_dcs_write_0(DCS_DISPLAY_ON); 669 taal_dcs_write_0(DCS_DISPLAY_ON);
663 670
671 r = _taal_enable_te(dssdev, td->te_enabled);
672 if (r)
673 goto err;
674
664#ifdef TAAL_USE_ESD_CHECK 675#ifdef TAAL_USE_ESD_CHECK
665 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 676 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
666#endif 677#endif
@@ -676,19 +687,27 @@ static int taal_enable(struct omap_dss_device *dssdev)
676 td->intro_printed = true; 687 td->intro_printed = true;
677 } 688 }
678 689
690 omapdss_dsi_vc_enable_hs(TCH, true);
691
692 dsi_bus_unlock();
693
679 return 0; 694 return 0;
680err: 695err:
696 dsi_bus_unlock();
697
698 omapdss_dsi_display_disable(dssdev);
699err0:
681 if (dssdev->platform_disable) 700 if (dssdev->platform_disable)
682 dssdev->platform_disable(dssdev); 701 dssdev->platform_disable(dssdev);
683 702
684 return r; 703 return r;
685} 704}
686 705
687static void taal_disable(struct omap_dss_device *dssdev) 706static void taal_power_off(struct omap_dss_device *dssdev)
688{ 707{
689 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 708 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
690 709
691 dev_dbg(&dssdev->dev, "disable\n"); 710 dsi_bus_lock();
692 711
693 cancel_delayed_work(&td->esd_work); 712 cancel_delayed_work(&td->esd_work);
694 713
@@ -698,41 +717,124 @@ static void taal_disable(struct omap_dss_device *dssdev)
698 /* wait a bit so that the message goes through */ 717 /* wait a bit so that the message goes through */
699 msleep(10); 718 msleep(10);
700 719
720 omapdss_dsi_display_disable(dssdev);
721
701 if (dssdev->platform_disable) 722 if (dssdev->platform_disable)
702 dssdev->platform_disable(dssdev); 723 dssdev->platform_disable(dssdev);
703 724
704 td->enabled = 0; 725 td->enabled = 0;
726
727 dsi_bus_unlock();
728}
729
730static int taal_enable(struct omap_dss_device *dssdev)
731{
732 int r;
733 dev_dbg(&dssdev->dev, "enable\n");
734
735 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
736 return -EINVAL;
737
738 r = taal_power_on(dssdev);
739 if (r)
740 return r;
741
742 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
743
744 return r;
745}
746
747static void taal_disable(struct omap_dss_device *dssdev)
748{
749 dev_dbg(&dssdev->dev, "disable\n");
750
751 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
752 taal_power_off(dssdev);
753
754 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
705} 755}
706 756
707static int taal_suspend(struct omap_dss_device *dssdev) 757static int taal_suspend(struct omap_dss_device *dssdev)
708{ 758{
709 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 759 dev_dbg(&dssdev->dev, "suspend\n");
710 struct backlight_device *bldev = td->bldev;
711 760
712 bldev->props.power = FB_BLANK_POWERDOWN; 761 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
713 taal_bl_update_status(bldev); 762 return -EINVAL;
763
764 taal_power_off(dssdev);
765 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
714 766
715 return 0; 767 return 0;
716} 768}
717 769
718static int taal_resume(struct omap_dss_device *dssdev) 770static int taal_resume(struct omap_dss_device *dssdev)
719{ 771{
772 int r;
773 dev_dbg(&dssdev->dev, "resume\n");
774
775 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
776 return -EINVAL;
777
778 r = taal_power_on(dssdev);
779 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
780 return r;
781}
782
783static void taal_framedone_cb(int err, void *data)
784{
785 struct omap_dss_device *dssdev = data;
786 dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
787 dsi_bus_unlock();
788}
789
790static int taal_update(struct omap_dss_device *dssdev,
791 u16 x, u16 y, u16 w, u16 h)
792{
720 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 793 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
721 struct backlight_device *bldev = td->bldev; 794 int r;
722 795
723 bldev->props.power = FB_BLANK_UNBLANK; 796 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
724 taal_bl_update_status(bldev); 797
798 dsi_bus_lock();
799
800 if (!td->enabled) {
801 r = 0;
802 goto err;
803 }
804
805 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h);
806 if (r)
807 goto err;
808
809 r = taal_set_update_window(x, y, w, h);
810 if (r)
811 goto err;
812
813 r = omap_dsi_update(dssdev, TCH, x, y, w, h,
814 taal_framedone_cb, dssdev);
815 if (r)
816 goto err;
725 817
818 /* note: no bus_unlock here. unlock is in framedone_cb */
726 return 0; 819 return 0;
820err:
821 dsi_bus_unlock();
822 return r;
727} 823}
728 824
729static void taal_setup_update(struct omap_dss_device *dssdev, 825static int taal_sync(struct omap_dss_device *dssdev)
730 u16 x, u16 y, u16 w, u16 h)
731{ 826{
732 taal_set_update_window(x, y, w, h); 827 dev_dbg(&dssdev->dev, "sync\n");
828
829 dsi_bus_lock();
830 dsi_bus_unlock();
831
832 dev_dbg(&dssdev->dev, "sync done\n");
833
834 return 0;
733} 835}
734 836
735static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) 837static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
736{ 838{
737 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 839 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
738 int r; 840 int r;
@@ -744,25 +846,32 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
744 else 846 else
745 r = taal_dcs_write_0(DCS_TEAR_OFF); 847 r = taal_dcs_write_0(DCS_TEAR_OFF);
746 848
849 omapdss_dsi_enable_te(dssdev, enable);
850
851 /* XXX for some reason, DSI TE breaks if we don't wait here.
852 * Panel bug? Needs more studying */
853 msleep(100);
854
747 return r; 855 return r;
748} 856}
749 857
750static int taal_wait_te(struct omap_dss_device *dssdev) 858static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
751{ 859{
752 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 860 int r;
753 long wait = msecs_to_jiffies(500);
754 861
755 if (!td->use_ext_te || !td->te_enabled) 862 dsi_bus_lock();
756 return 0;
757 863
758 INIT_COMPLETION(td->te_completion); 864 r = _taal_enable_te(dssdev, enable);
759 wait = wait_for_completion_timeout(&td->te_completion, wait);
760 if (wait == 0) {
761 dev_err(&dssdev->dev, "timeout waiting TE\n");
762 return -ETIME;
763 }
764 865
765 return 0; 866 dsi_bus_unlock();
867
868 return r;
869}
870
871static int taal_get_te(struct omap_dss_device *dssdev)
872{
873 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
874 return td->te_enabled;
766} 875}
767 876
768static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) 877static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
@@ -772,16 +881,21 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
772 881
773 dev_dbg(&dssdev->dev, "rotate %d\n", rotate); 882 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
774 883
884 dsi_bus_lock();
885
775 if (td->enabled) { 886 if (td->enabled) {
776 r = taal_set_addr_mode(rotate, td->mirror); 887 r = taal_set_addr_mode(rotate, td->mirror);
777
778 if (r) 888 if (r)
779 return r; 889 goto err;
780 } 890 }
781 891
782 td->rotate = rotate; 892 td->rotate = rotate;
783 893
894 dsi_bus_unlock();
784 return 0; 895 return 0;
896err:
897 dsi_bus_unlock();
898 return r;
785} 899}
786 900
787static u8 taal_get_rotate(struct omap_dss_device *dssdev) 901static u8 taal_get_rotate(struct omap_dss_device *dssdev)
@@ -797,16 +911,20 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
797 911
798 dev_dbg(&dssdev->dev, "mirror %d\n", enable); 912 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
799 913
914 dsi_bus_lock();
800 if (td->enabled) { 915 if (td->enabled) {
801 r = taal_set_addr_mode(td->rotate, enable); 916 r = taal_set_addr_mode(td->rotate, enable);
802
803 if (r) 917 if (r)
804 return r; 918 goto err;
805 } 919 }
806 920
807 td->mirror = enable; 921 td->mirror = enable;
808 922
923 dsi_bus_unlock();
809 return 0; 924 return 0;
925err:
926 dsi_bus_unlock();
927 return r;
810} 928}
811 929
812static bool taal_get_mirror(struct omap_dss_device *dssdev) 930static bool taal_get_mirror(struct omap_dss_device *dssdev)
@@ -820,17 +938,23 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
820 u8 id1, id2, id3; 938 u8 id1, id2, id3;
821 int r; 939 int r;
822 940
941 dsi_bus_lock();
942
823 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 943 r = taal_dcs_read_1(DCS_GET_ID1, &id1);
824 if (r) 944 if (r)
825 return r; 945 goto err;
826 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 946 r = taal_dcs_read_1(DCS_GET_ID2, &id2);
827 if (r) 947 if (r)
828 return r; 948 goto err;
829 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 949 r = taal_dcs_read_1(DCS_GET_ID3, &id3);
830 if (r) 950 if (r)
831 return r; 951 goto err;
832 952
953 dsi_bus_unlock();
833 return 0; 954 return 0;
955err:
956 dsi_bus_unlock();
957 return r;
834} 958}
835 959
836static int taal_memory_read(struct omap_dss_device *dssdev, 960static int taal_memory_read(struct omap_dss_device *dssdev,
@@ -841,6 +965,10 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
841 int first = 1; 965 int first = 1;
842 int plen; 966 int plen;
843 unsigned buf_used = 0; 967 unsigned buf_used = 0;
968 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
969
970 if (!td->enabled)
971 return -ENODEV;
844 972
845 if (size < w * h * 3) 973 if (size < w * h * 3)
846 return -ENOMEM; 974 return -ENOMEM;
@@ -849,6 +977,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
849 dssdev->panel.timings.x_res * 977 dssdev->panel.timings.x_res *
850 dssdev->panel.timings.y_res * 3); 978 dssdev->panel.timings.y_res * 3);
851 979
980 dsi_bus_lock();
981
852 /* plen 1 or 2 goes into short packet. until checksum error is fixed, 982 /* plen 1 or 2 goes into short packet. until checksum error is fixed,
853 * use short packets. plen 32 works, but bigger packets seem to cause 983 * use short packets. plen 32 works, but bigger packets seem to cause
854 * an error. */ 984 * an error. */
@@ -857,11 +987,11 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
857 else 987 else
858 plen = 2; 988 plen = 2;
859 989
860 taal_setup_update(dssdev, x, y, w, h); 990 taal_set_update_window(x, y, w, h);
861 991
862 r = dsi_vc_set_max_rx_packet_size(TCH, plen); 992 r = dsi_vc_set_max_rx_packet_size(TCH, plen);
863 if (r) 993 if (r)
864 return r; 994 goto err0;
865 995
866 while (buf_used < size) { 996 while (buf_used < size) {
867 u8 dcs_cmd = first ? 0x2e : 0x3e; 997 u8 dcs_cmd = first ? 0x2e : 0x3e;
@@ -894,7 +1024,8 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
894 1024
895err: 1025err:
896 dsi_vc_set_max_rx_packet_size(TCH, 1); 1026 dsi_vc_set_max_rx_packet_size(TCH, 1);
897 1027err0:
1028 dsi_bus_unlock();
898 return r; 1029 return r;
899} 1030}
900 1031
@@ -939,8 +1070,11 @@ static void taal_esd_work(struct work_struct *work)
939 } 1070 }
940 /* Self-diagnostics result is also shown on TE GPIO line. We need 1071 /* Self-diagnostics result is also shown on TE GPIO line. We need
941 * to re-enable TE after self diagnostics */ 1072 * to re-enable TE after self diagnostics */
942 if (td->use_ext_te && td->te_enabled) 1073 if (td->use_ext_te && td->te_enabled) {
943 taal_enable_te(dssdev, true); 1074 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
1075 if (r)
1076 goto err;
1077 }
944 1078
945 dsi_bus_unlock(); 1079 dsi_bus_unlock();
946 1080
@@ -958,6 +1092,20 @@ err:
958 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 1092 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
959} 1093}
960 1094
1095static int taal_set_update_mode(struct omap_dss_device *dssdev,
1096 enum omap_dss_update_mode mode)
1097{
1098 if (mode != OMAP_DSS_UPDATE_MANUAL)
1099 return -EINVAL;
1100 return 0;
1101}
1102
1103static enum omap_dss_update_mode taal_get_update_mode(
1104 struct omap_dss_device *dssdev)
1105{
1106 return OMAP_DSS_UPDATE_MANUAL;
1107}
1108
961static struct omap_dss_driver taal_driver = { 1109static struct omap_dss_driver taal_driver = {
962 .probe = taal_probe, 1110 .probe = taal_probe,
963 .remove = taal_remove, 1111 .remove = taal_remove,
@@ -967,9 +1115,18 @@ static struct omap_dss_driver taal_driver = {
967 .suspend = taal_suspend, 1115 .suspend = taal_suspend,
968 .resume = taal_resume, 1116 .resume = taal_resume,
969 1117
970 .setup_update = taal_setup_update, 1118 .set_update_mode = taal_set_update_mode,
1119 .get_update_mode = taal_get_update_mode,
1120
1121 .update = taal_update,
1122 .sync = taal_sync,
1123
1124 .get_resolution = taal_get_resolution,
1125 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
1126
971 .enable_te = taal_enable_te, 1127 .enable_te = taal_enable_te,
972 .wait_for_te = taal_wait_te, 1128 .get_te = taal_get_te,
1129
973 .set_rotate = taal_rotate, 1130 .set_rotate = taal_rotate,
974 .get_rotate = taal_get_rotate, 1131 .get_rotate = taal_get_rotate,
975 .set_mirror = taal_mirror, 1132 .set_mirror = taal_mirror,
@@ -977,6 +1134,8 @@ static struct omap_dss_driver taal_driver = {
977 .run_test = taal_run_test, 1134 .run_test = taal_run_test,
978 .memory_read = taal_memory_read, 1135 .memory_read = taal_memory_read,
979 1136
1137 .get_timings = taal_get_timings,
1138
980 .driver = { 1139 .driver = {
981 .name = "taal", 1140 .name = "taal",
982 .owner = THIS_MODULE, 1141 .owner = THIS_MODULE,
diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
new file mode 100644
index 000000000000..fa434ca6e4b7
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
@@ -0,0 +1,154 @@
1/*
2 * LCD panel driver for Toppoly TDO35S
3 *
4 * Copyright (C) 2009 CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on generic panel support
8 * Copyright (C) 2008 Nokia Corporation
9 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <linux/module.h>
25#include <linux/delay.h>
26
27#include <plat/display.h>
28
29static struct omap_video_timings toppoly_tdo_panel_timings = {
30 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
31 .x_res = 480,
32 .y_res = 640,
33
34 .pixel_clock = 26000,
35
36 .hfp = 104,
37 .hsw = 8,
38 .hbp = 8,
39
40 .vfp = 4,
41 .vsw = 2,
42 .vbp = 2,
43};
44
45static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 r = omapdss_dpi_display_enable(dssdev);
50 if (r)
51 goto err0;
52
53 if (dssdev->platform_enable) {
54 r = dssdev->platform_enable(dssdev);
55 if (r)
56 goto err1;
57 }
58
59 return 0;
60err1:
61 omapdss_dpi_display_disable(dssdev);
62err0:
63 return r;
64}
65
66static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
67{
68 if (dssdev->platform_disable)
69 dssdev->platform_disable(dssdev);
70
71 omapdss_dpi_display_disable(dssdev);
72}
73
74static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
75{
76 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
77 OMAP_DSS_LCD_IHS;
78 dssdev->panel.timings = toppoly_tdo_panel_timings;
79
80 return 0;
81}
82
83static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev)
84{
85}
86
87static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev)
88{
89 int r = 0;
90
91 r = toppoly_tdo_panel_power_on(dssdev);
92 if (r)
93 return r;
94
95 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
96
97 return 0;
98}
99
100static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev)
101{
102 toppoly_tdo_panel_power_off(dssdev);
103
104 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
105}
106
107static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev)
108{
109 toppoly_tdo_panel_power_off(dssdev);
110 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
111 return 0;
112}
113
114static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev)
115{
116 int r = 0;
117
118 r = toppoly_tdo_panel_power_on(dssdev);
119 if (r)
120 return r;
121
122 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
123
124 return 0;
125}
126
127static struct omap_dss_driver generic_driver = {
128 .probe = toppoly_tdo_panel_probe,
129 .remove = toppoly_tdo_panel_remove,
130
131 .enable = toppoly_tdo_panel_enable,
132 .disable = toppoly_tdo_panel_disable,
133 .suspend = toppoly_tdo_panel_suspend,
134 .resume = toppoly_tdo_panel_resume,
135
136 .driver = {
137 .name = "toppoly_tdo35s_panel",
138 .owner = THIS_MODULE,
139 },
140};
141
142static int __init toppoly_tdo_panel_drv_init(void)
143{
144 return omap_dss_register_driver(&generic_driver);
145}
146
147static void __exit toppoly_tdo_panel_drv_exit(void)
148{
149 omap_dss_unregister_driver(&generic_driver);
150}
151
152module_init(toppoly_tdo_panel_drv_init);
153module_exit(toppoly_tdo_panel_drv_exit);
154MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
new file mode 100644
index 000000000000..d578feee3550
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -0,0 +1,528 @@
1/*
2 * LCD panel driver for TPO TD043MTEA1
3 *
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/spi/spi.h>
15#include <linux/regulator/consumer.h>
16#include <linux/gpio.h>
17#include <linux/err.h>
18
19#include <plat/display.h>
20
21#define TPO_R02_MODE(x) ((x) & 7)
22#define TPO_R02_MODE_800x480 7
23#define TPO_R02_NCLK_RISING BIT(3)
24#define TPO_R02_HSYNC_HIGH BIT(4)
25#define TPO_R02_VSYNC_HIGH BIT(5)
26
27#define TPO_R03_NSTANDBY BIT(0)
28#define TPO_R03_EN_CP_CLK BIT(1)
29#define TPO_R03_EN_VGL_PUMP BIT(2)
30#define TPO_R03_EN_PWM BIT(3)
31#define TPO_R03_DRIVING_CAP_100 BIT(4)
32#define TPO_R03_EN_PRE_CHARGE BIT(6)
33#define TPO_R03_SOFTWARE_CTL BIT(7)
34
35#define TPO_R04_NFLIP_H BIT(0)
36#define TPO_R04_NFLIP_V BIT(1)
37#define TPO_R04_CP_CLK_FREQ_1H BIT(2)
38#define TPO_R04_VGL_FREQ_1H BIT(4)
39
40#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \
41 TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \
42 TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
43 TPO_R03_SOFTWARE_CTL)
44
45#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \
46 TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL)
47
48static const u16 tpo_td043_def_gamma[12] = {
49 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020
50};
51
52struct tpo_td043_device {
53 struct spi_device *spi;
54 struct regulator *vcc_reg;
55 u16 gamma[12];
56 u32 mode;
57 u32 hmirror:1;
58 u32 vmirror:1;
59};
60
61static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
62{
63 struct spi_message m;
64 struct spi_transfer xfer;
65 u16 w;
66 int r;
67
68 spi_message_init(&m);
69
70 memset(&xfer, 0, sizeof(xfer));
71
72 w = ((u16)addr << 10) | (1 << 8) | data;
73 xfer.tx_buf = &w;
74 xfer.bits_per_word = 16;
75 xfer.len = 2;
76 spi_message_add_tail(&xfer, &m);
77
78 r = spi_sync(spi, &m);
79 if (r < 0)
80 dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r);
81 return r;
82}
83
84static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12])
85{
86 u8 i, val;
87
88 /* gamma bits [9:8] */
89 for (val = i = 0; i < 4; i++)
90 val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
91 tpo_td043_write(spi, 0x11, val);
92
93 for (val = i = 0; i < 4; i++)
94 val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2);
95 tpo_td043_write(spi, 0x12, val);
96
97 for (val = i = 0; i < 4; i++)
98 val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2);
99 tpo_td043_write(spi, 0x13, val);
100
101 /* gamma bits [7:0] */
102 for (val = i = 0; i < 12; i++)
103 tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff);
104}
105
106static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v)
107{
108 u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \
109 TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H;
110 if (h)
111 reg4 &= ~TPO_R04_NFLIP_H;
112 if (v)
113 reg4 &= ~TPO_R04_NFLIP_V;
114
115 return tpo_td043_write(spi, 4, reg4);
116}
117
118static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable)
119{
120 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
121
122 tpo_td043->hmirror = enable;
123 return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
124 tpo_td043->vmirror);
125}
126
127static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev)
128{
129 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
130
131 return tpo_td043->hmirror;
132}
133
134static ssize_t tpo_td043_vmirror_show(struct device *dev,
135 struct device_attribute *attr, char *buf)
136{
137 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
138
139 return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror);
140}
141
142static ssize_t tpo_td043_vmirror_store(struct device *dev,
143 struct device_attribute *attr, const char *buf, size_t count)
144{
145 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
146 long val;
147 int ret;
148
149 ret = strict_strtol(buf, 0, &val);
150 if (ret < 0)
151 return ret;
152
153 ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
154 if (ret < 0)
155 return ret;
156
157 tpo_td043->vmirror = val;
158
159 return count;
160}
161
162static ssize_t tpo_td043_mode_show(struct device *dev,
163 struct device_attribute *attr, char *buf)
164{
165 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
166
167 return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode);
168}
169
170static ssize_t tpo_td043_mode_store(struct device *dev,
171 struct device_attribute *attr, const char *buf, size_t count)
172{
173 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
174 long val;
175 int ret;
176
177 ret = strict_strtol(buf, 0, &val);
178 if (ret != 0 || val & ~7)
179 return -EINVAL;
180
181 tpo_td043->mode = val;
182
183 val |= TPO_R02_NCLK_RISING;
184 tpo_td043_write(tpo_td043->spi, 2, val);
185
186 return count;
187}
188
189static ssize_t tpo_td043_gamma_show(struct device *dev,
190 struct device_attribute *attr, char *buf)
191{
192 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
193 ssize_t len = 0;
194 int ret;
195 int i;
196
197 for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) {
198 ret = snprintf(buf + len, PAGE_SIZE - len, "%u ",
199 tpo_td043->gamma[i]);
200 if (ret < 0)
201 return ret;
202 len += ret;
203 }
204 buf[len - 1] = '\n';
205
206 return len;
207}
208
209static ssize_t tpo_td043_gamma_store(struct device *dev,
210 struct device_attribute *attr, const char *buf, size_t count)
211{
212 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
213 unsigned int g[12];
214 int ret;
215 int i;
216
217 ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u",
218 &g[0], &g[1], &g[2], &g[3], &g[4], &g[5],
219 &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]);
220
221 if (ret != 12)
222 return -EINVAL;
223
224 for (i = 0; i < 12; i++)
225 tpo_td043->gamma[i] = g[i];
226
227 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
228
229 return count;
230}
231
232static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR,
233 tpo_td043_vmirror_show, tpo_td043_vmirror_store);
234static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
235 tpo_td043_mode_show, tpo_td043_mode_store);
236static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR,
237 tpo_td043_gamma_show, tpo_td043_gamma_store);
238
239static struct attribute *tpo_td043_attrs[] = {
240 &dev_attr_vmirror.attr,
241 &dev_attr_mode.attr,
242 &dev_attr_gamma.attr,
243 NULL,
244};
245
246static struct attribute_group tpo_td043_attr_group = {
247 .attrs = tpo_td043_attrs,
248};
249
250static const struct omap_video_timings tpo_td043_timings = {
251 .x_res = 800,
252 .y_res = 480,
253
254 .pixel_clock = 36000,
255
256 .hsw = 1,
257 .hfp = 68,
258 .hbp = 214,
259
260 .vsw = 1,
261 .vfp = 39,
262 .vbp = 34,
263};
264
265static int tpo_td043_power_on(struct omap_dss_device *dssdev)
266{
267 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
268 int nreset_gpio = dssdev->reset_gpio;
269 int r;
270
271 r = omapdss_dpi_display_enable(dssdev);
272 if (r)
273 goto err0;
274
275 if (dssdev->platform_enable) {
276 r = dssdev->platform_enable(dssdev);
277 if (r)
278 goto err1;
279 }
280
281 regulator_enable(tpo_td043->vcc_reg);
282
283 /* wait for power up */
284 msleep(160);
285
286 if (gpio_is_valid(nreset_gpio))
287 gpio_set_value(nreset_gpio, 1);
288
289 tpo_td043_write(tpo_td043->spi, 2,
290 TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
291 tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL);
292 tpo_td043_write(tpo_td043->spi, 0x20, 0xf0);
293 tpo_td043_write(tpo_td043->spi, 0x21, 0xf0);
294 tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror,
295 tpo_td043->vmirror);
296 tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma);
297
298 return 0;
299err1:
300 omapdss_dpi_display_disable(dssdev);
301err0:
302 return r;
303}
304
305static void tpo_td043_power_off(struct omap_dss_device *dssdev)
306{
307 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
308 int nreset_gpio = dssdev->reset_gpio;
309
310 tpo_td043_write(tpo_td043->spi, 3,
311 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
312
313 if (gpio_is_valid(nreset_gpio))
314 gpio_set_value(nreset_gpio, 0);
315
316 /* wait for at least 2 vsyncs before cutting off power */
317 msleep(50);
318
319 tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY);
320
321 regulator_disable(tpo_td043->vcc_reg);
322
323 if (dssdev->platform_disable)
324 dssdev->platform_disable(dssdev);
325
326 omapdss_dpi_display_disable(dssdev);
327}
328
329static int tpo_td043_enable(struct omap_dss_device *dssdev)
330{
331 int ret;
332
333 dev_dbg(&dssdev->dev, "enable\n");
334
335 ret = tpo_td043_power_on(dssdev);
336 if (ret)
337 return ret;
338
339 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
340
341 return 0;
342}
343
344static void tpo_td043_disable(struct omap_dss_device *dssdev)
345{
346 dev_dbg(&dssdev->dev, "disable\n");
347
348 tpo_td043_power_off(dssdev);
349
350 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
351}
352
353static int tpo_td043_suspend(struct omap_dss_device *dssdev)
354{
355 tpo_td043_power_off(dssdev);
356 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
357 return 0;
358}
359
360static int tpo_td043_resume(struct omap_dss_device *dssdev)
361{
362 int r = 0;
363
364 r = tpo_td043_power_on(dssdev);
365 if (r)
366 return r;
367
368 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
369
370 return 0;
371}
372
373static int tpo_td043_probe(struct omap_dss_device *dssdev)
374{
375 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
376 int nreset_gpio = dssdev->reset_gpio;
377 int ret = 0;
378
379 dev_dbg(&dssdev->dev, "probe\n");
380
381 if (tpo_td043 == NULL) {
382 dev_err(&dssdev->dev, "missing tpo_td043_device\n");
383 return -ENODEV;
384 }
385
386 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS |
387 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC;
388 dssdev->panel.timings = tpo_td043_timings;
389 dssdev->ctrl.pixel_size = 24;
390
391 tpo_td043->mode = TPO_R02_MODE_800x480;
392 memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma));
393
394 tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc");
395 if (IS_ERR(tpo_td043->vcc_reg)) {
396 dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n");
397 ret = PTR_ERR(tpo_td043->vcc_reg);
398 goto fail_regulator;
399 }
400
401 if (gpio_is_valid(nreset_gpio)) {
402 ret = gpio_request(nreset_gpio, "lcd reset");
403 if (ret < 0) {
404 dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
405 goto fail_gpio_req;
406 }
407
408 ret = gpio_direction_output(nreset_gpio, 0);
409 if (ret < 0) {
410 dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
411 goto fail_gpio_direction;
412 }
413 }
414
415 ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
416 if (ret)
417 dev_warn(&dssdev->dev, "failed to create sysfs files\n");
418
419 return 0;
420
421fail_gpio_direction:
422 gpio_free(nreset_gpio);
423fail_gpio_req:
424 regulator_put(tpo_td043->vcc_reg);
425fail_regulator:
426 kfree(tpo_td043);
427 return ret;
428}
429
430static void tpo_td043_remove(struct omap_dss_device *dssdev)
431{
432 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
433 int nreset_gpio = dssdev->reset_gpio;
434
435 dev_dbg(&dssdev->dev, "remove\n");
436
437 sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
438 regulator_put(tpo_td043->vcc_reg);
439 if (gpio_is_valid(nreset_gpio))
440 gpio_free(nreset_gpio);
441}
442
443static struct omap_dss_driver tpo_td043_driver = {
444 .probe = tpo_td043_probe,
445 .remove = tpo_td043_remove,
446
447 .enable = tpo_td043_enable,
448 .disable = tpo_td043_disable,
449 .suspend = tpo_td043_suspend,
450 .resume = tpo_td043_resume,
451 .set_mirror = tpo_td043_set_hmirror,
452 .get_mirror = tpo_td043_get_hmirror,
453
454 .driver = {
455 .name = "tpo_td043mtea1_panel",
456 .owner = THIS_MODULE,
457 },
458};
459
460static int tpo_td043_spi_probe(struct spi_device *spi)
461{
462 struct omap_dss_device *dssdev = spi->dev.platform_data;
463 struct tpo_td043_device *tpo_td043;
464 int ret;
465
466 if (dssdev == NULL) {
467 dev_err(&spi->dev, "missing dssdev\n");
468 return -ENODEV;
469 }
470
471 spi->bits_per_word = 16;
472 spi->mode = SPI_MODE_0;
473
474 ret = spi_setup(spi);
475 if (ret < 0) {
476 dev_err(&spi->dev, "spi_setup failed: %d\n", ret);
477 return ret;
478 }
479
480 tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL);
481 if (tpo_td043 == NULL)
482 return -ENOMEM;
483
484 tpo_td043->spi = spi;
485 dev_set_drvdata(&spi->dev, tpo_td043);
486 dev_set_drvdata(&dssdev->dev, tpo_td043);
487
488 omap_dss_register_driver(&tpo_td043_driver);
489
490 return 0;
491}
492
493static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
494{
495 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev);
496
497 omap_dss_unregister_driver(&tpo_td043_driver);
498 kfree(tpo_td043);
499
500 return 0;
501}
502
503static struct spi_driver tpo_td043_spi_driver = {
504 .driver = {
505 .name = "tpo_td043mtea1_panel_spi",
506 .bus = &spi_bus_type,
507 .owner = THIS_MODULE,
508 },
509 .probe = tpo_td043_spi_probe,
510 .remove = __devexit_p(tpo_td043_spi_remove),
511};
512
513static int __init tpo_td043_init(void)
514{
515 return spi_register_driver(&tpo_td043_spi_driver);
516}
517
518static void __exit tpo_td043_exit(void)
519{
520 spi_unregister_driver(&tpo_td043_spi_driver);
521}
522
523module_init(tpo_td043_init);
524module_exit(tpo_td043_exit);
525
526MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
527MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
528MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index c63ce767b277..87afb81b2c44 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS
30 depends on OMAP2_DSS_DEBUG_SUPPORT 30 depends on OMAP2_DSS_DEBUG_SUPPORT
31 default n 31 default n
32 help 32 help
33 Collect DSS IRQ statistics, printable via debugfs 33 Collect DSS IRQ statistics, printable via debugfs.
34
35 The statistics can be found from
36 <debugfs>/omapdss/dispc_irq for DISPC interrupts, and
37 <debugfs>/omapdss/dsi_irq for DSI interrupts.
34 38
35config OMAP2_DSS_RFBI 39config OMAP2_DSS_RFBI
36 bool "RFBI support" 40 bool "RFBI support"
37 default n 41 default n
38 help 42 help
39 MIPI DBI, or RFBI (Remote Framebuffer Interface), support. 43 MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
44 Instrument's terminology).
45
46 DBI is a bus between the host processor and a peripheral,
47 such as a display or a framebuffer chip.
48
49 See http://www.mipi.org/ for DBI spesifications.
40 50
41config OMAP2_DSS_VENC 51config OMAP2_DSS_VENC
42 bool "VENC support" 52 bool "VENC support"
43 default y 53 default y
44 help 54 help
45 OMAP Video Encoder support. 55 OMAP Video Encoder support for S-Video and composite TV-out.
46 56
47config OMAP2_DSS_SDI 57config OMAP2_DSS_SDI
48 bool "SDI support" 58 bool "SDI support"
@@ -51,12 +61,20 @@ config OMAP2_DSS_SDI
51 help 61 help
52 SDI (Serial Display Interface) support. 62 SDI (Serial Display Interface) support.
53 63
64 SDI is a high speed one-way display serial bus between the host
65 processor and a display.
66
54config OMAP2_DSS_DSI 67config OMAP2_DSS_DSI
55 bool "DSI support" 68 bool "DSI support"
56 depends on ARCH_OMAP3 69 depends on ARCH_OMAP3
57 default n 70 default n
58 help 71 help
59 MIPI DSI support. 72 MIPI DSI (Display Serial Interface) support.
73
74 DSI is a high speed half-duplex serial interface between the host
75 processor and a peripheral, such as a display or a framebuffer chip.
76
77 See http://www.mipi.org/ for DSI spesifications.
60 78
61config OMAP2_DSS_USE_DSI_PLL 79config OMAP2_DSS_USE_DSI_PLL
62 bool "Use DSI PLL for PCLK (EXPERIMENTAL)" 80 bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 82918eec6d2e..7ebe50b335ed 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);
@@ -284,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks)
284 289
285void dss_clk_enable(enum dss_clock clks) 290void dss_clk_enable(enum dss_clock clks)
286{ 291{
292 bool check_ctx = core.num_clks_enabled == 0;
293
287 dss_clk_enable_no_ctx(clks); 294 dss_clk_enable_no_ctx(clks);
288 295
289 if (cpu_is_omap34xx() && dss_need_ctx_restore()) 296 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
290 restore_all_ctx(); 297 restore_all_ctx();
291} 298}
292 299
@@ -352,6 +359,50 @@ static void dss_clk_disable_all(void)
352 dss_clk_disable(clks); 359 dss_clk_disable(clks);
353} 360}
354 361
362/* REGULATORS */
363
364struct regulator *dss_get_vdds_dsi(void)
365{
366 struct regulator *reg;
367
368 if (core.vdds_dsi_reg != NULL)
369 return core.vdds_dsi_reg;
370
371 reg = regulator_get(&core.pdev->dev, "vdds_dsi");
372 if (!IS_ERR(reg))
373 core.vdds_dsi_reg = reg;
374
375 return reg;
376}
377
378struct regulator *dss_get_vdds_sdi(void)
379{
380 struct regulator *reg;
381
382 if (core.vdds_sdi_reg != NULL)
383 return core.vdds_sdi_reg;
384
385 reg = regulator_get(&core.pdev->dev, "vdds_sdi");
386 if (!IS_ERR(reg))
387 core.vdds_sdi_reg = reg;
388
389 return reg;
390}
391
392struct regulator *dss_get_vdda_dac(void)
393{
394 struct regulator *reg;
395
396 if (core.vdda_dac_reg != NULL)
397 return core.vdda_dac_reg;
398
399 reg = regulator_get(&core.pdev->dev, "vdda_dac");
400 if (!IS_ERR(reg))
401 core.vdda_dac_reg = reg;
402
403 return reg;
404}
405
355/* DEBUGFS */ 406/* DEBUGFS */
356#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 407#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
357static void dss_debug_dump_clocks(struct seq_file *s) 408static void dss_debug_dump_clocks(struct seq_file *s)
@@ -397,10 +448,12 @@ static int dss_initialize_debugfs(void)
397 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, 448 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
398 &dss_debug_dump_clocks, &dss_debug_fops); 449 &dss_debug_dump_clocks, &dss_debug_fops);
399 450
451#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
400 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, 452 debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
401 &dispc_dump_irqs, &dss_debug_fops); 453 &dispc_dump_irqs, &dss_debug_fops);
454#endif
402 455
403#ifdef CONFIG_OMAP2_DSS_DSI 456#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
404 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, 457 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
405 &dsi_dump_irqs, &dss_debug_fops); 458 &dsi_dump_irqs, &dss_debug_fops);
406#endif 459#endif
@@ -473,7 +526,7 @@ static int omap_dss_probe(struct platform_device *pdev)
473 } 526 }
474#endif 527#endif
475 528
476 r = dpi_init(); 529 r = dpi_init(pdev);
477 if (r) { 530 if (r) {
478 DSSERR("Failed to initialize dpi\n"); 531 DSSERR("Failed to initialize dpi\n");
479 goto fail0; 532 goto fail0;
@@ -718,16 +771,14 @@ static int dss_driver_probe(struct device *dev)
718 771
719 dss_init_device(core.pdev, dssdev); 772 dss_init_device(core.pdev, dssdev);
720 773
721 /* skip this if the device is behind a ctrl */ 774 force = pdata->default_device == dssdev;
722 if (!dssdev->panel.ctrl) { 775 dss_recheck_connections(dssdev, force);
723 force = pdata->default_device == dssdev;
724 dss_recheck_connections(dssdev, force);
725 }
726 776
727 r = dssdrv->probe(dssdev); 777 r = dssdrv->probe(dssdev);
728 778
729 if (r) { 779 if (r) {
730 DSSERR("driver probe failed: %d\n", r); 780 DSSERR("driver probe failed: %d\n", r);
781 dss_uninit_device(core.pdev, dssdev);
731 return r; 782 return r;
732 } 783 }
733 784
@@ -760,6 +811,13 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
760 dssdriver->driver.bus = &dss_bus_type; 811 dssdriver->driver.bus = &dss_bus_type;
761 dssdriver->driver.probe = dss_driver_probe; 812 dssdriver->driver.probe = dss_driver_probe;
762 dssdriver->driver.remove = dss_driver_remove; 813 dssdriver->driver.remove = dss_driver_remove;
814
815 if (dssdriver->get_resolution == NULL)
816 dssdriver->get_resolution = omapdss_default_get_resolution;
817 if (dssdriver->get_recommended_bpp == NULL)
818 dssdriver->get_recommended_bpp =
819 omapdss_default_get_recommended_bpp;
820
763 return driver_register(&dssdriver->driver); 821 return driver_register(&dssdriver->driver);
764} 822}
765EXPORT_SYMBOL(omap_dss_register_driver); 823EXPORT_SYMBOL(omap_dss_register_driver);
@@ -808,8 +866,6 @@ static void omap_dss_dev_release(struct device *dev)
808int omap_dss_register_device(struct omap_dss_device *dssdev) 866int omap_dss_register_device(struct omap_dss_device *dssdev)
809{ 867{
810 static int dev_num; 868 static int dev_num;
811 static int panel_num;
812 int r;
813 869
814 WARN_ON(!dssdev->driver_name); 870 WARN_ON(!dssdev->driver_name);
815 871
@@ -818,36 +874,12 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
818 dssdev->dev.parent = &dss_bus; 874 dssdev->dev.parent = &dss_bus;
819 dssdev->dev.release = omap_dss_dev_release; 875 dssdev->dev.release = omap_dss_dev_release;
820 dev_set_name(&dssdev->dev, "display%d", dev_num++); 876 dev_set_name(&dssdev->dev, "display%d", dev_num++);
821 r = device_register(&dssdev->dev); 877 return device_register(&dssdev->dev);
822 if (r)
823 return r;
824
825 if (dssdev->ctrl.panel) {
826 struct omap_dss_device *panel = dssdev->ctrl.panel;
827
828 panel->panel.ctrl = dssdev;
829
830 reset_device(&panel->dev, 1);
831 panel->dev.bus = &dss_bus_type;
832 panel->dev.parent = &dssdev->dev;
833 panel->dev.release = omap_dss_dev_release;
834 dev_set_name(&panel->dev, "panel%d", panel_num++);
835 r = device_register(&panel->dev);
836 if (r)
837 return r;
838 }
839
840 return 0;
841} 878}
842 879
843void omap_dss_unregister_device(struct omap_dss_device *dssdev) 880void omap_dss_unregister_device(struct omap_dss_device *dssdev)
844{ 881{
845 device_unregister(&dssdev->dev); 882 device_unregister(&dssdev->dev);
846
847 if (dssdev->ctrl.panel) {
848 struct omap_dss_device *panel = dssdev->ctrl.panel;
849 device_unregister(&panel->dev);
850 }
851} 883}
852 884
853/* BUS */ 885/* BUS */
@@ -901,6 +933,21 @@ static int __init omap_dss_init(void)
901 933
902static void __exit omap_dss_exit(void) 934static void __exit omap_dss_exit(void)
903{ 935{
936 if (core.vdds_dsi_reg != NULL) {
937 regulator_put(core.vdds_dsi_reg);
938 core.vdds_dsi_reg = NULL;
939 }
940
941 if (core.vdds_sdi_reg != NULL) {
942 regulator_put(core.vdds_sdi_reg);
943 core.vdds_sdi_reg = NULL;
944 }
945
946 if (core.vdda_dac_reg != NULL) {
947 regulator_put(core.vdda_dac_reg);
948 core.vdda_dac_reg = NULL;
949 }
950
904 platform_driver_unregister(&omap_dss_driver); 951 platform_driver_unregister(&omap_dss_driver);
905 952
906 omap_dss_bus_unregister(); 953 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index de8bfbac9e26..e777e352dbcd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1725,7 +1725,7 @@ static void _enable_lcd_out(bool enable)
1725 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1725 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
1726} 1726}
1727 1727
1728void dispc_enable_lcd_out(bool enable) 1728static void dispc_enable_lcd_out(bool enable)
1729{ 1729{
1730 struct completion frame_done_completion; 1730 struct completion frame_done_completion;
1731 bool is_on; 1731 bool is_on;
@@ -1772,7 +1772,7 @@ static void _enable_digit_out(bool enable)
1772 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); 1772 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
1773} 1773}
1774 1774
1775void dispc_enable_digit_out(bool enable) 1775static void dispc_enable_digit_out(bool enable)
1776{ 1776{
1777 struct completion frame_done_completion; 1777 struct completion frame_done_completion;
1778 int r; 1778 int r;
@@ -1836,6 +1836,26 @@ void dispc_enable_digit_out(bool enable)
1836 enable_clocks(0); 1836 enable_clocks(0);
1837} 1837}
1838 1838
1839bool dispc_is_channel_enabled(enum omap_channel channel)
1840{
1841 if (channel == OMAP_DSS_CHANNEL_LCD)
1842 return !!REG_GET(DISPC_CONTROL, 0, 0);
1843 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1844 return !!REG_GET(DISPC_CONTROL, 1, 1);
1845 else
1846 BUG();
1847}
1848
1849void dispc_enable_channel(enum omap_channel channel, bool enable)
1850{
1851 if (channel == OMAP_DSS_CHANNEL_LCD)
1852 dispc_enable_lcd_out(enable);
1853 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1854 dispc_enable_digit_out(enable);
1855 else
1856 BUG();
1857}
1858
1839void dispc_lcd_enable_signal_polarity(bool act_high) 1859void dispc_lcd_enable_signal_polarity(bool act_high)
1840{ 1860{
1841 enable_clocks(1); 1861 enable_clocks(1);
@@ -2198,7 +2218,7 @@ unsigned long dispc_fclk_rate(void)
2198{ 2218{
2199 unsigned long r = 0; 2219 unsigned long r = 0;
2200 2220
2201 if (dss_get_dispc_clk_source() == 0) 2221 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
2202 r = dss_clk_get_rate(DSS_CLK_FCK1); 2222 r = dss_clk_get_rate(DSS_CLK_FCK1);
2203 else 2223 else
2204#ifdef CONFIG_OMAP2_DSS_DSI 2224#ifdef CONFIG_OMAP2_DSS_DSI
@@ -2251,7 +2271,7 @@ void dispc_dump_clocks(struct seq_file *s)
2251 seq_printf(s, "- DISPC -\n"); 2271 seq_printf(s, "- DISPC -\n");
2252 2272
2253 seq_printf(s, "dispc fclk source = %s\n", 2273 seq_printf(s, "dispc fclk source = %s\n",
2254 dss_get_dispc_clk_source() == 0 ? 2274 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
2255 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2275 "dss1_alwon_fclk" : "dsi1_pll_fclk");
2256 2276
2257 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2277 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
@@ -2301,8 +2321,6 @@ void dispc_dump_irqs(struct seq_file *s)
2301 PIS(WAKEUP); 2321 PIS(WAKEUP);
2302#undef PIS 2322#undef PIS
2303} 2323}
2304#else
2305void dispc_dump_irqs(struct seq_file *s) { }
2306#endif 2324#endif
2307 2325
2308void dispc_dump_regs(struct seq_file *s) 2326void dispc_dump_regs(struct seq_file *s)
@@ -2854,12 +2872,13 @@ static void dispc_error_worker(struct work_struct *work)
2854 manager = mgr; 2872 manager = mgr;
2855 enable = mgr->device->state == 2873 enable = mgr->device->state ==
2856 OMAP_DSS_DISPLAY_ACTIVE; 2874 OMAP_DSS_DISPLAY_ACTIVE;
2857 mgr->device->disable(mgr->device); 2875 mgr->device->driver->disable(mgr->device);
2858 break; 2876 break;
2859 } 2877 }
2860 } 2878 }
2861 2879
2862 if (manager) { 2880 if (manager) {
2881 struct omap_dss_device *dssdev = manager->device;
2863 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 2882 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2864 struct omap_overlay *ovl; 2883 struct omap_overlay *ovl;
2865 ovl = omap_dss_get_overlay(i); 2884 ovl = omap_dss_get_overlay(i);
@@ -2874,7 +2893,7 @@ static void dispc_error_worker(struct work_struct *work)
2874 dispc_go(manager->id); 2893 dispc_go(manager->id);
2875 mdelay(50); 2894 mdelay(50);
2876 if (enable) 2895 if (enable)
2877 manager->device->enable(manager->device); 2896 dssdev->driver->enable(dssdev);
2878 } 2897 }
2879 } 2898 }
2880 2899
@@ -2892,12 +2911,13 @@ static void dispc_error_worker(struct work_struct *work)
2892 manager = mgr; 2911 manager = mgr;
2893 enable = mgr->device->state == 2912 enable = mgr->device->state ==
2894 OMAP_DSS_DISPLAY_ACTIVE; 2913 OMAP_DSS_DISPLAY_ACTIVE;
2895 mgr->device->disable(mgr->device); 2914 mgr->device->driver->disable(mgr->device);
2896 break; 2915 break;
2897 } 2916 }
2898 } 2917 }
2899 2918
2900 if (manager) { 2919 if (manager) {
2920 struct omap_dss_device *dssdev = manager->device;
2901 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 2921 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2902 struct omap_overlay *ovl; 2922 struct omap_overlay *ovl;
2903 ovl = omap_dss_get_overlay(i); 2923 ovl = omap_dss_get_overlay(i);
@@ -2912,7 +2932,7 @@ static void dispc_error_worker(struct work_struct *work)
2912 dispc_go(manager->id); 2932 dispc_go(manager->id);
2913 mdelay(50); 2933 mdelay(50);
2914 if (enable) 2934 if (enable)
2915 manager->device->enable(manager->device); 2935 dssdev->driver->enable(dssdev);
2916 } 2936 }
2917 } 2937 }
2918 2938
@@ -2923,7 +2943,7 @@ static void dispc_error_worker(struct work_struct *work)
2923 mgr = omap_dss_get_overlay_manager(i); 2943 mgr = omap_dss_get_overlay_manager(i);
2924 2944
2925 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC) 2945 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
2926 mgr->device->disable(mgr->device); 2946 mgr->device->driver->disable(mgr->device);
2927 } 2947 }
2928 } 2948 }
2929 2949
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 3b92b84b9560..6a74ea116d29 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -53,11 +53,11 @@ static ssize_t display_enabled_store(struct device *dev,
53 53
54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
55 if (enabled) { 55 if (enabled) {
56 r = dssdev->enable(dssdev); 56 r = dssdev->driver->enable(dssdev);
57 if (r) 57 if (r)
58 return r; 58 return r;
59 } else { 59 } else {
60 dssdev->disable(dssdev); 60 dssdev->driver->disable(dssdev);
61 } 61 }
62 } 62 }
63 63
@@ -69,8 +69,8 @@ static ssize_t display_upd_mode_show(struct device *dev,
69{ 69{
70 struct omap_dss_device *dssdev = to_dss_device(dev); 70 struct omap_dss_device *dssdev = to_dss_device(dev);
71 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO; 71 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
72 if (dssdev->get_update_mode) 72 if (dssdev->driver->get_update_mode)
73 mode = dssdev->get_update_mode(dssdev); 73 mode = dssdev->driver->get_update_mode(dssdev);
74 return snprintf(buf, PAGE_SIZE, "%d\n", mode); 74 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
75} 75}
76 76
@@ -94,7 +94,7 @@ static ssize_t display_upd_mode_store(struct device *dev,
94 return -EINVAL; 94 return -EINVAL;
95 } 95 }
96 96
97 r = dssdev->set_update_mode(dssdev, mode); 97 r = dssdev->driver->set_update_mode(dssdev, mode);
98 if (r) 98 if (r)
99 return r; 99 return r;
100 100
@@ -106,7 +106,8 @@ static ssize_t display_tear_show(struct device *dev,
106{ 106{
107 struct omap_dss_device *dssdev = to_dss_device(dev); 107 struct omap_dss_device *dssdev = to_dss_device(dev);
108 return snprintf(buf, PAGE_SIZE, "%d\n", 108 return snprintf(buf, PAGE_SIZE, "%d\n",
109 dssdev->get_te ? dssdev->get_te(dssdev) : 0); 109 dssdev->driver->get_te ?
110 dssdev->driver->get_te(dssdev) : 0);
110} 111}
111 112
112static ssize_t display_tear_store(struct device *dev, 113static ssize_t display_tear_store(struct device *dev,
@@ -116,12 +117,12 @@ static ssize_t display_tear_store(struct device *dev,
116 unsigned long te; 117 unsigned long te;
117 int r; 118 int r;
118 119
119 if (!dssdev->enable_te || !dssdev->get_te) 120 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
120 return -ENOENT; 121 return -ENOENT;
121 122
122 te = simple_strtoul(buf, NULL, 0); 123 te = simple_strtoul(buf, NULL, 0);
123 124
124 r = dssdev->enable_te(dssdev, te); 125 r = dssdev->driver->enable_te(dssdev, te);
125 if (r) 126 if (r)
126 return r; 127 return r;
127 128
@@ -134,10 +135,10 @@ static ssize_t display_timings_show(struct device *dev,
134 struct omap_dss_device *dssdev = to_dss_device(dev); 135 struct omap_dss_device *dssdev = to_dss_device(dev);
135 struct omap_video_timings t; 136 struct omap_video_timings t;
136 137
137 if (!dssdev->get_timings) 138 if (!dssdev->driver->get_timings)
138 return -ENOENT; 139 return -ENOENT;
139 140
140 dssdev->get_timings(dssdev, &t); 141 dssdev->driver->get_timings(dssdev, &t);
141 142
142 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n", 143 return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
143 t.pixel_clock, 144 t.pixel_clock,
@@ -152,7 +153,7 @@ static ssize_t display_timings_store(struct device *dev,
152 struct omap_video_timings t; 153 struct omap_video_timings t;
153 int r, found; 154 int r, found;
154 155
155 if (!dssdev->set_timings || !dssdev->check_timings) 156 if (!dssdev->driver->set_timings || !dssdev->driver->check_timings)
156 return -ENOENT; 157 return -ENOENT;
157 158
158 found = 0; 159 found = 0;
@@ -171,11 +172,11 @@ static ssize_t display_timings_store(struct device *dev,
171 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9) 172 &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
172 return -EINVAL; 173 return -EINVAL;
173 174
174 r = dssdev->check_timings(dssdev, &t); 175 r = dssdev->driver->check_timings(dssdev, &t);
175 if (r) 176 if (r)
176 return r; 177 return r;
177 178
178 dssdev->set_timings(dssdev, &t); 179 dssdev->driver->set_timings(dssdev, &t);
179 180
180 return size; 181 return size;
181} 182}
@@ -185,9 +186,9 @@ static ssize_t display_rotate_show(struct device *dev,
185{ 186{
186 struct omap_dss_device *dssdev = to_dss_device(dev); 187 struct omap_dss_device *dssdev = to_dss_device(dev);
187 int rotate; 188 int rotate;
188 if (!dssdev->get_rotate) 189 if (!dssdev->driver->get_rotate)
189 return -ENOENT; 190 return -ENOENT;
190 rotate = dssdev->get_rotate(dssdev); 191 rotate = dssdev->driver->get_rotate(dssdev);
191 return snprintf(buf, PAGE_SIZE, "%u\n", rotate); 192 return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
192} 193}
193 194
@@ -198,12 +199,12 @@ static ssize_t display_rotate_store(struct device *dev,
198 unsigned long rot; 199 unsigned long rot;
199 int r; 200 int r;
200 201
201 if (!dssdev->set_rotate || !dssdev->get_rotate) 202 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
202 return -ENOENT; 203 return -ENOENT;
203 204
204 rot = simple_strtoul(buf, NULL, 0); 205 rot = simple_strtoul(buf, NULL, 0);
205 206
206 r = dssdev->set_rotate(dssdev, rot); 207 r = dssdev->driver->set_rotate(dssdev, rot);
207 if (r) 208 if (r)
208 return r; 209 return r;
209 210
@@ -215,9 +216,9 @@ static ssize_t display_mirror_show(struct device *dev,
215{ 216{
216 struct omap_dss_device *dssdev = to_dss_device(dev); 217 struct omap_dss_device *dssdev = to_dss_device(dev);
217 int mirror; 218 int mirror;
218 if (!dssdev->get_mirror) 219 if (!dssdev->driver->get_mirror)
219 return -ENOENT; 220 return -ENOENT;
220 mirror = dssdev->get_mirror(dssdev); 221 mirror = dssdev->driver->get_mirror(dssdev);
221 return snprintf(buf, PAGE_SIZE, "%u\n", mirror); 222 return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
222} 223}
223 224
@@ -228,12 +229,12 @@ static ssize_t display_mirror_store(struct device *dev,
228 unsigned long mirror; 229 unsigned long mirror;
229 int r; 230 int r;
230 231
231 if (!dssdev->set_mirror || !dssdev->get_mirror) 232 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
232 return -ENOENT; 233 return -ENOENT;
233 234
234 mirror = simple_strtoul(buf, NULL, 0); 235 mirror = simple_strtoul(buf, NULL, 0);
235 236
236 r = dssdev->set_mirror(dssdev, mirror); 237 r = dssdev->driver->set_mirror(dssdev, mirror);
237 if (r) 238 if (r)
238 return r; 239 return r;
239 240
@@ -246,10 +247,10 @@ static ssize_t display_wss_show(struct device *dev,
246 struct omap_dss_device *dssdev = to_dss_device(dev); 247 struct omap_dss_device *dssdev = to_dss_device(dev);
247 unsigned int wss; 248 unsigned int wss;
248 249
249 if (!dssdev->get_wss) 250 if (!dssdev->driver->get_wss)
250 return -ENOENT; 251 return -ENOENT;
251 252
252 wss = dssdev->get_wss(dssdev); 253 wss = dssdev->driver->get_wss(dssdev);
253 254
254 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); 255 return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
255} 256}
@@ -261,7 +262,7 @@ static ssize_t display_wss_store(struct device *dev,
261 unsigned long wss; 262 unsigned long wss;
262 int r; 263 int r;
263 264
264 if (!dssdev->get_wss || !dssdev->set_wss) 265 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
265 return -ENOENT; 266 return -ENOENT;
266 267
267 if (strict_strtoul(buf, 0, &wss)) 268 if (strict_strtoul(buf, 0, &wss))
@@ -270,7 +271,7 @@ static ssize_t display_wss_store(struct device *dev,
270 if (wss > 0xfffff) 271 if (wss > 0xfffff)
271 return -EINVAL; 272 return -EINVAL;
272 273
273 r = dssdev->set_wss(dssdev, wss); 274 r = dssdev->driver->set_wss(dssdev, wss);
274 if (r) 275 if (r)
275 return r; 276 return r;
276 277
@@ -303,12 +304,13 @@ static struct device_attribute *display_sysfs_attrs[] = {
303 NULL 304 NULL
304}; 305};
305 306
306static void default_get_resolution(struct omap_dss_device *dssdev, 307void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
307 u16 *xres, u16 *yres) 308 u16 *xres, u16 *yres)
308{ 309{
309 *xres = dssdev->panel.timings.x_res; 310 *xres = dssdev->panel.timings.x_res;
310 *yres = dssdev->panel.timings.y_res; 311 *yres = dssdev->panel.timings.y_res;
311} 312}
313EXPORT_SYMBOL(omapdss_default_get_resolution);
312 314
313void default_get_overlay_fifo_thresholds(enum omap_plane plane, 315void default_get_overlay_fifo_thresholds(enum omap_plane plane,
314 u32 fifo_size, enum omap_burst_size *burst_size, 316 u32 fifo_size, enum omap_burst_size *burst_size,
@@ -323,24 +325,8 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
323 *fifo_low = fifo_size - burst_size_bytes; 325 *fifo_low = fifo_size - burst_size_bytes;
324} 326}
325 327
326static int default_wait_vsync(struct omap_dss_device *dssdev) 328int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
327{ 329{
328 unsigned long timeout = msecs_to_jiffies(500);
329 u32 irq;
330
331 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
332 irq = DISPC_IRQ_EVSYNC_ODD;
333 else
334 irq = DISPC_IRQ_VSYNC;
335
336 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
337}
338
339static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
340{
341 if (dssdev->panel.recommended_bpp)
342 return dssdev->panel.recommended_bpp;
343
344 switch (dssdev->type) { 330 switch (dssdev->type) {
345 case OMAP_DISPLAY_TYPE_DPI: 331 case OMAP_DISPLAY_TYPE_DPI:
346 if (dssdev->phy.dpi.data_lines == 24) 332 if (dssdev->phy.dpi.data_lines == 24)
@@ -362,6 +348,7 @@ static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
362 BUG(); 348 BUG();
363 } 349 }
364} 350}
351EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
365 352
366/* Checks if replication logic should be used. Only use for active matrix, 353/* Checks if replication logic should be used. Only use for active matrix,
367 * when overlay is in RGB12U or RGB16 mode, and LCD interface is 354 * when overlay is in RGB12U or RGB16 mode, and LCD interface is
@@ -425,10 +412,6 @@ void dss_init_device(struct platform_device *pdev,
425 return; 412 return;
426 } 413 }
427 414
428 dssdev->get_resolution = default_get_resolution;
429 dssdev->get_recommended_bpp = default_get_recommended_bpp;
430 dssdev->wait_vsync = default_wait_vsync;
431
432 switch (dssdev->type) { 415 switch (dssdev->type) {
433 case OMAP_DISPLAY_TYPE_DPI: 416 case OMAP_DISPLAY_TYPE_DPI:
434 r = dpi_init_display(dssdev); 417 r = dpi_init_display(dssdev);
@@ -502,13 +485,13 @@ static int dss_suspend_device(struct device *dev, void *data)
502 return 0; 485 return 0;
503 } 486 }
504 487
505 if (!dssdev->suspend) { 488 if (!dssdev->driver->suspend) {
506 DSSERR("display '%s' doesn't implement suspend\n", 489 DSSERR("display '%s' doesn't implement suspend\n",
507 dssdev->name); 490 dssdev->name);
508 return -ENOSYS; 491 return -ENOSYS;
509 } 492 }
510 493
511 r = dssdev->suspend(dssdev); 494 r = dssdev->driver->suspend(dssdev);
512 if (r) 495 if (r)
513 return r; 496 return r;
514 497
@@ -537,8 +520,8 @@ static int dss_resume_device(struct device *dev, void *data)
537 int r; 520 int r;
538 struct omap_dss_device *dssdev = to_dss_device(dev); 521 struct omap_dss_device *dssdev = to_dss_device(dev);
539 522
540 if (dssdev->activate_after_resume && dssdev->resume) { 523 if (dssdev->activate_after_resume && dssdev->driver->resume) {
541 r = dssdev->resume(dssdev); 524 r = dssdev->driver->resume(dssdev);
542 if (r) 525 if (r)
543 return r; 526 return r;
544 } 527 }
@@ -558,7 +541,7 @@ int dss_resume_all_devices(void)
558static int dss_disable_device(struct device *dev, void *data) 541static int dss_disable_device(struct device *dev, void *data)
559{ 542{
560 struct omap_dss_device *dssdev = to_dss_device(dev); 543 struct omap_dss_device *dssdev = to_dss_device(dev);
561 dssdev->disable(dssdev); 544 dssdev->driver->disable(dssdev);
562 return 0; 545 return 0;
563} 546}
564 547
@@ -591,10 +574,6 @@ struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
591 574
592 int match(struct device *dev, void *data) 575 int match(struct device *dev, void *data)
593 { 576 {
594 /* skip panels connected to controllers */
595 if (to_dss_device(dev)->panel.ctrl)
596 return 0;
597
598 return 1; 577 return 1;
599 } 578 }
600 579
@@ -626,45 +605,21 @@ EXPORT_SYMBOL(omap_dss_find_device);
626 605
627int omap_dss_start_device(struct omap_dss_device *dssdev) 606int omap_dss_start_device(struct omap_dss_device *dssdev)
628{ 607{
629 int r;
630
631 if (!dssdev->driver) { 608 if (!dssdev->driver) {
632 DSSDBG("no driver\n"); 609 DSSDBG("no driver\n");
633 r = -ENODEV; 610 return -ENODEV;
634 goto err0;
635 }
636
637 if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
638 DSSDBG("no panel driver\n");
639 r = -ENODEV;
640 goto err0;
641 } 611 }
642 612
643 if (!try_module_get(dssdev->dev.driver->owner)) { 613 if (!try_module_get(dssdev->dev.driver->owner)) {
644 r = -ENODEV; 614 return -ENODEV;
645 goto err0;
646 }
647
648 if (dssdev->ctrl.panel) {
649 if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
650 r = -ENODEV;
651 goto err1;
652 }
653 } 615 }
654 616
655 return 0; 617 return 0;
656err1:
657 module_put(dssdev->dev.driver->owner);
658err0:
659 return r;
660} 618}
661EXPORT_SYMBOL(omap_dss_start_device); 619EXPORT_SYMBOL(omap_dss_start_device);
662 620
663void omap_dss_stop_device(struct omap_dss_device *dssdev) 621void omap_dss_stop_device(struct omap_dss_device *dssdev)
664{ 622{
665 if (dssdev->ctrl.panel)
666 module_put(dssdev->ctrl.panel->dev.driver->owner);
667
668 module_put(dssdev->dev.driver->owner); 623 module_put(dssdev->dev.driver->owner);
669} 624}
670EXPORT_SYMBOL(omap_dss_stop_device); 625EXPORT_SYMBOL(omap_dss_stop_device);
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 2d71031baa25..960e977a8bf0 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>
@@ -33,7 +36,7 @@
33#include "dss.h" 36#include "dss.h"
34 37
35static struct { 38static struct {
36 int update_enabled; 39 struct regulator *vdds_dsi_reg;
37} dpi; 40} dpi;
38 41
39#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
@@ -53,7 +56,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
53 if (r) 56 if (r)
54 return r; 57 return r;
55 58
56 dss_select_clk_source(0, 1); 59 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
57 60
58 r = dispc_set_clock_div(&dispc_cinfo); 61 r = dispc_set_clock_div(&dispc_cinfo);
59 if (r) 62 if (r)
@@ -150,7 +153,7 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
150 return 0; 153 return 0;
151} 154}
152 155
153static int dpi_display_enable(struct omap_dss_device *dssdev) 156int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
154{ 157{
155 int r; 158 int r;
156 159
@@ -160,10 +163,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
160 goto err0; 163 goto err0;
161 } 164 }
162 165
163 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 166 if (cpu_is_omap34xx()) {
164 DSSERR("display already enabled\n"); 167 r = regulator_enable(dpi.vdds_dsi_reg);
165 r = -EINVAL; 168 if (r)
166 goto err1; 169 goto err1;
167 } 170 }
168 171
169 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 172 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -184,18 +187,10 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
184 187
185 mdelay(2); 188 mdelay(2);
186 189
187 dispc_enable_lcd_out(1); 190 dssdev->manager->enable(dssdev->manager);
188
189 r = dssdev->driver->enable(dssdev);
190 if (r)
191 goto err5;
192
193 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
194 191
195 return 0; 192 return 0;
196 193
197err5:
198 dispc_enable_lcd_out(0);
199err4: 194err4:
200#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 195#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
201 dsi_pll_uninit(); 196 dsi_pll_uninit();
@@ -204,78 +199,35 @@ err3:
204#endif 199#endif
205err2: 200err2:
206 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 201 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
202 if (cpu_is_omap34xx())
203 regulator_disable(dpi.vdds_dsi_reg);
207err1: 204err1:
208 omap_dss_stop_device(dssdev); 205 omap_dss_stop_device(dssdev);
209err0: 206err0:
210 return r; 207 return r;
211} 208}
209EXPORT_SYMBOL(omapdss_dpi_display_enable);
212 210
213static int dpi_display_resume(struct omap_dss_device *dssdev); 211void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
214
215static void dpi_display_disable(struct omap_dss_device *dssdev)
216{ 212{
217 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) 213 dssdev->manager->disable(dssdev->manager);
218 return;
219
220 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
221 dpi_display_resume(dssdev);
222
223 dssdev->driver->disable(dssdev);
224
225 dispc_enable_lcd_out(0);
226 214
227#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 215#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
228 dss_select_clk_source(0, 0); 216 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
229 dsi_pll_uninit(); 217 dsi_pll_uninit();
230 dss_clk_disable(DSS_CLK_FCK2); 218 dss_clk_disable(DSS_CLK_FCK2);
231#endif 219#endif
232 220
233 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 221 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
234 222
235 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 223 if (cpu_is_omap34xx())
224 regulator_disable(dpi.vdds_dsi_reg);
236 225
237 omap_dss_stop_device(dssdev); 226 omap_dss_stop_device(dssdev);
238} 227}
228EXPORT_SYMBOL(omapdss_dpi_display_disable);
239 229
240static int dpi_display_suspend(struct omap_dss_device *dssdev) 230void dpi_set_timings(struct omap_dss_device *dssdev,
241{
242 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
243 return -EINVAL;
244
245 DSSDBG("dpi_display_suspend\n");
246
247 if (dssdev->driver->suspend)
248 dssdev->driver->suspend(dssdev);
249
250 dispc_enable_lcd_out(0);
251
252 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
253
254 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
255
256 return 0;
257}
258
259static int dpi_display_resume(struct omap_dss_device *dssdev)
260{
261 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
262 return -EINVAL;
263
264 DSSDBG("dpi_display_resume\n");
265
266 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
267
268 dispc_enable_lcd_out(1);
269
270 if (dssdev->driver->resume)
271 dssdev->driver->resume(dssdev);
272
273 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
274
275 return 0;
276}
277
278static void dpi_set_timings(struct omap_dss_device *dssdev,
279 struct omap_video_timings *timings) 231 struct omap_video_timings *timings)
280{ 232{
281 DSSDBG("dpi_set_timings\n"); 233 DSSDBG("dpi_set_timings\n");
@@ -285,8 +237,9 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
285 dispc_go(OMAP_DSS_CHANNEL_LCD); 237 dispc_go(OMAP_DSS_CHANNEL_LCD);
286 } 238 }
287} 239}
240EXPORT_SYMBOL(dpi_set_timings);
288 241
289static int dpi_check_timings(struct omap_dss_device *dssdev, 242int dpi_check_timings(struct omap_dss_device *dssdev,
290 struct omap_video_timings *timings) 243 struct omap_video_timings *timings)
291{ 244{
292 bool is_tft; 245 bool is_tft;
@@ -340,56 +293,25 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
340 293
341 return 0; 294 return 0;
342} 295}
343 296EXPORT_SYMBOL(dpi_check_timings);
344static void dpi_get_timings(struct omap_dss_device *dssdev,
345 struct omap_video_timings *timings)
346{
347 *timings = dssdev->panel.timings;
348}
349
350static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
351 enum omap_dss_update_mode mode)
352{
353 if (mode == OMAP_DSS_UPDATE_MANUAL)
354 return -EINVAL;
355
356 if (mode == OMAP_DSS_UPDATE_DISABLED) {
357 dispc_enable_lcd_out(0);
358 dpi.update_enabled = 0;
359 } else {
360 dispc_enable_lcd_out(1);
361 dpi.update_enabled = 1;
362 }
363
364 return 0;
365}
366
367static enum omap_dss_update_mode dpi_display_get_update_mode(
368 struct omap_dss_device *dssdev)
369{
370 return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
371 OMAP_DSS_UPDATE_DISABLED;
372}
373 297
374int dpi_init_display(struct omap_dss_device *dssdev) 298int dpi_init_display(struct omap_dss_device *dssdev)
375{ 299{
376 DSSDBG("init_display\n"); 300 DSSDBG("init_display\n");
377 301
378 dssdev->enable = dpi_display_enable;
379 dssdev->disable = dpi_display_disable;
380 dssdev->suspend = dpi_display_suspend;
381 dssdev->resume = dpi_display_resume;
382 dssdev->set_timings = dpi_set_timings;
383 dssdev->check_timings = dpi_check_timings;
384 dssdev->get_timings = dpi_get_timings;
385 dssdev->set_update_mode = dpi_display_set_update_mode;
386 dssdev->get_update_mode = dpi_display_get_update_mode;
387
388 return 0; 302 return 0;
389} 303}
390 304
391int dpi_init(void) 305int dpi_init(struct platform_device *pdev)
392{ 306{
307 if (cpu_is_omap34xx()) {
308 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
309 if (IS_ERR(dpi.vdds_dsi_reg)) {
310 DSSERR("can't get VDDS_DSI regulator\n");
311 return PTR_ERR(dpi.vdds_dsi_reg);
312 }
313 }
314
393 return 0; 315 return 0;
394} 316}
395 317
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6122178f5f85..3af207b2bde3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -27,11 +27,12 @@
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/semaphore.h>
30#include <linux/seq_file.h> 31#include <linux/seq_file.h>
31#include <linux/platform_device.h> 32#include <linux/platform_device.h>
32#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
33#include <linux/kthread.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h>
35 36
36#include <plat/display.h> 37#include <plat/display.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
@@ -199,7 +200,6 @@ enum dsi_vc_mode {
199}; 200};
200 201
201struct dsi_update_region { 202struct dsi_update_region {
202 bool dirty;
203 u16 x, y, w, h; 203 u16 x, y, w, h;
204 struct omap_dss_device *device; 204 struct omap_dss_device *device;
205}; 205};
@@ -224,29 +224,25 @@ static struct
224 enum dsi_vc_mode mode; 224 enum dsi_vc_mode mode;
225 struct omap_dss_device *dssdev; 225 struct omap_dss_device *dssdev;
226 enum fifo_size fifo_size; 226 enum fifo_size fifo_size;
227 int dest_per; /* destination peripheral 0-3 */
228 } vc[4]; 227 } vc[4];
229 228
230 struct mutex lock; 229 struct mutex lock;
231 struct mutex bus_lock; 230 struct semaphore bus_lock;
232 231
233 unsigned pll_locked; 232 unsigned pll_locked;
234 233
235 struct completion bta_completion; 234 struct completion bta_completion;
236 235
237 struct task_struct *thread; 236 int update_channel;
238 wait_queue_head_t waitqueue;
239
240 spinlock_t update_lock;
241 bool framedone_received;
242 struct dsi_update_region update_region; 237 struct dsi_update_region update_region;
243 struct dsi_update_region active_update_region;
244 struct completion update_completion;
245 238
246 enum omap_dss_update_mode user_update_mode;
247 enum omap_dss_update_mode update_mode;
248 bool te_enabled; 239 bool te_enabled;
249 bool use_ext_te; 240
241 struct work_struct framedone_work;
242 void (*framedone_callback)(int, void *);
243 void *framedone_data;
244
245 struct delayed_work framedone_timeout_work;
250 246
251#ifdef DSI_CATCH_MISSING_TE 247#ifdef DSI_CATCH_MISSING_TE
252 struct timer_list te_timer; 248 struct timer_list te_timer;
@@ -261,8 +257,6 @@ static struct
261#ifdef DEBUG 257#ifdef DEBUG
262 ktime_t perf_setup_time; 258 ktime_t perf_setup_time;
263 ktime_t perf_start_time; 259 ktime_t perf_start_time;
264 ktime_t perf_start_time_auto;
265 int perf_measure_frames;
266#endif 260#endif
267 int debug_read; 261 int debug_read;
268 int debug_write; 262 int debug_write;
@@ -299,16 +293,21 @@ void dsi_restore_context(void)
299 293
300void dsi_bus_lock(void) 294void dsi_bus_lock(void)
301{ 295{
302 mutex_lock(&dsi.bus_lock); 296 down(&dsi.bus_lock);
303} 297}
304EXPORT_SYMBOL(dsi_bus_lock); 298EXPORT_SYMBOL(dsi_bus_lock);
305 299
306void dsi_bus_unlock(void) 300void dsi_bus_unlock(void)
307{ 301{
308 mutex_unlock(&dsi.bus_lock); 302 up(&dsi.bus_lock);
309} 303}
310EXPORT_SYMBOL(dsi_bus_unlock); 304EXPORT_SYMBOL(dsi_bus_unlock);
311 305
306static bool dsi_bus_is_locked(void)
307{
308 return dsi.bus_lock.count == 0;
309}
310
312static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 311static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
313 int value) 312 int value)
314{ 313{
@@ -333,12 +332,6 @@ static void dsi_perf_mark_start(void)
333 dsi.perf_start_time = ktime_get(); 332 dsi.perf_start_time = ktime_get();
334} 333}
335 334
336static void dsi_perf_mark_start_auto(void)
337{
338 dsi.perf_measure_frames = 0;
339 dsi.perf_start_time_auto = ktime_get();
340}
341
342static void dsi_perf_show(const char *name) 335static void dsi_perf_show(const char *name)
343{ 336{
344 ktime_t t, setup_time, trans_time; 337 ktime_t t, setup_time, trans_time;
@@ -348,9 +341,6 @@ static void dsi_perf_show(const char *name)
348 if (!dsi_perf) 341 if (!dsi_perf)
349 return; 342 return;
350 343
351 if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
352 return;
353
354 t = ktime_get(); 344 t = ktime_get();
355 345
356 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); 346 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
@@ -365,76 +355,23 @@ static void dsi_perf_show(const char *name)
365 355
366 total_us = setup_us + trans_us; 356 total_us = setup_us + trans_us;
367 357
368 total_bytes = dsi.active_update_region.w * 358 total_bytes = dsi.update_region.w *
369 dsi.active_update_region.h * 359 dsi.update_region.h *
370 dsi.active_update_region.device->ctrl.pixel_size / 8; 360 dsi.update_region.device->ctrl.pixel_size / 8;
371
372 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
373 static u32 s_total_trans_us, s_total_setup_us;
374 static u32 s_min_trans_us = 0xffffffff, s_min_setup_us;
375 static u32 s_max_trans_us, s_max_setup_us;
376 const int numframes = 100;
377 ktime_t total_time_auto;
378 u32 total_time_auto_us;
379
380 dsi.perf_measure_frames++;
381
382 if (setup_us < s_min_setup_us)
383 s_min_setup_us = setup_us;
384 361
385 if (setup_us > s_max_setup_us) 362 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
386 s_max_setup_us = setup_us; 363 "%u bytes, %u kbytes/sec\n",
387 364 name,
388 s_total_setup_us += setup_us; 365 setup_us,
389 366 trans_us,
390 if (trans_us < s_min_trans_us) 367 total_us,
391 s_min_trans_us = trans_us; 368 1000*1000 / total_us,
392 369 total_bytes,
393 if (trans_us > s_max_trans_us) 370 total_bytes * 1000 / total_us);
394 s_max_trans_us = trans_us;
395
396 s_total_trans_us += trans_us;
397
398 if (dsi.perf_measure_frames < numframes)
399 return;
400
401 total_time_auto = ktime_sub(t, dsi.perf_start_time_auto);
402 total_time_auto_us = (u32)ktime_to_us(total_time_auto);
403
404 printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, "
405 "trans %u/%u/%u\n",
406 name,
407 1000 * 1000 * numframes / total_time_auto_us,
408 s_min_setup_us,
409 s_max_setup_us,
410 s_total_setup_us / numframes,
411 s_min_trans_us,
412 s_max_trans_us,
413 s_total_trans_us / numframes);
414
415 s_total_setup_us = 0;
416 s_min_setup_us = 0xffffffff;
417 s_max_setup_us = 0;
418 s_total_trans_us = 0;
419 s_min_trans_us = 0xffffffff;
420 s_max_trans_us = 0;
421 dsi_perf_mark_start_auto();
422 } else {
423 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
424 "%u bytes, %u kbytes/sec\n",
425 name,
426 setup_us,
427 trans_us,
428 total_us,
429 1000*1000 / total_us,
430 total_bytes,
431 total_bytes * 1000 / total_us);
432 }
433} 371}
434#else 372#else
435#define dsi_perf_mark_setup() 373#define dsi_perf_mark_setup()
436#define dsi_perf_mark_start() 374#define dsi_perf_mark_start()
437#define dsi_perf_mark_start_auto()
438#define dsi_perf_show(x) 375#define dsi_perf_show(x)
439#endif 376#endif
440 377
@@ -774,7 +711,7 @@ static unsigned long dsi_fclk_rate(void)
774{ 711{
775 unsigned long r; 712 unsigned long r;
776 713
777 if (dss_get_dsi_clk_source() == 0) { 714 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) {
778 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 715 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
779 r = dss_clk_get_rate(DSS_CLK_FCK1); 716 r = dss_clk_get_rate(DSS_CLK_FCK1);
780 } else { 717 } else {
@@ -1227,17 +1164,19 @@ void dsi_dump_clocks(struct seq_file *s)
1227 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1164 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n",
1228 cinfo->dsi1_pll_fclk, 1165 cinfo->dsi1_pll_fclk,
1229 cinfo->regm3, 1166 cinfo->regm3,
1230 dss_get_dispc_clk_source() == 0 ? "off" : "on"); 1167 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1168 "off" : "on");
1231 1169
1232 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1170 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n",
1233 cinfo->dsi2_pll_fclk, 1171 cinfo->dsi2_pll_fclk,
1234 cinfo->regm4, 1172 cinfo->regm4,
1235 dss_get_dsi_clk_source() == 0 ? "off" : "on"); 1173 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1174 "off" : "on");
1236 1175
1237 seq_printf(s, "- DSI -\n"); 1176 seq_printf(s, "- DSI -\n");
1238 1177
1239 seq_printf(s, "dsi fclk source = %s\n", 1178 seq_printf(s, "dsi fclk source = %s\n",
1240 dss_get_dsi_clk_source() == 0 ? 1179 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ?
1241 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1180 "dss1_alwon_fclk" : "dsi2_pll_fclk");
1242 1181
1243 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1182 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate());
@@ -1756,29 +1695,10 @@ static int dsi_force_tx_stop_mode_io(void)
1756 return 0; 1695 return 0;
1757} 1696}
1758 1697
1759static void dsi_vc_print_status(int channel)
1760{
1761 u32 r;
1762
1763 r = dsi_read_reg(DSI_VC_CTRL(channel));
1764 DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, "
1765 "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ",
1766 channel,
1767 FLD_GET(r, 5, 5),
1768 FLD_GET(r, 6, 6),
1769 FLD_GET(r, 15, 15),
1770 FLD_GET(r, 16, 16),
1771 FLD_GET(r, 20, 20));
1772
1773 r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS);
1774 DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff);
1775}
1776
1777static int dsi_vc_enable(int channel, bool enable) 1698static int dsi_vc_enable(int channel, bool enable)
1778{ 1699{
1779 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 1700 DSSDBG("dsi_vc_enable channel %d, enable %d\n",
1780 DSSDBG("dsi_vc_enable channel %d, enable %d\n", 1701 channel, enable);
1781 channel, enable);
1782 1702
1783 enable = enable ? 1 : 0; 1703 enable = enable ? 1 : 0;
1784 1704
@@ -1859,10 +1779,12 @@ static void dsi_vc_config_vp(int channel)
1859} 1779}
1860 1780
1861 1781
1862static void dsi_vc_enable_hs(int channel, bool enable) 1782void omapdss_dsi_vc_enable_hs(int channel, bool enable)
1863{ 1783{
1864 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); 1784 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
1865 1785
1786 WARN_ON(!dsi_bus_is_locked());
1787
1866 dsi_vc_enable(channel, 0); 1788 dsi_vc_enable(channel, 0);
1867 dsi_if_enable(0); 1789 dsi_if_enable(0);
1868 1790
@@ -1873,6 +1795,7 @@ static void dsi_vc_enable_hs(int channel, bool enable)
1873 1795
1874 dsi_force_tx_stop_mode_io(); 1796 dsi_force_tx_stop_mode_io();
1875} 1797}
1798EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
1876 1799
1877static void dsi_vc_flush_long_data(int channel) 1800static void dsi_vc_flush_long_data(int channel)
1878{ 1801{
@@ -1955,11 +1878,10 @@ static u16 dsi_vc_flush_receive_data(int channel)
1955 1878
1956static int dsi_vc_send_bta(int channel) 1879static int dsi_vc_send_bta(int channel)
1957{ 1880{
1958 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO && 1881 if (dsi.debug_write || dsi.debug_read)
1959 (dsi.debug_write || dsi.debug_read))
1960 DSSDBG("dsi_vc_send_bta %d\n", channel); 1882 DSSDBG("dsi_vc_send_bta %d\n", channel);
1961 1883
1962 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 1884 WARN_ON(!dsi_bus_is_locked());
1963 1885
1964 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 1886 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */
1965 DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); 1887 DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
@@ -2010,10 +1932,9 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type,
2010 u32 val; 1932 u32 val;
2011 u8 data_id; 1933 u8 data_id;
2012 1934
2013 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 1935 WARN_ON(!dsi_bus_is_locked());
2014 1936
2015 /*data_id = data_type | channel << 6; */ 1937 data_id = data_type | channel << 6;
2016 data_id = data_type | dsi.vc[channel].dest_per << 6;
2017 1938
2018 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 1939 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
2019 FLD_VAL(ecc, 31, 24); 1940 FLD_VAL(ecc, 31, 24);
@@ -2056,13 +1977,10 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2056 1977
2057 dsi_vc_write_long_header(channel, data_type, len, ecc); 1978 dsi_vc_write_long_header(channel, data_type, len, ecc);
2058 1979
2059 /*dsi_vc_print_status(0); */
2060
2061 p = data; 1980 p = data;
2062 for (i = 0; i < len >> 2; i++) { 1981 for (i = 0; i < len >> 2; i++) {
2063 if (dsi.debug_write) 1982 if (dsi.debug_write)
2064 DSSDBG("\tsending full packet %d\n", i); 1983 DSSDBG("\tsending full packet %d\n", i);
2065 /*dsi_vc_print_status(0); */
2066 1984
2067 b1 = *p++; 1985 b1 = *p++;
2068 b2 = *p++; 1986 b2 = *p++;
@@ -2105,7 +2023,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2105 u32 r; 2023 u32 r;
2106 u8 data_id; 2024 u8 data_id;
2107 2025
2108 WARN_ON(!mutex_is_locked(&dsi.bus_lock)); 2026 WARN_ON(!dsi_bus_is_locked());
2109 2027
2110 if (dsi.debug_write) 2028 if (dsi.debug_write)
2111 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", 2029 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
@@ -2119,7 +2037,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
2119 return -EINVAL; 2037 return -EINVAL;
2120 } 2038 }
2121 2039
2122 data_id = data_type | dsi.vc[channel].dest_per << 6; 2040 data_id = data_type | channel << 6;
2123 2041
2124 r = (data_id << 0) | (data << 8) | (ecc << 24); 2042 r = (data_id << 0) | (data << 8) | (ecc << 24);
2125 2043
@@ -2163,14 +2081,35 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len)
2163 2081
2164 r = dsi_vc_dcs_write_nosync(channel, data, len); 2082 r = dsi_vc_dcs_write_nosync(channel, data, len);
2165 if (r) 2083 if (r)
2166 return r; 2084 goto err;
2167 2085
2168 r = dsi_vc_send_bta_sync(channel); 2086 r = dsi_vc_send_bta_sync(channel);
2087 if (r)
2088 goto err;
2169 2089
2090 return 0;
2091err:
2092 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
2093 channel, data[0], len);
2170 return r; 2094 return r;
2171} 2095}
2172EXPORT_SYMBOL(dsi_vc_dcs_write); 2096EXPORT_SYMBOL(dsi_vc_dcs_write);
2173 2097
2098int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd)
2099{
2100 return dsi_vc_dcs_write(channel, &dcs_cmd, 1);
2101}
2102EXPORT_SYMBOL(dsi_vc_dcs_write_0);
2103
2104int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param)
2105{
2106 u8 buf[2];
2107 buf[0] = dcs_cmd;
2108 buf[1] = param;
2109 return dsi_vc_dcs_write(channel, buf, 2);
2110}
2111EXPORT_SYMBOL(dsi_vc_dcs_write_1);
2112
2174int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) 2113int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2175{ 2114{
2176 u32 val; 2115 u32 val;
@@ -2182,16 +2121,17 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2182 2121
2183 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); 2122 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
2184 if (r) 2123 if (r)
2185 return r; 2124 goto err;
2186 2125
2187 r = dsi_vc_send_bta_sync(channel); 2126 r = dsi_vc_send_bta_sync(channel);
2188 if (r) 2127 if (r)
2189 return r; 2128 goto err;
2190 2129
2191 /* RX_FIFO_NOT_EMPTY */ 2130 /* RX_FIFO_NOT_EMPTY */
2192 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { 2131 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) {
2193 DSSERR("RX fifo empty when trying to read.\n"); 2132 DSSERR("RX fifo empty when trying to read.\n");
2194 return -EIO; 2133 r = -EIO;
2134 goto err;
2195 } 2135 }
2196 2136
2197 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2137 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
@@ -2201,15 +2141,18 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2201 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 2141 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
2202 u16 err = FLD_GET(val, 23, 8); 2142 u16 err = FLD_GET(val, 23, 8);
2203 dsi_show_rx_ack_with_err(err); 2143 dsi_show_rx_ack_with_err(err);
2204 return -EIO; 2144 r = -EIO;
2145 goto err;
2205 2146
2206 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 2147 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
2207 u8 data = FLD_GET(val, 15, 8); 2148 u8 data = FLD_GET(val, 15, 8);
2208 if (dsi.debug_read) 2149 if (dsi.debug_read)
2209 DSSDBG("\tDCS short response, 1 byte: %02x\n", data); 2150 DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
2210 2151
2211 if (buflen < 1) 2152 if (buflen < 1) {
2212 return -EIO; 2153 r = -EIO;
2154 goto err;
2155 }
2213 2156
2214 buf[0] = data; 2157 buf[0] = data;
2215 2158
@@ -2219,8 +2162,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2219 if (dsi.debug_read) 2162 if (dsi.debug_read)
2220 DSSDBG("\tDCS short response, 2 byte: %04x\n", data); 2163 DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
2221 2164
2222 if (buflen < 2) 2165 if (buflen < 2) {
2223 return -EIO; 2166 r = -EIO;
2167 goto err;
2168 }
2224 2169
2225 buf[0] = data & 0xff; 2170 buf[0] = data & 0xff;
2226 buf[1] = (data >> 8) & 0xff; 2171 buf[1] = (data >> 8) & 0xff;
@@ -2232,8 +2177,10 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2232 if (dsi.debug_read) 2177 if (dsi.debug_read)
2233 DSSDBG("\tDCS long response, len %d\n", len); 2178 DSSDBG("\tDCS long response, len %d\n", len);
2234 2179
2235 if (len > buflen) 2180 if (len > buflen) {
2236 return -EIO; 2181 r = -EIO;
2182 goto err;
2183 }
2237 2184
2238 /* two byte checksum ends the packet, not included in len */ 2185 /* two byte checksum ends the packet, not included in len */
2239 for (w = 0; w < len + 2;) { 2186 for (w = 0; w < len + 2;) {
@@ -2255,14 +2202,52 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2255 } 2202 }
2256 2203
2257 return len; 2204 return len;
2258
2259 } else { 2205 } else {
2260 DSSERR("\tunknown datatype 0x%02x\n", dt); 2206 DSSERR("\tunknown datatype 0x%02x\n", dt);
2261 return -EIO; 2207 r = -EIO;
2208 goto err;
2262 } 2209 }
2210
2211 BUG();
2212err:
2213 DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
2214 channel, dcs_cmd);
2215 return r;
2216
2263} 2217}
2264EXPORT_SYMBOL(dsi_vc_dcs_read); 2218EXPORT_SYMBOL(dsi_vc_dcs_read);
2265 2219
2220int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2221{
2222 int r;
2223
2224 r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1);
2225
2226 if (r < 0)
2227 return r;
2228
2229 if (r != 1)
2230 return -EIO;
2231
2232 return 0;
2233}
2234EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2235
2236int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data)
2237{
2238 int r;
2239
2240 r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2);
2241
2242 if (r < 0)
2243 return r;
2244
2245 if (r != 2)
2246 return -EIO;
2247
2248 return 0;
2249}
2250EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2266 2251
2267int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 2252int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
2268{ 2253{
@@ -2491,15 +2476,15 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2491 u32 r; 2476 u32 r;
2492 int buswidth = 0; 2477 int buswidth = 0;
2493 2478
2494 dsi_config_tx_fifo(DSI_FIFO_SIZE_128, 2479 dsi_config_tx_fifo(DSI_FIFO_SIZE_32,
2495 DSI_FIFO_SIZE_0, 2480 DSI_FIFO_SIZE_32,
2496 DSI_FIFO_SIZE_0, 2481 DSI_FIFO_SIZE_32,
2497 DSI_FIFO_SIZE_0); 2482 DSI_FIFO_SIZE_32);
2498 2483
2499 dsi_config_rx_fifo(DSI_FIFO_SIZE_128, 2484 dsi_config_rx_fifo(DSI_FIFO_SIZE_32,
2500 DSI_FIFO_SIZE_0, 2485 DSI_FIFO_SIZE_32,
2501 DSI_FIFO_SIZE_0, 2486 DSI_FIFO_SIZE_32,
2502 DSI_FIFO_SIZE_0); 2487 DSI_FIFO_SIZE_32);
2503 2488
2504 /* XXX what values for the timeouts? */ 2489 /* XXX what values for the timeouts? */
2505 dsi_set_stop_state_counter(1000); 2490 dsi_set_stop_state_counter(1000);
@@ -2537,12 +2522,9 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2537 dsi_write_reg(DSI_CTRL, r); 2522 dsi_write_reg(DSI_CTRL, r);
2538 2523
2539 dsi_vc_initial_config(0); 2524 dsi_vc_initial_config(0);
2540 2525 dsi_vc_initial_config(1);
2541 /* set all vc targets to peripheral 0 */ 2526 dsi_vc_initial_config(2);
2542 dsi.vc[0].dest_per = 0; 2527 dsi_vc_initial_config(3);
2543 dsi.vc[1].dest_per = 0;
2544 dsi.vc[2].dest_per = 0;
2545 dsi.vc[3].dest_per = 0;
2546 2528
2547 return 0; 2529 return 0;
2548} 2530}
@@ -2777,18 +2759,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2777 unsigned packet_payload; 2759 unsigned packet_payload;
2778 unsigned packet_len; 2760 unsigned packet_len;
2779 u32 l; 2761 u32 l;
2780 bool use_te_trigger; 2762 const unsigned channel = dsi.update_channel;
2781 const unsigned channel = 0;
2782 /* line buffer is 1024 x 24bits */ 2763 /* line buffer is 1024 x 24bits */
2783 /* XXX: for some reason using full buffer size causes considerable TX 2764 /* XXX: for some reason using full buffer size causes considerable TX
2784 * slowdown with update sizes that fill the whole buffer */ 2765 * slowdown with update sizes that fill the whole buffer */
2785 const unsigned line_buf_size = 1023 * 3; 2766 const unsigned line_buf_size = 1023 * 3;
2786 2767
2787 use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; 2768 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2769 x, y, w, h);
2788 2770
2789 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 2771 dsi_vc_config_vp(channel);
2790 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2791 x, y, w, h);
2792 2772
2793 bytespp = dssdev->ctrl.pixel_size / 8; 2773 bytespp = dssdev->ctrl.pixel_size / 8;
2794 bytespl = w * bytespp; 2774 bytespl = w * bytespp;
@@ -2808,15 +2788,12 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2808 if (bytespf % packet_payload) 2788 if (bytespf % packet_payload)
2809 total_len += (bytespf % packet_payload) + 1; 2789 total_len += (bytespf % packet_payload) + 1;
2810 2790
2811 if (0)
2812 dsi_vc_print_status(1);
2813
2814 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ 2791 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
2815 dsi_write_reg(DSI_VC_TE(channel), l); 2792 dsi_write_reg(DSI_VC_TE(channel), l);
2816 2793
2817 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); 2794 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
2818 2795
2819 if (use_te_trigger) 2796 if (dsi.te_enabled)
2820 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ 2797 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
2821 else 2798 else
2822 l = FLD_MOD(l, 1, 31, 31); /* TE_START */ 2799 l = FLD_MOD(l, 1, 31, 31); /* TE_START */
@@ -2830,9 +2807,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2830 */ 2807 */
2831 dispc_disable_sidle(); 2808 dispc_disable_sidle();
2832 2809
2810 dsi_perf_mark_start();
2811
2812 schedule_delayed_work(&dsi.framedone_timeout_work,
2813 msecs_to_jiffies(250));
2814
2833 dss_start_update(dssdev); 2815 dss_start_update(dssdev);
2834 2816
2835 if (use_te_trigger) { 2817 if (dsi.te_enabled) {
2836 /* disable LP_RX_TO, so that we can receive TE. Time to wait 2818 /* disable LP_RX_TO, so that we can receive TE. Time to wait
2837 * for TE is longer than the timer allows */ 2819 * for TE is longer than the timer allows */
2838 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ 2820 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
@@ -2852,110 +2834,64 @@ static void dsi_te_timeout(unsigned long arg)
2852} 2834}
2853#endif 2835#endif
2854 2836
2855static void dsi_framedone_irq_callback(void *data, u32 mask) 2837static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2856{ 2838{
2857 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 2839 int r;
2858 * turns itself off. However, DSI still has the pixels in its buffers, 2840 const int channel = dsi.update_channel;
2859 * and is sending the data. 2841
2860 */ 2842 DSSERR("Framedone not received for 250ms!\n");
2861 2843
2862 /* SIDLEMODE back to smart-idle */ 2844 /* SIDLEMODE back to smart-idle */
2863 dispc_enable_sidle(); 2845 dispc_enable_sidle();
2864 2846
2865 dsi.framedone_received = true; 2847 if (dsi.te_enabled) {
2866 wake_up(&dsi.waitqueue); 2848 /* enable LP_RX_TO again after the TE */
2867} 2849 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2868
2869static void dsi_set_update_region(struct omap_dss_device *dssdev,
2870 u16 x, u16 y, u16 w, u16 h)
2871{
2872 spin_lock(&dsi.update_lock);
2873 if (dsi.update_region.dirty) {
2874 dsi.update_region.x = min(x, dsi.update_region.x);
2875 dsi.update_region.y = min(y, dsi.update_region.y);
2876 dsi.update_region.w = max(w, dsi.update_region.w);
2877 dsi.update_region.h = max(h, dsi.update_region.h);
2878 } else {
2879 dsi.update_region.x = x;
2880 dsi.update_region.y = y;
2881 dsi.update_region.w = w;
2882 dsi.update_region.h = h;
2883 } 2850 }
2884 2851
2885 dsi.update_region.device = dssdev; 2852 /* Send BTA after the frame. We need this for the TE to work, as TE
2886 dsi.update_region.dirty = true; 2853 * trigger is only sent for BTAs without preceding packet. Thus we need
2887 2854 * to BTA after the pixel packets so that next BTA will cause TE
2888 spin_unlock(&dsi.update_lock); 2855 * trigger.
2889 2856 *
2890} 2857 * This is not needed when TE is not in use, but we do it anyway to
2891 2858 * make sure that the transfer has been completed. It would be more
2892static int dsi_set_update_mode(struct omap_dss_device *dssdev, 2859 * optimal, but more complex, to wait only just before starting next
2893 enum omap_dss_update_mode mode) 2860 * transfer. */
2894{ 2861 r = dsi_vc_send_bta_sync(channel);
2895 int r = 0; 2862 if (r)
2896 int i; 2863 DSSERR("BTA after framedone failed\n");
2897
2898 WARN_ON(!mutex_is_locked(&dsi.bus_lock));
2899
2900 if (dsi.update_mode != mode) {
2901 dsi.update_mode = mode;
2902
2903 /* Mark the overlays dirty, and do apply(), so that we get the
2904 * overlays configured properly after update mode change. */
2905 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
2906 struct omap_overlay *ovl;
2907 ovl = omap_dss_get_overlay(i);
2908 if (ovl->manager == dssdev->manager)
2909 ovl->info_dirty = true;
2910 }
2911
2912 r = dssdev->manager->apply(dssdev->manager);
2913
2914 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
2915 mode == OMAP_DSS_UPDATE_AUTO) {
2916 u16 w, h;
2917
2918 DSSDBG("starting auto update\n");
2919
2920 dssdev->get_resolution(dssdev, &w, &h);
2921
2922 dsi_set_update_region(dssdev, 0, 0, w, h);
2923
2924 dsi_perf_mark_start_auto();
2925 2864
2926 wake_up(&dsi.waitqueue); 2865 /* RX_FIFO_NOT_EMPTY */
2927 } 2866 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2867 DSSERR("Received error during frame transfer:\n");
2868 dsi_vc_flush_receive_data(channel);
2928 } 2869 }
2929 2870
2930 return r; 2871 dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data);
2931} 2872}
2932 2873
2933static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) 2874static void dsi_framedone_irq_callback(void *data, u32 mask)
2934{ 2875{
2935 int r = 0; 2876 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
2877 * turns itself off. However, DSI still has the pixels in its buffers,
2878 * and is sending the data.
2879 */
2936 2880
2937 if (dssdev->driver->enable_te) { 2881 /* SIDLEMODE back to smart-idle */
2938 r = dssdev->driver->enable_te(dssdev, enable); 2882 dispc_enable_sidle();
2939 /* XXX for some reason, DSI TE breaks if we don't wait here.
2940 * Panel bug? Needs more studying */
2941 msleep(100);
2942 }
2943 2883
2944 return r; 2884 schedule_work(&dsi.framedone_work);
2945} 2885}
2946 2886
2947static void dsi_handle_framedone(void) 2887static void dsi_handle_framedone(void)
2948{ 2888{
2949 int r; 2889 int r;
2950 const int channel = 0; 2890 const int channel = dsi.update_channel;
2951 bool use_te_trigger;
2952
2953 use_te_trigger = dsi.te_enabled && !dsi.use_ext_te;
2954 2891
2955 if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) 2892 DSSDBG("FRAMEDONE\n");
2956 DSSDBG("FRAMEDONE\n");
2957 2893
2958 if (use_te_trigger) { 2894 if (dsi.te_enabled) {
2959 /* enable LP_RX_TO again after the TE */ 2895 /* enable LP_RX_TO again after the TE */
2960 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 2896 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2961 } 2897 }
@@ -2976,7 +2912,7 @@ static void dsi_handle_framedone(void)
2976 /* RX_FIFO_NOT_EMPTY */ 2912 /* RX_FIFO_NOT_EMPTY */
2977 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2913 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2978 DSSERR("Received error during frame transfer:\n"); 2914 DSSERR("Received error during frame transfer:\n");
2979 dsi_vc_flush_receive_data(0); 2915 dsi_vc_flush_receive_data(channel);
2980 } 2916 }
2981 2917
2982#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC 2918#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
@@ -2984,118 +2920,79 @@ static void dsi_handle_framedone(void)
2984#endif 2920#endif
2985} 2921}
2986 2922
2987static int dsi_update_thread(void *data) 2923static void dsi_framedone_work_callback(struct work_struct *work)
2988{ 2924{
2989 unsigned long timeout; 2925 DSSDBGF();
2990 struct omap_dss_device *device;
2991 u16 x, y, w, h;
2992
2993 while (1) {
2994 bool sched;
2995
2996 wait_event_interruptible(dsi.waitqueue,
2997 dsi.update_mode == OMAP_DSS_UPDATE_AUTO ||
2998 (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
2999 dsi.update_region.dirty == true) ||
3000 kthread_should_stop());
3001
3002 if (kthread_should_stop())
3003 break;
3004
3005 dsi_bus_lock();
3006
3007 if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED ||
3008 kthread_should_stop()) {
3009 dsi_bus_unlock();
3010 break;
3011 }
3012
3013 dsi_perf_mark_setup();
3014
3015 if (dsi.update_region.dirty) {
3016 spin_lock(&dsi.update_lock);
3017 dsi.active_update_region = dsi.update_region;
3018 dsi.update_region.dirty = false;
3019 spin_unlock(&dsi.update_lock);
3020 }
3021 2926
3022 device = dsi.active_update_region.device; 2927 cancel_delayed_work_sync(&dsi.framedone_timeout_work);
3023 x = dsi.active_update_region.x;
3024 y = dsi.active_update_region.y;
3025 w = dsi.active_update_region.w;
3026 h = dsi.active_update_region.h;
3027 2928
3028 if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2929 dsi_handle_framedone();
3029 2930
3030 if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) 2931 dsi_perf_show("DISPC");
3031 dss_setup_partial_planes(device,
3032 &x, &y, &w, &h);
3033 2932
3034 dispc_set_lcd_size(w, h); 2933 dsi.framedone_callback(0, dsi.framedone_data);
3035 } 2934}
3036 2935
3037 if (dsi.active_update_region.dirty) { 2936int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
3038 dsi.active_update_region.dirty = false; 2937 u16 *x, u16 *y, u16 *w, u16 *h)
3039 /* XXX TODO we don't need to send the coords, if they 2938{
3040 * are the same that are already programmed to the 2939 u16 dw, dh;
3041 * panel. That should speed up manual update a bit */
3042 device->driver->setup_update(device, x, y, w, h);
3043 }
3044 2940
3045 dsi_perf_mark_start(); 2941 dssdev->driver->get_resolution(dssdev, &dw, &dh);
3046 2942
3047 if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2943 if (*x > dw || *y > dh)
3048 dsi_vc_config_vp(0); 2944 return -EINVAL;
3049 2945
3050 if (dsi.te_enabled && dsi.use_ext_te) 2946 if (*x + *w > dw)
3051 device->driver->wait_for_te(device); 2947 return -EINVAL;
3052 2948
3053 dsi.framedone_received = false; 2949 if (*y + *h > dh)
2950 return -EINVAL;
3054 2951
3055 dsi_update_screen_dispc(device, x, y, w, h); 2952 if (*w == 1)
2953 return -EINVAL;
3056 2954
3057 /* wait for framedone */ 2955 if (*w == 0 || *h == 0)
3058 timeout = msecs_to_jiffies(1000); 2956 return -EINVAL;
3059 wait_event_timeout(dsi.waitqueue,
3060 dsi.framedone_received == true,
3061 timeout);
3062 2957
3063 if (!dsi.framedone_received) { 2958 dsi_perf_mark_setup();
3064 DSSERR("framedone timeout\n");
3065 DSSERR("failed update %d,%d %dx%d\n",
3066 x, y, w, h);
3067 2959
3068 dispc_enable_sidle(); 2960 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
3069 dispc_enable_lcd_out(0); 2961 dss_setup_partial_planes(dssdev, x, y, w, h);
2962 dispc_set_lcd_size(*w, *h);
2963 }
3070 2964
3071 dsi_reset_tx_fifo(0); 2965 return 0;
3072 } else { 2966}
3073 dsi_handle_framedone(); 2967EXPORT_SYMBOL(omap_dsi_prepare_update);
3074 dsi_perf_show("DISPC");
3075 }
3076 } else {
3077 dsi_update_screen_l4(device, x, y, w, h);
3078 dsi_perf_show("L4");
3079 }
3080 2968
3081 sched = atomic_read(&dsi.bus_lock.count) < 0; 2969int omap_dsi_update(struct omap_dss_device *dssdev,
2970 int channel,
2971 u16 x, u16 y, u16 w, u16 h,
2972 void (*callback)(int, void *), void *data)
2973{
2974 dsi.update_channel = channel;
3082 2975
3083 complete_all(&dsi.update_completion); 2976 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2977 dsi.framedone_callback = callback;
2978 dsi.framedone_data = data;
3084 2979
3085 dsi_bus_unlock(); 2980 dsi.update_region.x = x;
2981 dsi.update_region.y = y;
2982 dsi.update_region.w = w;
2983 dsi.update_region.h = h;
2984 dsi.update_region.device = dssdev;
3086 2985
3087 /* XXX We need to give others chance to get the bus lock. Is 2986 dsi_update_screen_dispc(dssdev, x, y, w, h);
3088 * there a better way for this? */ 2987 } else {
3089 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched) 2988 dsi_update_screen_l4(dssdev, x, y, w, h);
3090 schedule_timeout_interruptible(1); 2989 dsi_perf_show("L4");
2990 callback(0, data);
3091 } 2991 }
3092 2992
3093 DSSDBG("update thread exiting\n");
3094
3095 return 0; 2993 return 0;
3096} 2994}
3097 2995EXPORT_SYMBOL(omap_dsi_update);
3098
3099 2996
3100/* Display funcs */ 2997/* Display funcs */
3101 2998
@@ -3203,7 +3100,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3203 if (r) 3100 if (r)
3204 goto err1; 3101 goto err1;
3205 3102
3206 dss_select_clk_source(true, true); 3103 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
3104 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK);
3207 3105
3208 DSSDBG("PLL OK\n"); 3106 DSSDBG("PLL OK\n");
3209 3107
@@ -3229,25 +3127,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3229 3127
3230 /* enable interface */ 3128 /* enable interface */
3231 dsi_vc_enable(0, 1); 3129 dsi_vc_enable(0, 1);
3130 dsi_vc_enable(1, 1);
3131 dsi_vc_enable(2, 1);
3132 dsi_vc_enable(3, 1);
3232 dsi_if_enable(1); 3133 dsi_if_enable(1);
3233 dsi_force_tx_stop_mode_io(); 3134 dsi_force_tx_stop_mode_io();
3234 3135
3235 if (dssdev->driver->enable) {
3236 r = dssdev->driver->enable(dssdev);
3237 if (r)
3238 goto err4;
3239 }
3240
3241 /* enable high-speed after initial config */
3242 dsi_vc_enable_hs(0, 1);
3243
3244 return 0; 3136 return 0;
3245err4:
3246 dsi_if_enable(0);
3247err3: 3137err3:
3248 dsi_complexio_uninit(); 3138 dsi_complexio_uninit();
3249err2: 3139err2:
3250 dss_select_clk_source(false, false); 3140 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3141 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3251err1: 3142err1:
3252 dsi_pll_uninit(); 3143 dsi_pll_uninit();
3253err0: 3144err0:
@@ -3256,10 +3147,8 @@ err0:
3256 3147
3257static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 3148static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3258{ 3149{
3259 if (dssdev->driver->disable) 3150 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3260 dssdev->driver->disable(dssdev); 3151 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3261
3262 dss_select_clk_source(false, false);
3263 dsi_complexio_uninit(); 3152 dsi_complexio_uninit();
3264 dsi_pll_uninit(); 3153 dsi_pll_uninit();
3265} 3154}
@@ -3280,14 +3169,15 @@ static int dsi_core_init(void)
3280 return 0; 3169 return 0;
3281} 3170}
3282 3171
3283static int dsi_display_enable(struct omap_dss_device *dssdev) 3172int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3284{ 3173{
3285 int r = 0; 3174 int r = 0;
3286 3175
3287 DSSDBG("dsi_display_enable\n"); 3176 DSSDBG("dsi_display_enable\n");
3288 3177
3178 WARN_ON(!dsi_bus_is_locked());
3179
3289 mutex_lock(&dsi.lock); 3180 mutex_lock(&dsi.lock);
3290 dsi_bus_lock();
3291 3181
3292 r = omap_dss_start_device(dssdev); 3182 r = omap_dss_start_device(dssdev);
3293 if (r) { 3183 if (r) {
@@ -3295,100 +3185,47 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
3295 goto err0; 3185 goto err0;
3296 } 3186 }
3297 3187
3298 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
3299 DSSERR("dssdev already enabled\n");
3300 r = -EINVAL;
3301 goto err1;
3302 }
3303
3304 enable_clocks(1); 3188 enable_clocks(1);
3305 dsi_enable_pll_clock(1); 3189 dsi_enable_pll_clock(1);
3306 3190
3307 r = _dsi_reset(); 3191 r = _dsi_reset();
3308 if (r) 3192 if (r)
3309 goto err2; 3193 goto err1;
3310 3194
3311 dsi_core_init(); 3195 dsi_core_init();
3312 3196
3313 r = dsi_display_init_dispc(dssdev); 3197 r = dsi_display_init_dispc(dssdev);
3314 if (r) 3198 if (r)
3315 goto err2; 3199 goto err1;
3316 3200
3317 r = dsi_display_init_dsi(dssdev); 3201 r = dsi_display_init_dsi(dssdev);
3318 if (r) 3202 if (r)
3319 goto err3; 3203 goto err2;
3320
3321 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3322
3323 dsi.use_ext_te = dssdev->phy.dsi.ext_te;
3324 r = dsi_set_te(dssdev, dsi.te_enabled);
3325 if (r)
3326 goto err4;
3327
3328 dsi_set_update_mode(dssdev, dsi.user_update_mode);
3329 3204
3330 dsi_bus_unlock();
3331 mutex_unlock(&dsi.lock); 3205 mutex_unlock(&dsi.lock);
3332 3206
3333 return 0; 3207 return 0;
3334 3208
3335err4:
3336
3337 dsi_display_uninit_dsi(dssdev);
3338err3:
3339 dsi_display_uninit_dispc(dssdev);
3340err2: 3209err2:
3210 dsi_display_uninit_dispc(dssdev);
3211err1:
3341 enable_clocks(0); 3212 enable_clocks(0);
3342 dsi_enable_pll_clock(0); 3213 dsi_enable_pll_clock(0);
3343err1:
3344 omap_dss_stop_device(dssdev); 3214 omap_dss_stop_device(dssdev);
3345err0: 3215err0:
3346 dsi_bus_unlock();
3347 mutex_unlock(&dsi.lock); 3216 mutex_unlock(&dsi.lock);
3348 DSSDBG("dsi_display_enable FAILED\n"); 3217 DSSDBG("dsi_display_enable FAILED\n");
3349 return r; 3218 return r;
3350} 3219}
3220EXPORT_SYMBOL(omapdss_dsi_display_enable);
3351 3221
3352static void dsi_display_disable(struct omap_dss_device *dssdev) 3222void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
3353{ 3223{
3354 DSSDBG("dsi_display_disable\n"); 3224 DSSDBG("dsi_display_disable\n");
3355 3225
3356 mutex_lock(&dsi.lock); 3226 WARN_ON(!dsi_bus_is_locked());
3357 dsi_bus_lock();
3358
3359 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
3360 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
3361 goto end;
3362
3363 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3364 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
3365
3366 dsi_display_uninit_dispc(dssdev);
3367
3368 dsi_display_uninit_dsi(dssdev);
3369
3370 enable_clocks(0);
3371 dsi_enable_pll_clock(0);
3372
3373 omap_dss_stop_device(dssdev);
3374end:
3375 dsi_bus_unlock();
3376 mutex_unlock(&dsi.lock);
3377}
3378
3379static int dsi_display_suspend(struct omap_dss_device *dssdev)
3380{
3381 DSSDBG("dsi_display_suspend\n");
3382 3227
3383 mutex_lock(&dsi.lock); 3228 mutex_lock(&dsi.lock);
3384 dsi_bus_lock();
3385
3386 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
3387 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
3388 goto end;
3389
3390 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3391 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
3392 3229
3393 dsi_display_uninit_dispc(dssdev); 3230 dsi_display_uninit_dispc(dssdev);
3394 3231
@@ -3396,312 +3233,19 @@ static int dsi_display_suspend(struct omap_dss_device *dssdev)
3396 3233
3397 enable_clocks(0); 3234 enable_clocks(0);
3398 dsi_enable_pll_clock(0); 3235 dsi_enable_pll_clock(0);
3399end:
3400 dsi_bus_unlock();
3401 mutex_unlock(&dsi.lock);
3402
3403 return 0;
3404}
3405
3406static int dsi_display_resume(struct omap_dss_device *dssdev)
3407{
3408 int r;
3409
3410 DSSDBG("dsi_display_resume\n");
3411
3412 mutex_lock(&dsi.lock);
3413 dsi_bus_lock();
3414
3415 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
3416 DSSERR("dssdev not suspended\n");
3417 r = -EINVAL;
3418 goto err0;
3419 }
3420
3421 enable_clocks(1);
3422 dsi_enable_pll_clock(1);
3423
3424 r = _dsi_reset();
3425 if (r)
3426 goto err1;
3427
3428 dsi_core_init();
3429
3430 r = dsi_display_init_dispc(dssdev);
3431 if (r)
3432 goto err1;
3433
3434 r = dsi_display_init_dsi(dssdev);
3435 if (r)
3436 goto err2;
3437
3438 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
3439
3440 r = dsi_set_te(dssdev, dsi.te_enabled);
3441 if (r)
3442 goto err2;
3443
3444 dsi_set_update_mode(dssdev, dsi.user_update_mode);
3445
3446 dsi_bus_unlock();
3447 mutex_unlock(&dsi.lock);
3448
3449 return 0;
3450
3451err2:
3452 dsi_display_uninit_dispc(dssdev);
3453err1:
3454 enable_clocks(0);
3455 dsi_enable_pll_clock(0);
3456err0:
3457 dsi_bus_unlock();
3458 mutex_unlock(&dsi.lock);
3459 DSSDBG("dsi_display_resume FAILED\n");
3460 return r;
3461}
3462
3463static int dsi_display_update(struct omap_dss_device *dssdev,
3464 u16 x, u16 y, u16 w, u16 h)
3465{
3466 int r = 0;
3467 u16 dw, dh;
3468
3469 DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
3470 3236
3471 mutex_lock(&dsi.lock); 3237 omap_dss_stop_device(dssdev);
3472
3473 if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL)
3474 goto end;
3475
3476 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3477 goto end;
3478
3479 dssdev->get_resolution(dssdev, &dw, &dh);
3480
3481 if (x > dw || y > dh)
3482 goto end;
3483
3484 if (x + w > dw)
3485 w = dw - x;
3486
3487 if (y + h > dh)
3488 h = dh - y;
3489
3490 if (w == 0 || h == 0)
3491 goto end;
3492
3493 if (w == 1) {
3494 r = -EINVAL;
3495 goto end;
3496 }
3497
3498 dsi_set_update_region(dssdev, x, y, w, h);
3499
3500 wake_up(&dsi.waitqueue);
3501
3502end:
3503 mutex_unlock(&dsi.lock);
3504
3505 return r;
3506}
3507
3508static int dsi_display_sync(struct omap_dss_device *dssdev)
3509{
3510 bool wait;
3511
3512 DSSDBG("dsi_display_sync()\n");
3513
3514 mutex_lock(&dsi.lock);
3515 dsi_bus_lock();
3516
3517 if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL &&
3518 dsi.update_region.dirty) {
3519 INIT_COMPLETION(dsi.update_completion);
3520 wait = true;
3521 } else {
3522 wait = false;
3523 }
3524
3525 dsi_bus_unlock();
3526 mutex_unlock(&dsi.lock);
3527
3528 if (wait)
3529 wait_for_completion_interruptible(&dsi.update_completion);
3530
3531 DSSDBG("dsi_display_sync() done\n");
3532 return 0;
3533}
3534
3535static int dsi_display_set_update_mode(struct omap_dss_device *dssdev,
3536 enum omap_dss_update_mode mode)
3537{
3538 int r = 0;
3539
3540 DSSDBGF("%d", mode);
3541
3542 mutex_lock(&dsi.lock);
3543 dsi_bus_lock();
3544
3545 dsi.user_update_mode = mode;
3546 r = dsi_set_update_mode(dssdev, mode);
3547 3238
3548 dsi_bus_unlock();
3549 mutex_unlock(&dsi.lock); 3239 mutex_unlock(&dsi.lock);
3550
3551 return r;
3552} 3240}
3241EXPORT_SYMBOL(omapdss_dsi_display_disable);
3553 3242
3554static enum omap_dss_update_mode dsi_display_get_update_mode( 3243int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
3555 struct omap_dss_device *dssdev)
3556{ 3244{
3557 return dsi.update_mode;
3558}
3559
3560
3561static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
3562{
3563 int r = 0;
3564
3565 DSSDBGF("%d", enable);
3566
3567 if (!dssdev->driver->enable_te)
3568 return -ENOENT;
3569
3570 dsi_bus_lock();
3571
3572 dsi.te_enabled = enable; 3245 dsi.te_enabled = enable;
3573
3574 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3575 goto end;
3576
3577 r = dsi_set_te(dssdev, enable);
3578end:
3579 dsi_bus_unlock();
3580
3581 return r;
3582}
3583
3584static int dsi_display_get_te(struct omap_dss_device *dssdev)
3585{
3586 return dsi.te_enabled;
3587}
3588
3589static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate)
3590{
3591
3592 DSSDBGF("%d", rotate);
3593
3594 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
3595 return -EINVAL;
3596
3597 dsi_bus_lock();
3598 dssdev->driver->set_rotate(dssdev, rotate);
3599 if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
3600 u16 w, h;
3601 /* the display dimensions may have changed, so set a new
3602 * update region */
3603 dssdev->get_resolution(dssdev, &w, &h);
3604 dsi_set_update_region(dssdev, 0, 0, w, h);
3605 }
3606 dsi_bus_unlock();
3607
3608 return 0; 3246 return 0;
3609} 3247}
3610 3248EXPORT_SYMBOL(omapdss_dsi_enable_te);
3611static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev)
3612{
3613 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
3614 return 0;
3615
3616 return dssdev->driver->get_rotate(dssdev);
3617}
3618
3619static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror)
3620{
3621 DSSDBGF("%d", mirror);
3622
3623 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
3624 return -EINVAL;
3625
3626 dsi_bus_lock();
3627 dssdev->driver->set_mirror(dssdev, mirror);
3628 dsi_bus_unlock();
3629
3630 return 0;
3631}
3632
3633static bool dsi_display_get_mirror(struct omap_dss_device *dssdev)
3634{
3635 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
3636 return 0;
3637
3638 return dssdev->driver->get_mirror(dssdev);
3639}
3640
3641static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num)
3642{
3643 int r;
3644
3645 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3646 return -EIO;
3647
3648 DSSDBGF("%d", test_num);
3649
3650 dsi_bus_lock();
3651
3652 /* run test first in low speed mode */
3653 dsi_vc_enable_hs(0, 0);
3654
3655 if (dssdev->driver->run_test) {
3656 r = dssdev->driver->run_test(dssdev, test_num);
3657 if (r)
3658 goto end;
3659 }
3660
3661 /* then in high speed */
3662 dsi_vc_enable_hs(0, 1);
3663
3664 if (dssdev->driver->run_test) {
3665 r = dssdev->driver->run_test(dssdev, test_num);
3666 if (r)
3667 goto end;
3668 }
3669
3670end:
3671 dsi_vc_enable_hs(0, 1);
3672
3673 dsi_bus_unlock();
3674
3675 return r;
3676}
3677
3678static int dsi_display_memory_read(struct omap_dss_device *dssdev,
3679 void *buf, size_t size,
3680 u16 x, u16 y, u16 w, u16 h)
3681{
3682 int r;
3683
3684 DSSDBGF("");
3685
3686 if (!dssdev->driver->memory_read)
3687 return -EINVAL;
3688
3689 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
3690 return -EIO;
3691
3692 dsi_bus_lock();
3693
3694 r = dssdev->driver->memory_read(dssdev, buf, size,
3695 x, y, w, h);
3696
3697 /* Memory read usually changes the update area. This will
3698 * force the next update to re-set the update area */
3699 dsi.active_update_region.dirty = true;
3700
3701 dsi_bus_unlock();
3702
3703 return r;
3704}
3705 3249
3706void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 3250void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3707 u32 fifo_size, enum omap_burst_size *burst_size, 3251 u32 fifo_size, enum omap_burst_size *burst_size,
@@ -3720,26 +3264,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3720{ 3264{
3721 DSSDBG("DSI init\n"); 3265 DSSDBG("DSI init\n");
3722 3266
3723 dssdev->enable = dsi_display_enable;
3724 dssdev->disable = dsi_display_disable;
3725 dssdev->suspend = dsi_display_suspend;
3726 dssdev->resume = dsi_display_resume;
3727 dssdev->update = dsi_display_update;
3728 dssdev->sync = dsi_display_sync;
3729 dssdev->set_update_mode = dsi_display_set_update_mode;
3730 dssdev->get_update_mode = dsi_display_get_update_mode;
3731 dssdev->enable_te = dsi_display_enable_te;
3732 dssdev->get_te = dsi_display_get_te;
3733
3734 dssdev->get_rotate = dsi_display_get_rotate;
3735 dssdev->set_rotate = dsi_display_set_rotate;
3736
3737 dssdev->get_mirror = dsi_display_get_mirror;
3738 dssdev->set_mirror = dsi_display_set_mirror;
3739
3740 dssdev->run_test = dsi_display_run_test;
3741 dssdev->memory_read = dsi_display_memory_read;
3742
3743 /* XXX these should be figured out dynamically */ 3267 /* XXX these should be figured out dynamically */
3744 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 3268 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3745 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 3269 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
@@ -3754,9 +3278,6 @@ int dsi_init(struct platform_device *pdev)
3754{ 3278{
3755 u32 rev; 3279 u32 rev;
3756 int r; 3280 int r;
3757 struct sched_param param = {
3758 .sched_priority = MAX_USER_RT_PRIO-1
3759 };
3760 3281
3761 spin_lock_init(&dsi.errors_lock); 3282 spin_lock_init(&dsi.errors_lock);
3762 dsi.errors = 0; 3283 dsi.errors = 0;
@@ -3767,31 +3288,19 @@ int dsi_init(struct platform_device *pdev)
3767#endif 3288#endif
3768 3289
3769 init_completion(&dsi.bta_completion); 3290 init_completion(&dsi.bta_completion);
3770 init_completion(&dsi.update_completion);
3771
3772 dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi");
3773 if (IS_ERR(dsi.thread)) {
3774 DSSERR("cannot create kthread\n");
3775 r = PTR_ERR(dsi.thread);
3776 goto err0;
3777 }
3778 sched_setscheduler(dsi.thread, SCHED_FIFO, &param);
3779
3780 init_waitqueue_head(&dsi.waitqueue);
3781 spin_lock_init(&dsi.update_lock);
3782 3291
3783 mutex_init(&dsi.lock); 3292 mutex_init(&dsi.lock);
3784 mutex_init(&dsi.bus_lock); 3293 sema_init(&dsi.bus_lock, 1);
3294
3295 INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback);
3296 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
3297 dsi_framedone_timeout_work_callback);
3785 3298
3786#ifdef DSI_CATCH_MISSING_TE 3299#ifdef DSI_CATCH_MISSING_TE
3787 init_timer(&dsi.te_timer); 3300 init_timer(&dsi.te_timer);
3788 dsi.te_timer.function = dsi_te_timeout; 3301 dsi.te_timer.function = dsi_te_timeout;
3789 dsi.te_timer.data = 0; 3302 dsi.te_timer.data = 0;
3790#endif 3303#endif
3791
3792 dsi.update_mode = OMAP_DSS_UPDATE_DISABLED;
3793 dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED;
3794
3795 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 3304 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
3796 if (!dsi.base) { 3305 if (!dsi.base) {
3797 DSSERR("can't ioremap DSI\n"); 3306 DSSERR("can't ioremap DSI\n");
@@ -3799,7 +3308,7 @@ int dsi_init(struct platform_device *pdev)
3799 goto err1; 3308 goto err1;
3800 } 3309 }
3801 3310
3802 dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); 3311 dsi.vdds_dsi_reg = dss_get_vdds_dsi();
3803 if (IS_ERR(dsi.vdds_dsi_reg)) { 3312 if (IS_ERR(dsi.vdds_dsi_reg)) {
3804 iounmap(dsi.base); 3313 iounmap(dsi.base);
3805 DSSERR("can't get VDDS_DSI regulator\n"); 3314 DSSERR("can't get VDDS_DSI regulator\n");
@@ -3815,23 +3324,15 @@ int dsi_init(struct platform_device *pdev)
3815 3324
3816 enable_clocks(0); 3325 enable_clocks(0);
3817 3326
3818 wake_up_process(dsi.thread);
3819
3820 return 0; 3327 return 0;
3821err2: 3328err2:
3822 iounmap(dsi.base); 3329 iounmap(dsi.base);
3823err1: 3330err1:
3824 kthread_stop(dsi.thread);
3825err0:
3826 return r; 3331 return r;
3827} 3332}
3828 3333
3829void dsi_exit(void) 3334void dsi_exit(void)
3830{ 3335{
3831 kthread_stop(dsi.thread);
3832
3833 regulator_put(dsi.vdds_dsi_reg);
3834
3835 iounmap(dsi.base); 3336 iounmap(dsi.base);
3836 3337
3837 DSSDBG("omap_dsi_exit\n"); 3338 DSSDBG("omap_dsi_exit\n");
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 0a26b7d84d41..8254a4232a53 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -68,6 +68,9 @@ static struct {
68 struct dss_clock_info cache_dss_cinfo; 68 struct dss_clock_info cache_dss_cinfo;
69 struct dispc_clock_info cache_dispc_cinfo; 69 struct dispc_clock_info cache_dispc_cinfo;
70 70
71 enum dss_clk_source dsi_clk_source;
72 enum dss_clk_source dispc_clk_source;
73
71 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 74 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
72} dss; 75} dss;
73 76
@@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s)
247#undef DUMPREG 250#undef DUMPREG
248} 251}
249 252
250void dss_select_clk_source(bool dsi, bool dispc) 253void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
254{
255 int b;
256
257 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK &&
258 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
259
260 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
261
262 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
263
264 dss.dispc_clk_source = clk_src;
265}
266
267void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
251{ 268{
252 u32 r; 269 int b;
253 r = dss_read_reg(DSS_CONTROL); 270
254 r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */ 271 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK &&
255 r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */ 272 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
256 dss_write_reg(DSS_CONTROL, r); 273
274 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
275
276 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
277
278 dss.dsi_clk_source = clk_src;
257} 279}
258 280
259int dss_get_dsi_clk_source(void) 281enum dss_clk_source dss_get_dispc_clk_source(void)
260{ 282{
261 return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1); 283 return dss.dispc_clk_source;
262} 284}
263 285
264int dss_get_dispc_clk_source(void) 286enum dss_clk_source dss_get_dsi_clk_source(void)
265{ 287{
266 return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0); 288 return dss.dsi_clk_source;
267} 289}
268 290
269/* calculate clock rates using dividers in cinfo */ 291/* calculate clock rates using dividers in cinfo */
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 2bcb1245d6c2..24326a5fd292 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -119,6 +119,12 @@ enum dss_clock {
119 DSS_CLK_96M = 1 << 4, 119 DSS_CLK_96M = 1 << 4,
120}; 120};
121 121
122enum dss_clk_source {
123 DSS_SRC_DSI1_PLL_FCLK,
124 DSS_SRC_DSI2_PLL_FCLK,
125 DSS_SRC_DSS1_ALWON_FCLK,
126};
127
122struct dss_clock_info { 128struct dss_clock_info {
123 /* rates that we get with dividers below */ 129 /* rates that we get with dividers below */
124 unsigned long fck; 130 unsigned long fck;
@@ -169,6 +175,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk);
169int dss_need_ctx_restore(void); 175int dss_need_ctx_restore(void);
170void dss_dump_clocks(struct seq_file *s); 176void dss_dump_clocks(struct seq_file *s);
171struct bus_type *dss_get_bus(void); 177struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
172 181
173/* display */ 182/* display */
174int dss_suspend_all_devices(void); 183int dss_suspend_all_devices(void);
@@ -216,9 +225,11 @@ void dss_sdi_init(u8 datapairs);
216int dss_sdi_enable(void); 225int dss_sdi_enable(void);
217void dss_sdi_disable(void); 226void dss_sdi_disable(void);
218 227
219void dss_select_clk_source(bool dsi, bool dispc); 228void dss_select_dispc_clk_source(enum dss_clk_source clk_src);
220int dss_get_dsi_clk_source(void); 229void dss_select_dsi_clk_source(enum dss_clk_source clk_src);
221int dss_get_dispc_clk_source(void); 230enum dss_clk_source dss_get_dispc_clk_source(void);
231enum dss_clk_source dss_get_dsi_clk_source(void);
232
222void dss_set_venc_output(enum omap_dss_venc_type type); 233void dss_set_venc_output(enum omap_dss_venc_type type);
223void dss_set_dac_pwrdn_bgz(bool enable); 234void dss_set_dac_pwrdn_bgz(bool enable);
224 235
@@ -261,7 +272,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
261 u32 *fifo_low, u32 *fifo_high); 272 u32 *fifo_low, u32 *fifo_high);
262 273
263/* DPI */ 274/* DPI */
264int dpi_init(void); 275int dpi_init(struct platform_device *pdev);
265void dpi_exit(void); 276void dpi_exit(void);
266int dpi_init_display(struct omap_dss_device *dssdev); 277int dpi_init_display(struct omap_dss_device *dssdev);
267 278
@@ -313,8 +324,8 @@ int dispc_setup_plane(enum omap_plane plane,
313 324
314bool dispc_go_busy(enum omap_channel channel); 325bool dispc_go_busy(enum omap_channel channel);
315void dispc_go(enum omap_channel channel); 326void dispc_go(enum omap_channel channel);
316void dispc_enable_lcd_out(bool enable); 327void dispc_enable_channel(enum omap_channel channel, bool enable);
317void dispc_enable_digit_out(bool enable); 328bool dispc_is_channel_enabled(enum omap_channel channel);
318int dispc_enable_plane(enum omap_plane plane, bool enable); 329int dispc_enable_plane(enum omap_plane plane, bool enable);
319void dispc_enable_replication(enum omap_plane plane, bool enable); 330void dispc_enable_replication(enum omap_plane plane, bool enable);
320 331
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 27d9c465c851..913142d4cab1 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -501,6 +501,19 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
501 return 0; 501 return 0;
502} 502}
503 503
504static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
505{
506 unsigned long timeout = msecs_to_jiffies(500);
507 u32 irq;
508
509 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
510 irq = DISPC_IRQ_EVSYNC_ODD;
511 else
512 irq = DISPC_IRQ_VSYNC;
513
514 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
515}
516
504static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 517static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
505{ 518{
506 unsigned long timeout = msecs_to_jiffies(500); 519 unsigned long timeout = msecs_to_jiffies(500);
@@ -509,17 +522,18 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
509 u32 irq; 522 u32 irq;
510 int r; 523 int r;
511 int i; 524 int i;
525 struct omap_dss_device *dssdev = mgr->device;
512 526
513 if (!mgr->device) 527 if (!dssdev)
514 return 0; 528 return 0;
515 529
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { 530 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 531 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
518 channel = OMAP_DSS_CHANNEL_DIGIT; 532 channel = OMAP_DSS_CHANNEL_DIGIT;
519 } else { 533 } else {
520 if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 534 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
521 enum omap_dss_update_mode mode; 535 enum omap_dss_update_mode mode;
522 mode = mgr->device->get_update_mode(mgr->device); 536 mode = dssdev->driver->get_update_mode(dssdev);
523 if (mode != OMAP_DSS_UPDATE_AUTO) 537 if (mode != OMAP_DSS_UPDATE_AUTO)
524 return 0; 538 return 0;
525 539
@@ -592,7 +606,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
592 } else { 606 } else {
593 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 607 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
594 enum omap_dss_update_mode mode; 608 enum omap_dss_update_mode mode;
595 mode = dssdev->get_update_mode(dssdev); 609 mode = dssdev->driver->get_update_mode(dssdev);
596 if (mode != OMAP_DSS_UPDATE_AUTO) 610 if (mode != OMAP_DSS_UPDATE_AUTO)
597 return 0; 611 return 0;
598 612
@@ -1064,7 +1078,7 @@ void dss_start_update(struct omap_dss_device *dssdev)
1064 mc->shadow_dirty = false; 1078 mc->shadow_dirty = false;
1065 } 1079 }
1066 1080
1067 dispc_enable_lcd_out(1); 1081 dssdev->manager->enable(dssdev->manager);
1068} 1082}
1069 1083
1070static void dss_apply_irq_handler(void *data, u32 mask) 1084static void dss_apply_irq_handler(void *data, u32 mask)
@@ -1196,7 +1210,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1196 1210
1197 oc->manual_update = 1211 oc->manual_update =
1198 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1212 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1199 dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; 1213 dssdev->driver->get_update_mode(dssdev) !=
1214 OMAP_DSS_UPDATE_AUTO;
1200 1215
1201 ++num_planes_enabled; 1216 ++num_planes_enabled;
1202 } 1217 }
@@ -1237,7 +1252,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1237 1252
1238 mc->manual_update = 1253 mc->manual_update =
1239 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1254 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1240 dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; 1255 dssdev->driver->get_update_mode(dssdev) !=
1256 OMAP_DSS_UPDATE_AUTO;
1241 } 1257 }
1242 1258
1243 /* XXX TODO: Try to get fifomerge working. The problem is that it 1259 /* XXX TODO: Try to get fifomerge working. The problem is that it
@@ -1351,6 +1367,18 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
1351 *info = mgr->info; 1367 *info = mgr->info;
1352} 1368}
1353 1369
1370static int dss_mgr_enable(struct omap_overlay_manager *mgr)
1371{
1372 dispc_enable_channel(mgr->id, 1);
1373 return 0;
1374}
1375
1376static int dss_mgr_disable(struct omap_overlay_manager *mgr)
1377{
1378 dispc_enable_channel(mgr->id, 0);
1379 return 0;
1380}
1381
1354static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) 1382static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
1355{ 1383{
1356 ++num_managers; 1384 ++num_managers;
@@ -1394,6 +1422,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1394 mgr->set_manager_info = &omap_dss_mgr_set_info; 1422 mgr->set_manager_info = &omap_dss_mgr_set_info;
1395 mgr->get_manager_info = &omap_dss_mgr_get_info; 1423 mgr->get_manager_info = &omap_dss_mgr_get_info;
1396 mgr->wait_for_go = &dss_mgr_wait_for_go; 1424 mgr->wait_for_go = &dss_mgr_wait_for_go;
1425 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
1426
1427 mgr->enable = &dss_mgr_enable;
1428 mgr->disable = &dss_mgr_disable;
1397 1429
1398 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; 1430 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
1399 1431
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index b7f9a7339842..0c5bea263ac6 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -350,7 +350,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
350 return -EINVAL; 350 return -EINVAL;
351 } 351 }
352 352
353 dssdev->get_resolution(dssdev, &dw, &dh); 353 dssdev->driver->get_resolution(dssdev, &dw, &dh);
354 354
355 DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n", 355 DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
356 ovl->id, 356 ovl->id,
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index b936495c065d..cc23f53cc62d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
36#include <plat/display.h> 36#include <plat/display.h>
37#include "dss.h" 37#include "dss.h"
38 38
39/*#define MEASURE_PERF*/
40
41#define RFBI_BASE 0x48050800 39#define RFBI_BASE 0x48050800
42 40
43struct rfbi_reg { u16 idx; }; 41struct rfbi_reg { u16 idx; };
@@ -66,8 +64,6 @@ struct rfbi_reg { u16 idx; };
66#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090) 64#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090)
67#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094) 65#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094)
68 66
69#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param))
70
71#define REG_FLD_MOD(idx, val, start, end) \ 67#define REG_FLD_MOD(idx, val, start, end) \
72 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) 68 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
73 69
@@ -102,7 +98,6 @@ enum update_cmd {
102 98
103static int rfbi_convert_timings(struct rfbi_timings *t); 99static int rfbi_convert_timings(struct rfbi_timings *t);
104static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
105static void process_cmd_fifo(void);
106 101
107static struct { 102static struct {
108 void __iomem *base; 103 void __iomem *base;
@@ -125,11 +120,6 @@ static struct {
125 struct completion cmd_done; 120 struct completion cmd_done;
126 atomic_t cmd_fifo_full; 121 atomic_t cmd_fifo_full;
127 atomic_t cmd_pending; 122 atomic_t cmd_pending;
128#ifdef MEASURE_PERF
129 unsigned perf_bytes;
130 ktime_t perf_setup_time;
131 ktime_t perf_start_time;
132#endif
133} rfbi; 123} rfbi;
134 124
135struct update_region { 125struct update_region {
@@ -139,16 +129,6 @@ struct update_region {
139 u16 h; 129 u16 h;
140}; 130};
141 131
142struct update_param {
143 u8 rfbi_module;
144 u8 cmd;
145
146 union {
147 struct update_region r;
148 struct completion *sync;
149 } par;
150};
151
152static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 132static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
153{ 133{
154 __raw_writel(val, rfbi.base + idx.idx); 134 __raw_writel(val, rfbi.base + idx.idx);
@@ -321,55 +301,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
321} 301}
322EXPORT_SYMBOL(omap_rfbi_write_pixels); 302EXPORT_SYMBOL(omap_rfbi_write_pixels);
323 303
324#ifdef MEASURE_PERF
325static void perf_mark_setup(void)
326{
327 rfbi.perf_setup_time = ktime_get();
328}
329
330static void perf_mark_start(void)
331{
332 rfbi.perf_start_time = ktime_get();
333}
334
335static void perf_show(const char *name)
336{
337 ktime_t t, setup_time, trans_time;
338 u32 total_bytes;
339 u32 setup_us, trans_us, total_us;
340
341 t = ktime_get();
342
343 setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time);
344 setup_us = (u32)ktime_to_us(setup_time);
345 if (setup_us == 0)
346 setup_us = 1;
347
348 trans_time = ktime_sub(t, rfbi.perf_start_time);
349 trans_us = (u32)ktime_to_us(trans_time);
350 if (trans_us == 0)
351 trans_us = 1;
352
353 total_us = setup_us + trans_us;
354
355 total_bytes = rfbi.perf_bytes;
356
357 DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
358 "%u kbytes/sec\n",
359 name,
360 setup_us,
361 trans_us,
362 total_us,
363 1000*1000 / total_us,
364 total_bytes,
365 total_bytes * 1000 / total_us);
366}
367#else
368#define perf_mark_setup()
369#define perf_mark_start()
370#define perf_show(x)
371#endif
372
373void rfbi_transfer_area(u16 width, u16 height, 304void rfbi_transfer_area(u16 width, u16 height,
374 void (callback)(void *data), void *data) 305 void (callback)(void *data), void *data)
375{ 306{
@@ -382,7 +313,7 @@ void rfbi_transfer_area(u16 width, u16 height,
382 313
383 dispc_set_lcd_size(width, height); 314 dispc_set_lcd_size(width, height);
384 315
385 dispc_enable_lcd_out(1); 316 dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true);
386 317
387 rfbi.framedone_callback = callback; 318 rfbi.framedone_callback = callback;
388 rfbi.framedone_callback_data = data; 319 rfbi.framedone_callback_data = data;
@@ -396,8 +327,6 @@ void rfbi_transfer_area(u16 width, u16 height,
396 if (!rfbi.te_enabled) 327 if (!rfbi.te_enabled)
397 l = FLD_MOD(l, 1, 4, 4); /* ITE */ 328 l = FLD_MOD(l, 1, 4, 4); /* ITE */
398 329
399 perf_mark_start();
400
401 rfbi_write_reg(RFBI_CONTROL, l); 330 rfbi_write_reg(RFBI_CONTROL, l);
402} 331}
403 332
@@ -407,8 +336,6 @@ static void framedone_callback(void *data, u32 mask)
407 336
408 DSSDBG("FRAMEDONE\n"); 337 DSSDBG("FRAMEDONE\n");
409 338
410 perf_show("DISPC");
411
412 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); 339 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
413 340
414 rfbi_enable_clocks(0); 341 rfbi_enable_clocks(0);
@@ -416,11 +343,10 @@ static void framedone_callback(void *data, u32 mask)
416 callback = rfbi.framedone_callback; 343 callback = rfbi.framedone_callback;
417 rfbi.framedone_callback = NULL; 344 rfbi.framedone_callback = NULL;
418 345
419 /*callback(rfbi.framedone_callback_data);*/ 346 if (callback != NULL)
347 callback(rfbi.framedone_callback_data);
420 348
421 atomic_set(&rfbi.cmd_pending, 0); 349 atomic_set(&rfbi.cmd_pending, 0);
422
423 process_cmd_fifo();
424} 350}
425 351
426#if 1 /* VERBOSE */ 352#if 1 /* VERBOSE */
@@ -937,52 +863,43 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
937} 863}
938EXPORT_SYMBOL(rfbi_configure); 864EXPORT_SYMBOL(rfbi_configure);
939 865
940static int rfbi_find_display(struct omap_dss_device *dssdev) 866int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
867 u16 *x, u16 *y, u16 *w, u16 *h)
941{ 868{
942 if (dssdev == rfbi.dssdev[0]) 869 u16 dw, dh;
943 return 0;
944 870
945 if (dssdev == rfbi.dssdev[1]) 871 dssdev->driver->get_resolution(dssdev, &dw, &dh);
946 return 1;
947 872
948 BUG(); 873 if (*x > dw || *y > dh)
949 return -1; 874 return -EINVAL;
950}
951 875
876 if (*x + *w > dw)
877 return -EINVAL;
952 878
953static void signal_fifo_waiters(void) 879 if (*y + *h > dh)
954{ 880 return -EINVAL;
955 if (atomic_read(&rfbi.cmd_fifo_full) > 0) {
956 /* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */
957 complete(&rfbi.cmd_done);
958 atomic_dec(&rfbi.cmd_fifo_full);
959 }
960}
961 881
962/* returns 1 for async op, and 0 for sync op */ 882 if (*w == 1)
963static int do_update(struct omap_dss_device *dssdev, struct update_region *upd) 883 return -EINVAL;
964{
965 u16 x = upd->x;
966 u16 y = upd->y;
967 u16 w = upd->w;
968 u16 h = upd->h;
969 884
970 perf_mark_setup(); 885 if (*w == 0 || *h == 0)
886 return -EINVAL;
971 887
972 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
973 /*dssdev->driver->enable_te(dssdev, 1); */ 889 dss_setup_partial_planes(dssdev, x, y, w, h);
974 dss_setup_partial_planes(dssdev, &x, &y, &w, &h); 890 dispc_set_lcd_size(*w, *h);
975 } 891 }
976 892
977#ifdef MEASURE_PERF 893 return 0;
978 rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */ 894}
979#endif 895EXPORT_SYMBOL(omap_rfbi_prepare_update);
980
981 dssdev->driver->setup_update(dssdev, x, y, w, h);
982 896
897int omap_rfbi_update(struct omap_dss_device *dssdev,
898 u16 x, u16 y, u16 w, u16 h,
899 void (*callback)(void *), void *data)
900{
983 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 901 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
984 rfbi_transfer_area(w, h, NULL, NULL); 902 rfbi_transfer_area(w, h, callback, data);
985 return 1;
986 } else { 903 } else {
987 struct omap_overlay *ovl; 904 struct omap_overlay *ovl;
988 void __iomem *addr; 905 void __iomem *addr;
@@ -994,123 +911,12 @@ static int do_update(struct omap_dss_device *dssdev, struct update_region *upd)
994 911
995 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h); 912 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
996 913
997 perf_show("L4"); 914 callback(data);
998
999 return 0;
1000 } 915 }
1001}
1002
1003static void process_cmd_fifo(void)
1004{
1005 int len;
1006 struct update_param p;
1007 struct omap_dss_device *dssdev;
1008 unsigned long flags;
1009
1010 if (atomic_inc_return(&rfbi.cmd_pending) != 1)
1011 return;
1012
1013 while (true) {
1014 spin_lock_irqsave(&rfbi.cmd_lock, flags);
1015
1016 len = kfifo_out(&rfbi.cmd_fifo, (unsigned char *)&p,
1017 sizeof(struct update_param));
1018 if (len == 0) {
1019 DSSDBG("nothing more in fifo\n");
1020 atomic_set(&rfbi.cmd_pending, 0);
1021 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1022 break;
1023 }
1024
1025 /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
1026
1027 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1028
1029 BUG_ON(len != sizeof(struct update_param));
1030 BUG_ON(p.rfbi_module > 1);
1031
1032 dssdev = rfbi.dssdev[p.rfbi_module];
1033
1034 if (p.cmd == RFBI_CMD_UPDATE) {
1035 if (do_update(dssdev, &p.par.r))
1036 break; /* async op */
1037 } else if (p.cmd == RFBI_CMD_SYNC) {
1038 DSSDBG("Signaling SYNC done!\n");
1039 complete(p.par.sync);
1040 } else
1041 BUG();
1042 }
1043
1044 signal_fifo_waiters();
1045}
1046 916
1047static void rfbi_push_cmd(struct update_param *p) 917 return 0;
1048{
1049 int ret;
1050
1051 while (1) {
1052 unsigned long flags;
1053 int available;
1054
1055 spin_lock_irqsave(&rfbi.cmd_lock, flags);
1056 available = RFBI_CMD_FIFO_LEN_BYTES -
1057 kfifo_len(&rfbi.cmd_fifo);
1058
1059/* DSSDBG("%d bytes left in fifo\n", available); */
1060 if (available < sizeof(struct update_param)) {
1061 DSSDBG("Going to wait because FIFO FULL..\n");
1062 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1063 atomic_inc(&rfbi.cmd_fifo_full);
1064 wait_for_completion(&rfbi.cmd_done);
1065 /*DSSDBG("Woke up because fifo not full anymore\n");*/
1066 continue;
1067 }
1068
1069 ret = kfifo_in(&rfbi.cmd_fifo, (unsigned char *)p,
1070 sizeof(struct update_param));
1071/* DSSDBG("pushed %d bytes\n", ret);*/
1072
1073 spin_unlock_irqrestore(&rfbi.cmd_lock, flags);
1074
1075 BUG_ON(ret != sizeof(struct update_param));
1076
1077 break;
1078 }
1079}
1080
1081static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h)
1082{
1083 struct update_param p;
1084
1085 p.rfbi_module = rfbi_module;
1086 p.cmd = RFBI_CMD_UPDATE;
1087
1088 p.par.r.x = x;
1089 p.par.r.y = y;
1090 p.par.r.w = w;
1091 p.par.r.h = h;
1092
1093 DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h);
1094
1095 rfbi_push_cmd(&p);
1096
1097 process_cmd_fifo();
1098}
1099
1100static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp)
1101{
1102 struct update_param p;
1103
1104 p.rfbi_module = rfbi_module;
1105 p.cmd = RFBI_CMD_SYNC;
1106 p.par.sync = sync_comp;
1107
1108 rfbi_push_cmd(&p);
1109
1110 DSSDBG("RFBI sync pushed to cmd fifo\n");
1111
1112 process_cmd_fifo();
1113} 918}
919EXPORT_SYMBOL(omap_rfbi_update);
1114 920
1115void rfbi_dump_regs(struct seq_file *s) 921void rfbi_dump_regs(struct seq_file *s)
1116{ 922{
@@ -1155,12 +961,8 @@ int rfbi_init(void)
1155{ 961{
1156 u32 rev; 962 u32 rev;
1157 u32 l; 963 u32 l;
1158 int r;
1159 964
1160 spin_lock_init(&rfbi.cmd_lock); 965 spin_lock_init(&rfbi.cmd_lock);
1161 r = kfifo_alloc(&rfbi.cmd_fifo, RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL);
1162 if (r)
1163 return r;
1164 966
1165 init_completion(&rfbi.cmd_done); 967 init_completion(&rfbi.cmd_done);
1166 atomic_set(&rfbi.cmd_fifo_full, 0); 968 atomic_set(&rfbi.cmd_fifo_full, 0);
@@ -1196,49 +998,10 @@ void rfbi_exit(void)
1196{ 998{
1197 DSSDBG("rfbi_exit\n"); 999 DSSDBG("rfbi_exit\n");
1198 1000
1199 kfifo_free(&rfbi.cmd_fifo);
1200
1201 iounmap(rfbi.base); 1001 iounmap(rfbi.base);
1202} 1002}
1203 1003
1204/* struct omap_display support */ 1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1205static int rfbi_display_update(struct omap_dss_device *dssdev,
1206 u16 x, u16 y, u16 w, u16 h)
1207{
1208 int rfbi_module;
1209
1210 if (w == 0 || h == 0)
1211 return 0;
1212
1213 rfbi_module = rfbi_find_display(dssdev);
1214
1215 rfbi_push_update(rfbi_module, x, y, w, h);
1216
1217 return 0;
1218}
1219
1220static int rfbi_display_sync(struct omap_dss_device *dssdev)
1221{
1222 struct completion sync_comp;
1223 int rfbi_module;
1224
1225 rfbi_module = rfbi_find_display(dssdev);
1226
1227 init_completion(&sync_comp);
1228 rfbi_push_sync(rfbi_module, &sync_comp);
1229 DSSDBG("Waiting for SYNC to happen...\n");
1230 wait_for_completion(&sync_comp);
1231 DSSDBG("Released from SYNC\n");
1232 return 0;
1233}
1234
1235static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
1236{
1237 dssdev->driver->enable_te(dssdev, enable);
1238 return 0;
1239}
1240
1241static int rfbi_display_enable(struct omap_dss_device *dssdev)
1242{ 1005{
1243 int r; 1006 int r;
1244 1007
@@ -1269,41 +1032,25 @@ static int rfbi_display_enable(struct omap_dss_device *dssdev)
1269 &dssdev->ctrl.rfbi_timings); 1032 &dssdev->ctrl.rfbi_timings);
1270 1033
1271 1034
1272 if (dssdev->driver->enable) {
1273 r = dssdev->driver->enable(dssdev);
1274 if (r)
1275 goto err2;
1276 }
1277
1278 return 0; 1035 return 0;
1279err2:
1280 omap_dispc_unregister_isr(framedone_callback, NULL,
1281 DISPC_IRQ_FRAMEDONE);
1282err1: 1036err1:
1283 omap_dss_stop_device(dssdev); 1037 omap_dss_stop_device(dssdev);
1284err0: 1038err0:
1285 return r; 1039 return r;
1286} 1040}
1041EXPORT_SYMBOL(omapdss_rfbi_display_enable);
1287 1042
1288static void rfbi_display_disable(struct omap_dss_device *dssdev) 1043void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
1289{ 1044{
1290 dssdev->driver->disable(dssdev);
1291 omap_dispc_unregister_isr(framedone_callback, NULL, 1045 omap_dispc_unregister_isr(framedone_callback, NULL,
1292 DISPC_IRQ_FRAMEDONE); 1046 DISPC_IRQ_FRAMEDONE);
1293 omap_dss_stop_device(dssdev); 1047 omap_dss_stop_device(dssdev);
1294} 1048}
1049EXPORT_SYMBOL(omapdss_rfbi_display_disable);
1295 1050
1296int rfbi_init_display(struct omap_dss_device *dssdev) 1051int rfbi_init_display(struct omap_dss_device *dssdev)
1297{ 1052{
1298 dssdev->enable = rfbi_display_enable;
1299 dssdev->disable = rfbi_display_disable;
1300 dssdev->update = rfbi_display_update;
1301 dssdev->sync = rfbi_display_sync;
1302 dssdev->enable_te = rfbi_display_enable_te;
1303
1304 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; 1053 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
1305
1306 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 1054 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1307
1308 return 0; 1055 return 0;
1309} 1056}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index c24f307d3da1..12eb4042dd82 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -41,7 +41,7 @@ static void sdi_basic_init(void)
41 dispc_lcd_enable_signal_polarity(1); 41 dispc_lcd_enable_signal_polarity(1);
42} 42}
43 43
44static int sdi_display_enable(struct omap_dss_device *dssdev) 44int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
45{ 45{
46 struct omap_video_timings *t = &dssdev->panel.timings; 46 struct omap_video_timings *t = &dssdev->panel.timings;
47 struct dss_clock_info dss_cinfo; 47 struct dss_clock_info dss_cinfo;
@@ -57,12 +57,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
57 goto err0; 57 goto err0;
58 } 58 }
59 59
60 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
61 DSSERR("dssdev already enabled\n");
62 r = -EINVAL;
63 goto err1;
64 }
65
66 /* In case of skip_init sdi_init has already enabled the clocks */ 60 /* In case of skip_init sdi_init has already enabled the clocks */
67 if (!sdi.skip_init) 61 if (!sdi.skip_init)
68 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 62 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -119,7 +113,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
119 mdelay(2); 113 mdelay(2);
120 } 114 }
121 115
122 dispc_enable_lcd_out(1); 116 dssdev->manager->enable(dssdev->manager);
123 117
124 if (dssdev->driver->enable) { 118 if (dssdev->driver->enable) {
125 r = dssdev->driver->enable(dssdev); 119 r = dssdev->driver->enable(dssdev);
@@ -127,13 +121,11 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
127 goto err3; 121 goto err3;
128 } 122 }
129 123
130 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
131
132 sdi.skip_init = 0; 124 sdi.skip_init = 0;
133 125
134 return 0; 126 return 0;
135err3: 127err3:
136 dispc_enable_lcd_out(0); 128 dssdev->manager->disable(dssdev->manager);
137err2: 129err2:
138 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 130 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
139err1: 131err1:
@@ -141,120 +133,27 @@ err1:
141err0: 133err0:
142 return r; 134 return r;
143} 135}
136EXPORT_SYMBOL(omapdss_sdi_display_enable);
144 137
145static int sdi_display_resume(struct omap_dss_device *dssdev); 138void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
146
147static void sdi_display_disable(struct omap_dss_device *dssdev)
148{ 139{
149 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
150 return;
151
152 if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
153 if (sdi_display_resume(dssdev))
154 return;
155
156 if (dssdev->driver->disable) 140 if (dssdev->driver->disable)
157 dssdev->driver->disable(dssdev); 141 dssdev->driver->disable(dssdev);
158 142
159 dispc_enable_lcd_out(0); 143 dssdev->manager->disable(dssdev->manager);
160 144
161 dss_sdi_disable(); 145 dss_sdi_disable();
162 146
163 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
164 148
165 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
166
167 omap_dss_stop_device(dssdev); 149 omap_dss_stop_device(dssdev);
168} 150}
169 151EXPORT_SYMBOL(omapdss_sdi_display_disable);
170static int sdi_display_suspend(struct omap_dss_device *dssdev)
171{
172 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
173 return -EINVAL;
174
175 if (dssdev->driver->suspend)
176 dssdev->driver->suspend(dssdev);
177
178 dispc_enable_lcd_out(0);
179
180 dss_sdi_disable();
181
182 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
183
184 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
185
186 return 0;
187}
188
189static int sdi_display_resume(struct omap_dss_device *dssdev)
190{
191 int r;
192
193 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
194 return -EINVAL;
195
196 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
197
198 r = dss_sdi_enable();
199 if (r)
200 goto err;
201 mdelay(2);
202
203 dispc_enable_lcd_out(1);
204
205 if (dssdev->driver->resume)
206 dssdev->driver->resume(dssdev);
207
208 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
209
210 return 0;
211err:
212 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
213 return r;
214}
215
216static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
217 enum omap_dss_update_mode mode)
218{
219 if (mode == OMAP_DSS_UPDATE_MANUAL)
220 return -EINVAL;
221
222 if (mode == OMAP_DSS_UPDATE_DISABLED) {
223 dispc_enable_lcd_out(0);
224 sdi.update_enabled = 0;
225 } else {
226 dispc_enable_lcd_out(1);
227 sdi.update_enabled = 1;
228 }
229
230 return 0;
231}
232
233static enum omap_dss_update_mode sdi_display_get_update_mode(
234 struct omap_dss_device *dssdev)
235{
236 return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
237 OMAP_DSS_UPDATE_DISABLED;
238}
239
240static void sdi_get_timings(struct omap_dss_device *dssdev,
241 struct omap_video_timings *timings)
242{
243 *timings = dssdev->panel.timings;
244}
245 152
246int sdi_init_display(struct omap_dss_device *dssdev) 153int sdi_init_display(struct omap_dss_device *dssdev)
247{ 154{
248 DSSDBG("SDI init\n"); 155 DSSDBG("SDI init\n");
249 156
250 dssdev->enable = sdi_display_enable;
251 dssdev->disable = sdi_display_disable;
252 dssdev->suspend = sdi_display_suspend;
253 dssdev->resume = sdi_display_resume;
254 dssdev->set_update_mode = sdi_display_set_update_mode;
255 dssdev->get_update_mode = sdi_display_get_update_mode;
256 dssdev->get_timings = sdi_get_timings;
257
258 return 0; 157 return 0;
259} 158}
260 159
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 749a5a0f5be4..f0ba5732d84a 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -400,114 +400,6 @@ static const struct venc_config *venc_timings_to_config(
400 BUG(); 400 BUG();
401} 401}
402 402
403
404
405
406
407/* driver */
408static int venc_panel_probe(struct omap_dss_device *dssdev)
409{
410 dssdev->panel.timings = omap_dss_pal_timings;
411
412 return 0;
413}
414
415static void venc_panel_remove(struct omap_dss_device *dssdev)
416{
417}
418
419static int venc_panel_enable(struct omap_dss_device *dssdev)
420{
421 int r = 0;
422
423 /* wait couple of vsyncs until enabling the LCD */
424 msleep(50);
425
426 if (dssdev->platform_enable)
427 r = dssdev->platform_enable(dssdev);
428
429 return r;
430}
431
432static void venc_panel_disable(struct omap_dss_device *dssdev)
433{
434 if (dssdev->platform_disable)
435 dssdev->platform_disable(dssdev);
436
437 /* wait at least 5 vsyncs after disabling the LCD */
438
439 msleep(100);
440}
441
442static int venc_panel_suspend(struct omap_dss_device *dssdev)
443{
444 venc_panel_disable(dssdev);
445 return 0;
446}
447
448static int venc_panel_resume(struct omap_dss_device *dssdev)
449{
450 return venc_panel_enable(dssdev);
451}
452
453static struct omap_dss_driver venc_driver = {
454 .probe = venc_panel_probe,
455 .remove = venc_panel_remove,
456
457 .enable = venc_panel_enable,
458 .disable = venc_panel_disable,
459 .suspend = venc_panel_suspend,
460 .resume = venc_panel_resume,
461
462 .driver = {
463 .name = "venc",
464 .owner = THIS_MODULE,
465 },
466};
467/* driver end */
468
469
470
471int venc_init(struct platform_device *pdev)
472{
473 u8 rev_id;
474
475 mutex_init(&venc.venc_lock);
476
477 venc.wss_data = 0;
478
479 venc.base = ioremap(VENC_BASE, SZ_1K);
480 if (!venc.base) {
481 DSSERR("can't ioremap VENC\n");
482 return -ENOMEM;
483 }
484
485 venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac");
486 if (IS_ERR(venc.vdda_dac_reg)) {
487 iounmap(venc.base);
488 DSSERR("can't get VDDA_DAC regulator\n");
489 return PTR_ERR(venc.vdda_dac_reg);
490 }
491
492 venc_enable_clocks(1);
493
494 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
495 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
496
497 venc_enable_clocks(0);
498
499 return omap_dss_register_driver(&venc_driver);
500}
501
502void venc_exit(void)
503{
504 omap_dss_unregister_driver(&venc_driver);
505
506 regulator_put(venc.vdda_dac_reg);
507
508 iounmap(venc.base);
509}
510
511static void venc_power_on(struct omap_dss_device *dssdev) 403static void venc_power_on(struct omap_dss_device *dssdev)
512{ 404{
513 u32 l; 405 u32 l;
@@ -540,7 +432,7 @@ static void venc_power_on(struct omap_dss_device *dssdev)
540 if (dssdev->platform_enable) 432 if (dssdev->platform_enable)
541 dssdev->platform_enable(dssdev); 433 dssdev->platform_enable(dssdev);
542 434
543 dispc_enable_digit_out(1); 435 dssdev->manager->enable(dssdev->manager);
544} 436}
545 437
546static void venc_power_off(struct omap_dss_device *dssdev) 438static void venc_power_off(struct omap_dss_device *dssdev)
@@ -548,7 +440,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
548 venc_write_reg(VENC_OUTPUT_CONTROL, 0); 440 venc_write_reg(VENC_OUTPUT_CONTROL, 0);
549 dss_set_dac_pwrdn_bgz(0); 441 dss_set_dac_pwrdn_bgz(0);
550 442
551 dispc_enable_digit_out(0); 443 dssdev->manager->disable(dssdev->manager);
552 444
553 if (dssdev->platform_disable) 445 if (dssdev->platform_disable)
554 dssdev->platform_disable(dssdev); 446 dssdev->platform_disable(dssdev);
@@ -558,7 +450,23 @@ static void venc_power_off(struct omap_dss_device *dssdev)
558 venc_enable_clocks(0); 450 venc_enable_clocks(0);
559} 451}
560 452
561static int venc_enable_display(struct omap_dss_device *dssdev) 453
454
455
456
457/* driver */
458static int venc_panel_probe(struct omap_dss_device *dssdev)
459{
460 dssdev->panel.timings = omap_dss_pal_timings;
461
462 return 0;
463}
464
465static void venc_panel_remove(struct omap_dss_device *dssdev)
466{
467}
468
469static int venc_panel_enable(struct omap_dss_device *dssdev)
562{ 470{
563 int r = 0; 471 int r = 0;
564 472
@@ -568,7 +476,13 @@ static int venc_enable_display(struct omap_dss_device *dssdev)
568 476
569 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 477 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
570 r = -EINVAL; 478 r = -EINVAL;
571 goto err; 479 goto err1;
480 }
481
482 if (dssdev->platform_enable) {
483 r = dssdev->platform_enable(dssdev);
484 if (r)
485 goto err2;
572 } 486 }
573 487
574 venc_power_on(dssdev); 488 venc_power_on(dssdev);
@@ -576,13 +490,21 @@ static int venc_enable_display(struct omap_dss_device *dssdev)
576 venc.wss_data = 0; 490 venc.wss_data = 0;
577 491
578 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 492 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
579err: 493
494 /* wait couple of vsyncs until enabling the LCD */
495 msleep(50);
496
580 mutex_unlock(&venc.venc_lock); 497 mutex_unlock(&venc.venc_lock);
581 498
582 return r; 499 return r;
500err2:
501 venc_power_off(dssdev);
502err1:
503 mutex_unlock(&venc.venc_lock);
504 return r;
583} 505}
584 506
585static void venc_disable_display(struct omap_dss_device *dssdev) 507static void venc_panel_disable(struct omap_dss_device *dssdev)
586{ 508{
587 DSSDBG("venc_disable_display\n"); 509 DSSDBG("venc_disable_display\n");
588 510
@@ -599,53 +521,40 @@ static void venc_disable_display(struct omap_dss_device *dssdev)
599 521
600 venc_power_off(dssdev); 522 venc_power_off(dssdev);
601 523
524 /* wait at least 5 vsyncs after disabling the LCD */
525 msleep(100);
526
527 if (dssdev->platform_disable)
528 dssdev->platform_disable(dssdev);
529
602 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 530 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
603end: 531end:
604 mutex_unlock(&venc.venc_lock); 532 mutex_unlock(&venc.venc_lock);
605} 533}
606 534
607static int venc_display_suspend(struct omap_dss_device *dssdev) 535static int venc_panel_suspend(struct omap_dss_device *dssdev)
608{ 536{
609 int r = 0; 537 venc_panel_disable(dssdev);
610 538 return 0;
611 DSSDBG("venc_display_suspend\n");
612
613 mutex_lock(&venc.venc_lock);
614
615 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
616 r = -EINVAL;
617 goto err;
618 }
619
620 venc_power_off(dssdev);
621
622 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
623err:
624 mutex_unlock(&venc.venc_lock);
625
626 return r;
627} 539}
628 540
629static int venc_display_resume(struct omap_dss_device *dssdev) 541static int venc_panel_resume(struct omap_dss_device *dssdev)
630{ 542{
631 int r = 0; 543 return venc_panel_enable(dssdev);
632 544}
633 DSSDBG("venc_display_resume\n");
634
635 mutex_lock(&venc.venc_lock);
636
637 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
638 r = -EINVAL;
639 goto err;
640 }
641
642 venc_power_on(dssdev);
643 545
644 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 546static enum omap_dss_update_mode venc_get_update_mode(
645err: 547 struct omap_dss_device *dssdev)
646 mutex_unlock(&venc.venc_lock); 548{
549 return OMAP_DSS_UPDATE_AUTO;
550}
647 551
648 return r; 552static int venc_set_update_mode(struct omap_dss_device *dssdev,
553 enum omap_dss_update_mode mode)
554{
555 if (mode != OMAP_DSS_UPDATE_AUTO)
556 return -EINVAL;
557 return 0;
649} 558}
650 559
651static void venc_get_timings(struct omap_dss_device *dssdev, 560static void venc_get_timings(struct omap_dss_device *dssdev,
@@ -666,8 +575,8 @@ static void venc_set_timings(struct omap_dss_device *dssdev,
666 dssdev->panel.timings = *timings; 575 dssdev->panel.timings = *timings;
667 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 576 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
668 /* turn the venc off and on to get new timings to use */ 577 /* turn the venc off and on to get new timings to use */
669 venc_disable_display(dssdev); 578 venc_panel_disable(dssdev);
670 venc_enable_display(dssdev); 579 venc_panel_enable(dssdev);
671 } 580 }
672} 581}
673 582
@@ -716,30 +625,79 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
716 return 0; 625 return 0;
717} 626}
718 627
719static enum omap_dss_update_mode venc_display_get_update_mode( 628static struct omap_dss_driver venc_driver = {
720 struct omap_dss_device *dssdev) 629 .probe = venc_panel_probe,
630 .remove = venc_panel_remove,
631
632 .enable = venc_panel_enable,
633 .disable = venc_panel_disable,
634 .suspend = venc_panel_suspend,
635 .resume = venc_panel_resume,
636
637 .get_resolution = omapdss_default_get_resolution,
638 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
639
640 .set_update_mode = venc_set_update_mode,
641 .get_update_mode = venc_get_update_mode,
642
643 .get_timings = venc_get_timings,
644 .set_timings = venc_set_timings,
645 .check_timings = venc_check_timings,
646
647 .get_wss = venc_get_wss,
648 .set_wss = venc_set_wss,
649
650 .driver = {
651 .name = "venc",
652 .owner = THIS_MODULE,
653 },
654};
655/* driver end */
656
657
658
659int venc_init(struct platform_device *pdev)
721{ 660{
722 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 661 u8 rev_id;
723 return OMAP_DSS_UPDATE_AUTO; 662
724 else 663 mutex_init(&venc.venc_lock);
725 return OMAP_DSS_UPDATE_DISABLED; 664
665 venc.wss_data = 0;
666
667 venc.base = ioremap(VENC_BASE, SZ_1K);
668 if (!venc.base) {
669 DSSERR("can't ioremap VENC\n");
670 return -ENOMEM;
671 }
672
673 venc.vdda_dac_reg = dss_get_vdda_dac();
674 if (IS_ERR(venc.vdda_dac_reg)) {
675 iounmap(venc.base);
676 DSSERR("can't get VDDA_DAC regulator\n");
677 return PTR_ERR(venc.vdda_dac_reg);
678 }
679
680 venc_enable_clocks(1);
681
682 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
683 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
684
685 venc_enable_clocks(0);
686
687 return omap_dss_register_driver(&venc_driver);
688}
689
690void venc_exit(void)
691{
692 omap_dss_unregister_driver(&venc_driver);
693
694 iounmap(venc.base);
726} 695}
727 696
728int venc_init_display(struct omap_dss_device *dssdev) 697int venc_init_display(struct omap_dss_device *dssdev)
729{ 698{
730 DSSDBG("init_display\n"); 699 DSSDBG("init_display\n");
731 700
732 dssdev->enable = venc_enable_display;
733 dssdev->disable = venc_disable_display;
734 dssdev->suspend = venc_display_suspend;
735 dssdev->resume = venc_display_resume;
736 dssdev->get_timings = venc_get_timings;
737 dssdev->set_timings = venc_set_timings;
738 dssdev->check_timings = venc_check_timings;
739 dssdev->get_wss = venc_get_wss;
740 dssdev->set_wss = venc_set_wss;
741 dssdev->get_update_mode = venc_display_get_update_mode;
742
743 return 0; 701 return 0;
744} 702}
745 703
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index bb694cc52a50..43496d6c377f 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -16,16 +16,7 @@ config FB_OMAP2_DEBUG_SUPPORT
16 depends on FB_OMAP2 16 depends on FB_OMAP2
17 help 17 help
18 Support for debug output. You have to enable the actual printing 18 Support for debug output. You have to enable the actual printing
19 with debug module parameter. 19 with 'debug' module parameter.
20
21config FB_OMAP2_FORCE_AUTO_UPDATE
22 bool "Force main display to automatic update mode"
23 depends on FB_OMAP2
24 help
25 Forces main display to automatic update mode (if possible),
26 and also enables tearsync (if possible). By default
27 displays that support manual update are started in manual
28 update mode.
29 20
30config FB_OMAP2_NUM_FBS 21config FB_OMAP2_NUM_FBS
31 int "Number of framebuffers" 22 int "Number of framebuffers"
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 4c4bafdfaa43..1ffa760b8545 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -167,12 +167,12 @@ static int omapfb_update_window_nolock(struct fb_info *fbi,
167 if (w == 0 || h == 0) 167 if (w == 0 || h == 0)
168 return 0; 168 return 0;
169 169
170 display->get_resolution(display, &dw, &dh); 170 display->driver->get_resolution(display, &dw, &dh);
171 171
172 if (x + w > dw || y + h > dh) 172 if (x + w > dw || y + h > dh)
173 return -EINVAL; 173 return -EINVAL;
174 174
175 return display->update(display, x, y, w, h); 175 return display->driver->update(display, x, y, w, h);
176} 176}
177 177
178/* This function is exported for SGX driver use */ 178/* This function is exported for SGX driver use */
@@ -202,7 +202,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi,
202 enum omap_dss_update_mode um; 202 enum omap_dss_update_mode um;
203 int r; 203 int r;
204 204
205 if (!display || !display->set_update_mode) 205 if (!display || !display->driver->set_update_mode)
206 return -EINVAL; 206 return -EINVAL;
207 207
208 switch (mode) { 208 switch (mode) {
@@ -222,7 +222,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi,
222 return -EINVAL; 222 return -EINVAL;
223 } 223 }
224 224
225 r = display->set_update_mode(display, um); 225 r = display->driver->set_update_mode(display, um);
226 226
227 return r; 227 return r;
228} 228}
@@ -233,10 +233,15 @@ static int omapfb_get_update_mode(struct fb_info *fbi,
233 struct omap_dss_device *display = fb2display(fbi); 233 struct omap_dss_device *display = fb2display(fbi);
234 enum omap_dss_update_mode m; 234 enum omap_dss_update_mode m;
235 235
236 if (!display || !display->get_update_mode) 236 if (!display)
237 return -EINVAL; 237 return -EINVAL;
238 238
239 m = display->get_update_mode(display); 239 if (!display->driver->get_update_mode) {
240 *mode = OMAPFB_AUTO_UPDATE;
241 return 0;
242 }
243
244 m = display->driver->get_update_mode(display);
240 245
241 switch (m) { 246 switch (m) {
242 case OMAP_DSS_UPDATE_DISABLED: 247 case OMAP_DSS_UPDATE_DISABLED:
@@ -374,7 +379,7 @@ static int omapfb_memory_read(struct fb_info *fbi,
374 void *buf; 379 void *buf;
375 int r; 380 int r;
376 381
377 if (!display || !display->memory_read) 382 if (!display || !display->driver->memory_read)
378 return -ENOENT; 383 return -ENOENT;
379 384
380 if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size)) 385 if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size))
@@ -389,7 +394,7 @@ static int omapfb_memory_read(struct fb_info *fbi,
389 return -ENOMEM; 394 return -ENOMEM;
390 } 395 }
391 396
392 r = display->memory_read(display, buf, mr->buffer_size, 397 r = display->driver->memory_read(display, buf, mr->buffer_size,
393 mr->x, mr->y, mr->w, mr->h); 398 mr->x, mr->y, mr->w, mr->h);
394 399
395 if (r > 0) { 400 if (r > 0) {
@@ -483,6 +488,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
483 struct omapfb_memory_read memory_read; 488 struct omapfb_memory_read memory_read;
484 struct omapfb_vram_info vram_info; 489 struct omapfb_vram_info vram_info;
485 struct omapfb_tearsync_info tearsync_info; 490 struct omapfb_tearsync_info tearsync_info;
491 struct omapfb_display_info display_info;
486 } p; 492 } p;
487 493
488 int r = 0; 494 int r = 0;
@@ -490,18 +496,18 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
490 switch (cmd) { 496 switch (cmd) {
491 case OMAPFB_SYNC_GFX: 497 case OMAPFB_SYNC_GFX:
492 DBG("ioctl SYNC_GFX\n"); 498 DBG("ioctl SYNC_GFX\n");
493 if (!display || !display->sync) { 499 if (!display || !display->driver->sync) {
494 /* DSS1 never returns an error here, so we neither */ 500 /* DSS1 never returns an error here, so we neither */
495 /*r = -EINVAL;*/ 501 /*r = -EINVAL;*/
496 break; 502 break;
497 } 503 }
498 504
499 r = display->sync(display); 505 r = display->driver->sync(display);
500 break; 506 break;
501 507
502 case OMAPFB_UPDATE_WINDOW_OLD: 508 case OMAPFB_UPDATE_WINDOW_OLD:
503 DBG("ioctl UPDATE_WINDOW_OLD\n"); 509 DBG("ioctl UPDATE_WINDOW_OLD\n");
504 if (!display || !display->update) { 510 if (!display || !display->driver->update) {
505 r = -EINVAL; 511 r = -EINVAL;
506 break; 512 break;
507 } 513 }
@@ -519,7 +525,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
519 525
520 case OMAPFB_UPDATE_WINDOW: 526 case OMAPFB_UPDATE_WINDOW:
521 DBG("ioctl UPDATE_WINDOW\n"); 527 DBG("ioctl UPDATE_WINDOW\n");
522 if (!display || !display->update) { 528 if (!display || !display->driver->update) {
523 r = -EINVAL; 529 r = -EINVAL;
524 break; 530 break;
525 } 531 }
@@ -648,7 +654,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
648 break; 654 break;
649 } 655 }
650 656
651 r = display->wait_vsync(display); 657 r = display->manager->wait_for_vsync(display->manager);
652 break; 658 break;
653 659
654 case OMAPFB_WAITFORGO: 660 case OMAPFB_WAITFORGO:
@@ -669,12 +675,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
669 r = -EFAULT; 675 r = -EFAULT;
670 break; 676 break;
671 } 677 }
672 if (!display || !display->run_test) { 678 if (!display || !display->driver->run_test) {
673 r = -EINVAL; 679 r = -EINVAL;
674 break; 680 break;
675 } 681 }
676 682
677 r = display->run_test(display, p.test_num); 683 r = display->driver->run_test(display, p.test_num);
678 684
679 break; 685 break;
680 686
@@ -684,12 +690,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
684 r = -EFAULT; 690 r = -EFAULT;
685 break; 691 break;
686 } 692 }
687 if (!display || !display->run_test) { 693 if (!display || !display->driver->run_test) {
688 r = -EINVAL; 694 r = -EINVAL;
689 break; 695 break;
690 } 696 }
691 697
692 r = display->run_test(display, p.test_num); 698 r = display->driver->run_test(display, p.test_num);
693 699
694 break; 700 break;
695 701
@@ -731,13 +737,37 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
731 break; 737 break;
732 } 738 }
733 739
734 if (!display->enable_te) { 740 if (!display->driver->enable_te) {
735 r = -ENODEV; 741 r = -ENODEV;
736 break; 742 break;
737 } 743 }
738 744
739 r = display->enable_te(display, !!p.tearsync_info.enabled); 745 r = display->driver->enable_te(display,
746 !!p.tearsync_info.enabled);
747
748 break;
749 }
750
751 case OMAPFB_GET_DISPLAY_INFO: {
752 u16 xres, yres;
740 753
754 DBG("ioctl GET_DISPLAY_INFO\n");
755
756 if (display == NULL) {
757 r = -ENODEV;
758 break;
759 }
760
761 display->driver->get_resolution(display, &xres, &yres);
762
763 p.display_info.xres = xres;
764 p.display_info.yres = yres;
765 p.display_info.width = 0;
766 p.display_info.height = 0;
767
768 if (copy_to_user((void __user *)arg, &p.display_info,
769 sizeof(p.display_info)))
770 r = -EFAULT;
741 break; 771 break;
742 } 772 }
743 773
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index d17caef6915a..4a76917b7cc8 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -54,6 +54,8 @@ module_param_named(test, omapfb_test_pattern, bool, 0644);
54#endif 54#endif
55 55
56static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); 56static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
57static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
58 struct omap_dss_device *dssdev);
57 59
58#ifdef DEBUG 60#ifdef DEBUG
59static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) 61static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color)
@@ -152,9 +154,9 @@ static void fill_fb(struct fb_info *fbi)
152} 154}
153#endif 155#endif
154 156
155static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) 157static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
156{ 158{
157 struct vrfb *vrfb = &ofbi->region.vrfb; 159 const struct vrfb *vrfb = &ofbi->region.vrfb;
158 unsigned offset; 160 unsigned offset;
159 161
160 switch (rot) { 162 switch (rot) {
@@ -179,7 +181,7 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
179 return offset; 181 return offset;
180} 182}
181 183
182static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) 184static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
183{ 185{
184 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 186 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
185 return ofbi->region.vrfb.paddr[rot] 187 return ofbi->region.vrfb.paddr[rot]
@@ -189,7 +191,7 @@ static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot)
189 } 191 }
190} 192}
191 193
192static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) 194static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
193{ 195{
194 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 196 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
195 return ofbi->region.vrfb.paddr[0]; 197 return ofbi->region.vrfb.paddr[0];
@@ -197,7 +199,7 @@ static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
197 return ofbi->region.paddr; 199 return ofbi->region.paddr;
198} 200}
199 201
200static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) 202static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
201{ 203{
202 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 204 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
203 return ofbi->region.vrfb.vaddr[0]; 205 return ofbi->region.vrfb.vaddr[0];
@@ -703,9 +705,9 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
703 var->width = -1; 705 var->width = -1;
704 var->grayscale = 0; 706 var->grayscale = 0;
705 707
706 if (display && display->get_timings) { 708 if (display && display->driver->get_timings) {
707 struct omap_video_timings timings; 709 struct omap_video_timings timings;
708 display->get_timings(display, &timings); 710 display->driver->get_timings(display, &timings);
709 711
710 /* pixclock in ps, the rest in pixclock */ 712 /* pixclock in ps, the rest in pixclock */
711 var->pixclock = timings.pixel_clock != 0 ? 713 var->pixclock = timings.pixel_clock != 0 ?
@@ -778,8 +780,8 @@ static int omapfb_release(struct fb_info *fbi, int user)
778 return 0; 780 return 0;
779} 781}
780 782
781static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var, 783static unsigned calc_rotation_offset_dma(const struct fb_var_screeninfo *var,
782 struct fb_fix_screeninfo *fix, int rotation) 784 const struct fb_fix_screeninfo *fix, int rotation)
783{ 785{
784 unsigned offset; 786 unsigned offset;
785 787
@@ -789,8 +791,8 @@ static unsigned calc_rotation_offset_dma(struct fb_var_screeninfo *var,
789 return offset; 791 return offset;
790} 792}
791 793
792static unsigned calc_rotation_offset_vrfb(struct fb_var_screeninfo *var, 794static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
793 struct fb_fix_screeninfo *fix, int rotation) 795 const struct fb_fix_screeninfo *fix, int rotation)
794{ 796{
795 unsigned offset; 797 unsigned offset;
796 798
@@ -1221,11 +1223,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1221 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1223 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
1222 goto exit; 1224 goto exit;
1223 1225
1224 if (display->resume) 1226 if (display->driver->resume)
1225 r = display->resume(display); 1227 r = display->driver->resume(display);
1226 1228
1227 if (r == 0 && display->get_update_mode && 1229 if (r == 0 && display->driver->get_update_mode &&
1228 display->get_update_mode(display) == 1230 display->driver->get_update_mode(display) ==
1229 OMAP_DSS_UPDATE_MANUAL) 1231 OMAP_DSS_UPDATE_MANUAL)
1230 do_update = 1; 1232 do_update = 1;
1231 1233
@@ -1240,8 +1242,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1240 if (display->state != OMAP_DSS_DISPLAY_ACTIVE) 1242 if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
1241 goto exit; 1243 goto exit;
1242 1244
1243 if (display->suspend) 1245 if (display->driver->suspend)
1244 r = display->suspend(display); 1246 r = display->driver->suspend(display);
1245 1247
1246 break; 1248 break;
1247 1249
@@ -1252,11 +1254,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1252exit: 1254exit:
1253 omapfb_unlock(fbdev); 1255 omapfb_unlock(fbdev);
1254 1256
1255 if (r == 0 && do_update && display->update) { 1257 if (r == 0 && do_update && display->driver->update) {
1256 u16 w, h; 1258 u16 w, h;
1257 display->get_resolution(display, &w, &h); 1259 display->driver->get_resolution(display, &w, &h);
1258 1260
1259 r = display->update(display, 0, 0, w, h); 1261 r = display->driver->update(display, 0, 0, w, h);
1260 } 1262 }
1261 1263
1262 return r; 1264 return r;
@@ -1404,6 +1406,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1404 unsigned long paddr) 1406 unsigned long paddr)
1405{ 1407{
1406 struct omapfb_info *ofbi = FB2OFB(fbi); 1408 struct omapfb_info *ofbi = FB2OFB(fbi);
1409 struct omapfb2_device *fbdev = ofbi->fbdev;
1407 struct omap_dss_device *display; 1410 struct omap_dss_device *display;
1408 int bytespp; 1411 int bytespp;
1409 1412
@@ -1412,7 +1415,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1412 if (!display) 1415 if (!display)
1413 return 0; 1416 return 0;
1414 1417
1415 switch (display->get_recommended_bpp(display)) { 1418 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1416 case 16: 1419 case 16:
1417 bytespp = 2; 1420 bytespp = 2;
1418 break; 1421 break;
@@ -1427,7 +1430,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
1427 if (!size) { 1430 if (!size) {
1428 u16 w, h; 1431 u16 w, h;
1429 1432
1430 display->get_resolution(display, &w, &h); 1433 display->driver->get_resolution(display, &w, &h);
1431 1434
1432 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1435 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
1433 size = max(omap_vrfb_min_phys_size(w, h, bytespp), 1436 size = max(omap_vrfb_min_phys_size(w, h, bytespp),
@@ -1636,8 +1639,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1636 if (old_size == size && old_type == type) 1639 if (old_size == size && old_type == type)
1637 return 0; 1640 return 0;
1638 1641
1639 if (display && display->sync) 1642 if (display && display->driver->sync)
1640 display->sync(display); 1643 display->driver->sync(display);
1641 1644
1642 omapfb_free_fbmem(fbi); 1645 omapfb_free_fbmem(fbi);
1643 1646
@@ -1745,7 +1748,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1745 u16 w, h; 1748 u16 w, h;
1746 int rotation = (var->rotate + ofbi->rotation[0]) % 4; 1749 int rotation = (var->rotate + ofbi->rotation[0]) % 4;
1747 1750
1748 display->get_resolution(display, &w, &h); 1751 display->driver->get_resolution(display, &w, &h);
1749 1752
1750 if (rotation == FB_ROTATE_CW || 1753 if (rotation == FB_ROTATE_CW ||
1751 rotation == FB_ROTATE_CCW) { 1754 rotation == FB_ROTATE_CCW) {
@@ -1760,7 +1763,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1760 var->yres_virtual = var->yres; 1763 var->yres_virtual = var->yres;
1761 1764
1762 if (!var->bits_per_pixel) { 1765 if (!var->bits_per_pixel) {
1763 switch (display->get_recommended_bpp(display)) { 1766 switch (omapfb_get_recommended_bpp(fbdev, display)) {
1764 case 16: 1767 case 16:
1765 var->bits_per_pixel = 16; 1768 var->bits_per_pixel = 16;
1766 break; 1769 break;
@@ -1828,7 +1831,7 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1828 1831
1829 for (i = 0; i < fbdev->num_displays; i++) { 1832 for (i = 0; i < fbdev->num_displays; i++) {
1830 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) 1833 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
1831 fbdev->displays[i]->disable(fbdev->displays[i]); 1834 fbdev->displays[i]->driver->disable(fbdev->displays[i]);
1832 1835
1833 omap_dss_put_device(fbdev->displays[i]); 1836 omap_dss_put_device(fbdev->displays[i]);
1834 } 1837 }
@@ -2011,7 +2014,8 @@ static int omapfb_mode_to_timings(const char *mode_str,
2011 } 2014 }
2012} 2015}
2013 2016
2014static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) 2017static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2018 struct omap_dss_device *display, char *mode_str)
2015{ 2019{
2016 int r; 2020 int r;
2017 u8 bpp; 2021 u8 bpp;
@@ -2021,20 +2025,37 @@ static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str)
2021 if (r) 2025 if (r)
2022 return r; 2026 return r;
2023 2027
2024 display->panel.recommended_bpp = bpp; 2028 fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display;
2029 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
2030 ++fbdev->num_bpp_overrides;
2025 2031
2026 if (!display->check_timings || !display->set_timings) 2032 if (!display->driver->check_timings || !display->driver->set_timings)
2027 return -EINVAL; 2033 return -EINVAL;
2028 2034
2029 r = display->check_timings(display, &timings); 2035 r = display->driver->check_timings(display, &timings);
2030 if (r) 2036 if (r)
2031 return r; 2037 return r;
2032 2038
2033 display->set_timings(display, &timings); 2039 display->driver->set_timings(display, &timings);
2034 2040
2035 return 0; 2041 return 0;
2036} 2042}
2037 2043
2044static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
2045 struct omap_dss_device *dssdev)
2046{
2047 int i;
2048
2049 BUG_ON(dssdev->driver->get_recommended_bpp == NULL);
2050
2051 for (i = 0; i < fbdev->num_bpp_overrides; ++i) {
2052 if (dssdev == fbdev->bpp_overrides[i].dssdev)
2053 return fbdev->bpp_overrides[i].bpp;
2054 }
2055
2056 return dssdev->driver->get_recommended_bpp(dssdev);
2057}
2058
2038static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) 2059static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2039{ 2060{
2040 char *str, *options, *this_opt; 2061 char *str, *options, *this_opt;
@@ -2073,7 +2094,7 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2073 break; 2094 break;
2074 } 2095 }
2075 2096
2076 r = omapfb_set_def_mode(display, mode_str); 2097 r = omapfb_set_def_mode(fbdev, display, mode_str);
2077 if (r) 2098 if (r)
2078 break; 2099 break;
2079 } 2100 }
@@ -2111,18 +2132,23 @@ static int omapfb_probe(struct platform_device *pdev)
2111 fbdev->dev = &pdev->dev; 2132 fbdev->dev = &pdev->dev;
2112 platform_set_drvdata(pdev, fbdev); 2133 platform_set_drvdata(pdev, fbdev);
2113 2134
2135 r = 0;
2114 fbdev->num_displays = 0; 2136 fbdev->num_displays = 0;
2115 dssdev = NULL; 2137 dssdev = NULL;
2116 for_each_dss_dev(dssdev) { 2138 for_each_dss_dev(dssdev) {
2117 omap_dss_get_device(dssdev); 2139 omap_dss_get_device(dssdev);
2140
2118 if (!dssdev->driver) { 2141 if (!dssdev->driver) {
2119 dev_err(&pdev->dev, "no driver for display\n"); 2142 dev_err(&pdev->dev, "no driver for display\n");
2120 r = -EINVAL; 2143 r = -ENODEV;
2121 goto cleanup;
2122 } 2144 }
2145
2123 fbdev->displays[fbdev->num_displays++] = dssdev; 2146 fbdev->displays[fbdev->num_displays++] = dssdev;
2124 } 2147 }
2125 2148
2149 if (r)
2150 goto cleanup;
2151
2126 if (fbdev->num_displays == 0) { 2152 if (fbdev->num_displays == 0) {
2127 dev_err(&pdev->dev, "no displays\n"); 2153 dev_err(&pdev->dev, "no displays\n");
2128 r = -EINVAL; 2154 r = -EINVAL;
@@ -2167,35 +2193,28 @@ static int omapfb_probe(struct platform_device *pdev)
2167 } 2193 }
2168 2194
2169 if (def_display) { 2195 if (def_display) {
2170#ifndef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE 2196 struct omap_dss_driver *dssdrv = def_display->driver;
2171 u16 w, h; 2197
2172#endif 2198 r = def_display->driver->enable(def_display);
2173 r = def_display->enable(def_display); 2199 if (r) {
2174 if (r)
2175 dev_warn(fbdev->dev, "Failed to enable display '%s'\n", 2200 dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
2176 def_display->name); 2201 def_display->name);
2202 goto cleanup;
2203 }
2177 2204
2178 /* set the update mode */
2179 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 2205 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2180#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE 2206 u16 w, h;
2181 if (def_display->enable_te) 2207 if (dssdrv->enable_te)
2182 def_display->enable_te(def_display, 1); 2208 dssdrv->enable_te(def_display, 1);
2183 if (def_display->set_update_mode) 2209 if (dssdrv->set_update_mode)
2184 def_display->set_update_mode(def_display, 2210 dssdrv->set_update_mode(def_display,
2185 OMAP_DSS_UPDATE_AUTO);
2186#else /* MANUAL_UPDATE */
2187 if (def_display->enable_te)
2188 def_display->enable_te(def_display, 0);
2189 if (def_display->set_update_mode)
2190 def_display->set_update_mode(def_display,
2191 OMAP_DSS_UPDATE_MANUAL); 2211 OMAP_DSS_UPDATE_MANUAL);
2192 2212
2193 def_display->get_resolution(def_display, &w, &h); 2213 dssdrv->get_resolution(def_display, &w, &h);
2194 def_display->update(def_display, 0, 0, w, h); 2214 def_display->driver->update(def_display, 0, 0, w, h);
2195#endif
2196 } else { 2215 } else {
2197 if (def_display->set_update_mode) 2216 if (dssdrv->set_update_mode)
2198 def_display->set_update_mode(def_display, 2217 dssdrv->set_update_mode(def_display,
2199 OMAP_DSS_UPDATE_AUTO); 2218 OMAP_DSS_UPDATE_AUTO);
2200 } 2219 }
2201 } 2220 }
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index f7c9c739e5ef..cd54fdbfd8bb 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -83,6 +83,12 @@ struct omapfb2_device {
83 struct omap_overlay *overlays[10]; 83 struct omap_overlay *overlays[10];
84 unsigned num_managers; 84 unsigned num_managers;
85 struct omap_overlay_manager *managers[10]; 85 struct omap_overlay_manager *managers[10];
86
87 unsigned num_bpp_overrides;
88 struct {
89 struct omap_dss_device *dssdev;
90 u8 bpp;
91 } bpp_overrides[10];
86}; 92};
87 93
88struct omapfb_colormode { 94struct omapfb_colormode {
@@ -105,6 +111,9 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
105 111
106int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg); 112int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
107 113
114int omapfb_update_window(struct fb_info *fbi,
115 u32 x, u32 y, u32 w, u32 h);
116
108int dss_mode_to_fb_mode(enum omap_color_mode dssmode, 117int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
109 struct fb_var_screeninfo *var); 118 struct fb_var_screeninfo *var);
110 119
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 5b0d997f23ef..e2ea0b2159cd 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -126,6 +126,7 @@ header-y += nfs2.h
126header-y += nfs4_mount.h 126header-y += nfs4_mount.h
127header-y += nfs_mount.h 127header-y += nfs_mount.h
128header-y += nl80211.h 128header-y += nl80211.h
129header-y += omapfb.h
129header-y += param.h 130header-y += param.h
130header-y += pci_regs.h 131header-y += pci_regs.h
131header-y += perf_event.h 132header-y += perf_event.h
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index f46c40ac6d45..9bdd91486b49 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -57,6 +57,7 @@
57#define OMAPFB_WAITFORGO OMAP_IO(60) 57#define OMAPFB_WAITFORGO OMAP_IO(60)
58#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info) 58#define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info)
59#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info) 59#define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info)
60#define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info)
60 61
61#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff 62#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
62#define OMAPFB_CAPS_LCDC_MASK 0x00fff000 63#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
@@ -206,6 +207,14 @@ struct omapfb_tearsync_info {
206 __u16 reserved2; 207 __u16 reserved2;
207}; 208};
208 209
210struct omapfb_display_info {
211 __u16 xres;
212 __u16 yres;
213 __u32 width; /* phys width of the display in micrometers */
214 __u32 height; /* phys height of the display in micrometers */
215 __u32 reserved[5];
216};
217
209#ifdef __KERNEL__ 218#ifdef __KERNEL__
210 219
211#include <plat/board.h> 220#include <plat/board.h>