aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-10 02:18:03 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-10 02:18:08 -0400
commit6cd05430eeab0668c55ff4693ab79ff559b2b5c7 (patch)
tree47f6de06e649c2fefaddf85c681a0d7e33b2a07a
parentc50e86ce7c2961a41f2f7aa6e4fd6c99229ba205 (diff)
parentb2f5976c109350977104f27211a7029ec67cd488 (diff)
Merge miscellaneous omapdss changes
Most important changes: * Remove OMAP4 HDMI gpio handling from board files * Add vdda_hdmi_dac supply for HDMI to twl-common.c * Calculate DSI clocks dynamically * Remove DSS clock dividers from 4430sdp board file * vram.c no longer uses OMAP's sDMA to clear the memory * Fifomerge has been reverted * Swap GFX and WB fifos to avoid underflows
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c73
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c27
-rw-r--r--arch/arm/mach-omap2/twl-common.c6
-rw-r--r--drivers/video/omap/hwa742.c1
-rw-r--r--drivers/video/omap/lcd_ams_delta.c1
-rw-r--r--drivers/video/omap/lcd_palmte.c1
-rw-r--r--drivers/video/omap/omapfb_main.c9
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c1
-rw-r--r--drivers/video/omap2/displays/panel-taal.c223
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c14
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/apply.c236
-rw-r--r--drivers/video/omap2/dss/dispc.c68
-rw-r--r--drivers/video/omap2/dss/dispc.h4
-rw-r--r--drivers/video/omap2/dss/display.c4
-rw-r--r--drivers/video/omap2/dss/dpi.c15
-rw-r--r--drivers/video/omap2/dss/dsi.c132
-rw-r--r--drivers/video/omap2/dss/dss.c1
-rw-r--r--drivers/video/omap2/dss/dss.h7
-rw-r--r--drivers/video/omap2/dss/dss_features.c2
-rw-r--r--drivers/video/omap2/dss/dss_features.h1
-rw-r--r--drivers/video/omap2/dss/hdmi.c113
-rw-r--r--drivers/video/omap2/dss/manager-sysfs.c499
-rw-r--r--drivers/video/omap2/dss/manager.c462
-rw-r--r--drivers/video/omap2/dss/overlay-sysfs.c456
-rw-r--r--drivers/video/omap2/dss/overlay.c421
-rw-r--r--drivers/video/omap2/dss/rfbi.c1
-rw-r--r--drivers/video/omap2/dss/sdi.c10
-rw-r--r--drivers/video/omap2/dss/venc.c14
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c26
-rw-r--r--drivers/video/omap2/vram.c56
-rw-r--r--include/video/omapdss.h5
32 files changed, 1424 insertions, 1467 deletions
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index ad8a7d94afcd..c165e20506c9 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -601,29 +601,6 @@ static void __init omap_sfh7741prox_init(void)
601 __func__, OMAP4_SFH7741_ENABLE_GPIO, error); 601 __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
602} 602}
603 603
604static struct gpio sdp4430_hdmi_gpios[] = {
605 { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
606 { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
607 { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
608};
609
610static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
611{
612 int status;
613
614 status = gpio_request_array(sdp4430_hdmi_gpios,
615 ARRAY_SIZE(sdp4430_hdmi_gpios));
616 if (status)
617 pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
618
619 return status;
620}
621
622static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
623{
624 gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
625}
626
627static struct nokia_dsi_panel_data dsi1_panel = { 604static struct nokia_dsi_panel_data dsi1_panel = {
628 .name = "taal", 605 .name = "taal",
629 .reset_gpio = 102, 606 .reset_gpio = 102,
@@ -644,29 +621,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
644 .phy.dsi = { 621 .phy.dsi = {
645 .module = 0, 622 .module = 0,
646 }, 623 },
647
648 .clocks = {
649 .dispc = {
650 .channel = {
651 /* Logic Clock = 172.8 MHz */
652 .lck_div = 1,
653 /* Pixel Clock = 34.56 MHz */
654 .pck_div = 5,
655 .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
656 },
657 .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
658 },
659
660 .dsi = {
661 .regn = 16, /* Fint = 2.4 MHz */
662 .regm = 180, /* DDR Clock = 216 MHz */
663 .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
664 .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
665
666 .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
667 .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
668 },
669 },
670 .channel = OMAP_DSS_CHANNEL_LCD, 624 .channel = OMAP_DSS_CHANNEL_LCD,
671}; 625};
672 626
@@ -691,33 +645,12 @@ static struct omap_dss_device sdp4430_lcd2_device = {
691 645
692 .module = 1, 646 .module = 1,
693 }, 647 },
694
695 .clocks = {
696 .dispc = {
697 .channel = {
698 /* Logic Clock = 172.8 MHz */
699 .lck_div = 1,
700 /* Pixel Clock = 34.56 MHz */
701 .pck_div = 5,
702 .lcd_clk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
703 },
704 .dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK,
705 },
706
707 .dsi = {
708 .regn = 16, /* Fint = 2.4 MHz */
709 .regm = 180, /* DDR Clock = 216 MHz */
710 .regm_dispc = 5, /* PLL1_CLK1 = 172.8 MHz */
711 .regm_dsi = 5, /* PLL1_CLK2 = 172.8 MHz */
712
713 .lp_clk_div = 10, /* LP Clock = 8.64 MHz */
714 .dsi_fclk_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
715 },
716 },
717 .channel = OMAP_DSS_CHANNEL_LCD2, 648 .channel = OMAP_DSS_CHANNEL_LCD2,
718}; 649};
719 650
720static struct omap_dss_hdmi_data sdp4430_hdmi_data = { 651static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
652 .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
653 .ls_oe_gpio = HDMI_GPIO_LS_OE,
721 .hpd_gpio = HDMI_GPIO_HPD, 654 .hpd_gpio = HDMI_GPIO_HPD,
722}; 655};
723 656
@@ -725,8 +658,6 @@ static struct omap_dss_device sdp4430_hdmi_device = {
725 .name = "hdmi", 658 .name = "hdmi",
726 .driver_name = "hdmi_panel", 659 .driver_name = "hdmi_panel",
727 .type = OMAP_DISPLAY_TYPE_HDMI, 660 .type = OMAP_DISPLAY_TYPE_HDMI,
728 .platform_enable = sdp4430_panel_enable_hdmi,
729 .platform_disable = sdp4430_panel_disable_hdmi,
730 .channel = OMAP_DSS_CHANNEL_DIGIT, 661 .channel = OMAP_DSS_CHANNEL_DIGIT,
731 .data = &sdp4430_hdmi_data, 662 .data = &sdp4430_hdmi_data,
732}; 663};
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 70f6d1d25463..cd4852e5ca57 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -408,30 +408,9 @@ static struct omap_dss_device omap4_panda_dvi_device = {
408 .channel = OMAP_DSS_CHANNEL_LCD2, 408 .channel = OMAP_DSS_CHANNEL_LCD2,
409}; 409};
410 410
411static struct gpio panda_hdmi_gpios[] = {
412 { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
413 { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
414 { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
415};
416
417static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
418{
419 int status;
420
421 status = gpio_request_array(panda_hdmi_gpios,
422 ARRAY_SIZE(panda_hdmi_gpios));
423 if (status)
424 pr_err("Cannot request HDMI GPIOs\n");
425
426 return status;
427}
428
429static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
430{
431 gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
432}
433
434static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { 411static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
412 .ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
413 .ls_oe_gpio = HDMI_GPIO_LS_OE,
435 .hpd_gpio = HDMI_GPIO_HPD, 414 .hpd_gpio = HDMI_GPIO_HPD,
436}; 415};
437 416
@@ -439,8 +418,6 @@ static struct omap_dss_device omap4_panda_hdmi_device = {
439 .name = "hdmi", 418 .name = "hdmi",
440 .driver_name = "hdmi_panel", 419 .driver_name = "hdmi_panel",
441 .type = OMAP_DISPLAY_TYPE_HDMI, 420 .type = OMAP_DISPLAY_TYPE_HDMI,
442 .platform_enable = omap4_panda_panel_enable_hdmi,
443 .platform_disable = omap4_panda_panel_disable_hdmi,
444 .channel = OMAP_DSS_CHANNEL_DIGIT, 421 .channel = OMAP_DSS_CHANNEL_DIGIT,
445 .data = &omap4_panda_hdmi_data, 422 .data = &omap4_panda_hdmi_data,
446}; 423};
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index db5ff6642375..9bf8a89e78c6 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -258,6 +258,10 @@ static struct twl4030_usb_data omap4_usb_pdata = {
258 .phy_suspend = omap4430_phy_suspend, 258 .phy_suspend = omap4430_phy_suspend,
259}; 259};
260 260
261static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
262 REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
263};
264
261static struct regulator_init_data omap4_vdac_idata = { 265static struct regulator_init_data omap4_vdac_idata = {
262 .constraints = { 266 .constraints = {
263 .min_uV = 1800000, 267 .min_uV = 1800000,
@@ -267,6 +271,8 @@ static struct regulator_init_data omap4_vdac_idata = {
267 .valid_ops_mask = REGULATOR_CHANGE_MODE 271 .valid_ops_mask = REGULATOR_CHANGE_MODE
268 | REGULATOR_CHANGE_STATUS, 272 | REGULATOR_CHANGE_STATUS,
269 }, 273 },
274 .num_consumer_supplies = ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
275 .consumer_supplies = omap4_vdda_hdmi_dac_supplies,
270 .supply_regulator = "V2V1", 276 .supply_regulator = "V2V1",
271}; 277};
272 278
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 9f1d23c319cb..f349ee6f0cea 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -27,7 +27,6 @@
27#include <linux/clk.h> 27#include <linux/clk.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29 29
30#include <plat/dma.h>
31#include "omapfb.h" 30#include "omapfb.h"
32 31
33#define HWA742_REV_CODE_REG 0x0 32#define HWA742_REV_CODE_REG 0x0
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index d3a311327227..5cca6b373af7 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -28,7 +28,6 @@
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29 29
30#include <plat/board-ams-delta.h> 30#include <plat/board-ams-delta.h>
31#include <mach/hardware.h>
32 31
33#include "omapfb.h" 32#include "omapfb.h"
34 33
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 88c31eb0cd6c..ff4fb624b904 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -23,7 +23,6 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/io.h> 24#include <linux/io.h>
25 25
26#include <plat/fpga.h>
27#include "omapfb.h" 26#include "omapfb.h"
28 27
29static int palmte_panel_init(struct lcd_panel *panel, 28static int palmte_panel_init(struct lcd_panel *panel,
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index f54b463709e9..4351c438b76f 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -131,15 +131,6 @@ static void omapfb_rqueue_unlock(struct omapfb_device *fbdev)
131 * LCD controller and LCD DMA 131 * LCD controller and LCD DMA
132 * --------------------------------------------------------------------------- 132 * ---------------------------------------------------------------------------
133 */ 133 */
134/* Lookup table to map elem size to elem type. */
135static const int dma_elem_type[] = {
136 0,
137 OMAP_DMA_DATA_TYPE_S8,
138 OMAP_DMA_DATA_TYPE_S16,
139 0,
140 OMAP_DMA_DATA_TYPE_S32,
141};
142
143/* 134/*
144 * Allocate resources needed for LCD controller and LCD DMA operations. Video 135 * Allocate resources needed for LCD controller and LCD DMA operations. Video
145 * memory is allocated from system memory according to the virtual display 136 * memory is allocated from system memory according to the virtual display
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 17ae85e0033f..3fc5ad081a21 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -489,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
489 dssdev->panel.timings.y_res = 480; 489 dssdev->panel.timings.y_res = 480;
490 dssdev->ctrl.pixel_size = 16; 490 dssdev->ctrl.pixel_size = 16;
491 dssdev->ctrl.rfbi_timings = n8x0_panel_timings; 491 dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
492 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
492 493
493 memset(&props, 0, sizeof(props)); 494 memset(&props, 0, sizeof(props));
494 props.max_brightness = 127; 495 props.max_brightness = 127;
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 77aed0e51f9b..4cf94161ff51 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -121,6 +121,18 @@ struct taal_data {
121 121
122 struct omap_dss_device *dssdev; 122 struct omap_dss_device *dssdev;
123 123
124 /* panel specific HW info */
125 struct panel_config *panel_config;
126
127 /* panel HW configuration from DT or platform data */
128 int reset_gpio;
129 int ext_te_gpio;
130
131 bool use_dsi_backlight;
132
133 struct omap_dsi_pin_config pin_config;
134
135 /* runtime variables */
124 bool enabled; 136 bool enabled;
125 u8 rotate; 137 u8 rotate;
126 bool mirror; 138 bool mirror;
@@ -145,16 +157,8 @@ struct taal_data {
145 bool ulps_enabled; 157 bool ulps_enabled;
146 unsigned ulps_timeout; 158 unsigned ulps_timeout;
147 struct delayed_work ulps_work; 159 struct delayed_work ulps_work;
148
149 struct panel_config *panel_config;
150}; 160};
151 161
152static inline struct nokia_dsi_panel_data
153*get_panel_data(const struct omap_dss_device *dssdev)
154{
155 return (struct nokia_dsi_panel_data *) dssdev->data;
156}
157
158static void taal_esd_work(struct work_struct *work); 162static void taal_esd_work(struct work_struct *work);
159static void taal_ulps_work(struct work_struct *work); 163static void taal_ulps_work(struct work_struct *work);
160 164
@@ -371,7 +375,6 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
371static int taal_enter_ulps(struct omap_dss_device *dssdev) 375static int taal_enter_ulps(struct omap_dss_device *dssdev)
372{ 376{
373 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 377 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
374 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
375 int r; 378 int r;
376 379
377 if (td->ulps_enabled) 380 if (td->ulps_enabled)
@@ -383,7 +386,8 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
383 if (r) 386 if (r)
384 goto err; 387 goto err;
385 388
386 disable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 389 if (gpio_is_valid(td->ext_te_gpio))
390 disable_irq(gpio_to_irq(td->ext_te_gpio));
387 391
388 omapdss_dsi_display_disable(dssdev, false, true); 392 omapdss_dsi_display_disable(dssdev, false, true);
389 393
@@ -405,7 +409,6 @@ err:
405static int taal_exit_ulps(struct omap_dss_device *dssdev) 409static int taal_exit_ulps(struct omap_dss_device *dssdev)
406{ 410{
407 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 411 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
408 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
409 int r; 412 int r;
410 413
411 if (!td->ulps_enabled) 414 if (!td->ulps_enabled)
@@ -425,7 +428,8 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
425 goto err2; 428 goto err2;
426 } 429 }
427 430
428 enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 431 if (gpio_is_valid(td->ext_te_gpio))
432 enable_irq(gpio_to_irq(td->ext_te_gpio));
429 433
430 taal_queue_ulps_work(dssdev); 434 taal_queue_ulps_work(dssdev);
431 435
@@ -438,7 +442,8 @@ err2:
438 442
439 r = taal_panel_reset(dssdev); 443 r = taal_panel_reset(dssdev);
440 if (!r) { 444 if (!r) {
441 enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 445 if (gpio_is_valid(td->ext_te_gpio))
446 enable_irq(gpio_to_irq(td->ext_te_gpio));
442 td->ulps_enabled = false; 447 td->ulps_enabled = false;
443 } 448 }
444err1: 449err1:
@@ -835,94 +840,135 @@ static struct attribute_group taal_attr_group = {
835static void taal_hw_reset(struct omap_dss_device *dssdev) 840static void taal_hw_reset(struct omap_dss_device *dssdev)
836{ 841{
837 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 842 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
838 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
839 843
840 if (panel_data->reset_gpio == -1) 844 if (!gpio_is_valid(td->reset_gpio))
841 return; 845 return;
842 846
843 gpio_set_value(panel_data->reset_gpio, 1); 847 gpio_set_value(td->reset_gpio, 1);
844 if (td->panel_config->reset_sequence.high) 848 if (td->panel_config->reset_sequence.high)
845 udelay(td->panel_config->reset_sequence.high); 849 udelay(td->panel_config->reset_sequence.high);
846 /* reset the panel */ 850 /* reset the panel */
847 gpio_set_value(panel_data->reset_gpio, 0); 851 gpio_set_value(td->reset_gpio, 0);
848 /* assert reset */ 852 /* assert reset */
849 if (td->panel_config->reset_sequence.low) 853 if (td->panel_config->reset_sequence.low)
850 udelay(td->panel_config->reset_sequence.low); 854 udelay(td->panel_config->reset_sequence.low);
851 gpio_set_value(panel_data->reset_gpio, 1); 855 gpio_set_value(td->reset_gpio, 1);
852 /* wait after releasing reset */ 856 /* wait after releasing reset */
853 if (td->panel_config->sleep.hw_reset) 857 if (td->panel_config->sleep.hw_reset)
854 msleep(td->panel_config->sleep.hw_reset); 858 msleep(td->panel_config->sleep.hw_reset);
855} 859}
856 860
861static void taal_probe_pdata(struct taal_data *td,
862 const struct nokia_dsi_panel_data *pdata)
863{
864 td->reset_gpio = pdata->reset_gpio;
865
866 if (pdata->use_ext_te)
867 td->ext_te_gpio = pdata->ext_te_gpio;
868 else
869 td->ext_te_gpio = -1;
870
871 td->esd_interval = pdata->esd_interval;
872 td->ulps_timeout = pdata->ulps_timeout;
873
874 td->use_dsi_backlight = pdata->use_dsi_backlight;
875
876 td->pin_config = pdata->pin_config;
877}
878
857static int taal_probe(struct omap_dss_device *dssdev) 879static int taal_probe(struct omap_dss_device *dssdev)
858{ 880{
859 struct backlight_properties props; 881 struct backlight_properties props;
860 struct taal_data *td; 882 struct taal_data *td;
861 struct backlight_device *bldev = NULL; 883 struct backlight_device *bldev = NULL;
862 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
863 struct panel_config *panel_config = NULL;
864 int r, i; 884 int r, i;
885 const char *panel_name;
865 886
866 dev_dbg(&dssdev->dev, "probe\n"); 887 dev_dbg(&dssdev->dev, "probe\n");
867 888
868 if (!panel_data || !panel_data->name) { 889 td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
869 r = -EINVAL; 890 if (!td)
870 goto err; 891 return -ENOMEM;
892
893 dev_set_drvdata(&dssdev->dev, td);
894 td->dssdev = dssdev;
895
896 if (dssdev->data) {
897 const struct nokia_dsi_panel_data *pdata = dssdev->data;
898
899 taal_probe_pdata(td, pdata);
900
901 panel_name = pdata->name;
902 } else {
903 return -ENODEV;
871 } 904 }
872 905
906 if (panel_name == NULL)
907 return -EINVAL;
908
873 for (i = 0; i < ARRAY_SIZE(panel_configs); i++) { 909 for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
874 if (strcmp(panel_data->name, panel_configs[i].name) == 0) { 910 if (strcmp(panel_name, panel_configs[i].name) == 0) {
875 panel_config = &panel_configs[i]; 911 td->panel_config = &panel_configs[i];
876 break; 912 break;
877 } 913 }
878 } 914 }
879 915
880 if (!panel_config) { 916 if (!td->panel_config)
881 r = -EINVAL; 917 return -EINVAL;
882 goto err;
883 }
884 918
885 dssdev->panel.timings = panel_config->timings; 919 dssdev->panel.timings = td->panel_config->timings;
886 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; 920 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
887 921 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
888 td = kzalloc(sizeof(*td), GFP_KERNEL); 922 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
889 if (!td) {
890 r = -ENOMEM;
891 goto err;
892 }
893 td->dssdev = dssdev;
894 td->panel_config = panel_config;
895 td->esd_interval = panel_data->esd_interval;
896 td->ulps_enabled = false;
897 td->ulps_timeout = panel_data->ulps_timeout;
898 923
899 mutex_init(&td->lock); 924 mutex_init(&td->lock);
900 925
901 atomic_set(&td->do_update, 0); 926 atomic_set(&td->do_update, 0);
902 927
903 td->workqueue = create_singlethread_workqueue("taal_esd"); 928 if (gpio_is_valid(td->reset_gpio)) {
904 if (td->workqueue == NULL) { 929 r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
905 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 930 GPIOF_OUT_INIT_LOW, "taal rst");
906 r = -ENOMEM; 931 if (r) {
907 goto err_wq; 932 dev_err(&dssdev->dev, "failed to request reset gpio\n");
933 return r;
934 }
908 } 935 }
909 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
910 INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
911 936
912 dev_set_drvdata(&dssdev->dev, td); 937 if (gpio_is_valid(td->ext_te_gpio)) {
938 r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
939 GPIOF_IN, "taal irq");
940 if (r) {
941 dev_err(&dssdev->dev, "GPIO request failed\n");
942 return r;
943 }
944
945 r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
946 taal_te_isr,
947 IRQF_TRIGGER_RISING,
948 "taal vsync", dssdev);
913 949
914 if (gpio_is_valid(panel_data->reset_gpio)) {
915 r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
916 "taal rst");
917 if (r) { 950 if (r) {
918 dev_err(&dssdev->dev, "failed to request reset gpio\n"); 951 dev_err(&dssdev->dev, "IRQ request failed\n");
919 goto err_rst_gpio; 952 return r;
920 } 953 }
954
955 INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
956 taal_te_timeout_work_callback);
957
958 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
959 }
960
961 td->workqueue = create_singlethread_workqueue("taal_esd");
962 if (td->workqueue == NULL) {
963 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
964 return -ENOMEM;
921 } 965 }
966 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
967 INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
922 968
923 taal_hw_reset(dssdev); 969 taal_hw_reset(dssdev);
924 970
925 if (panel_data->use_dsi_backlight) { 971 if (td->use_dsi_backlight) {
926 memset(&props, 0, sizeof(struct backlight_properties)); 972 memset(&props, 0, sizeof(struct backlight_properties));
927 props.max_brightness = 255; 973 props.max_brightness = 255;
928 974
@@ -943,31 +989,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
943 taal_bl_update_status(bldev); 989 taal_bl_update_status(bldev);
944 } 990 }
945 991
946 if (panel_data->use_ext_te) {
947 int gpio = panel_data->ext_te_gpio;
948
949 r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
950 if (r) {
951 dev_err(&dssdev->dev, "GPIO request failed\n");
952 goto err_gpio;
953 }
954
955 r = request_irq(gpio_to_irq(gpio), taal_te_isr,
956 IRQF_TRIGGER_RISING,
957 "taal vsync", dssdev);
958
959 if (r) {
960 dev_err(&dssdev->dev, "IRQ request failed\n");
961 gpio_free(gpio);
962 goto err_irq;
963 }
964
965 INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
966 taal_te_timeout_work_callback);
967
968 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
969 }
970
971 r = omap_dsi_request_vc(dssdev, &td->channel); 992 r = omap_dsi_request_vc(dssdev, &td->channel);
972 if (r) { 993 if (r) {
973 dev_err(&dssdev->dev, "failed to get virtual channel\n"); 994 dev_err(&dssdev->dev, "failed to get virtual channel\n");
@@ -991,29 +1012,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
991err_vc_id: 1012err_vc_id:
992 omap_dsi_release_vc(dssdev, td->channel); 1013 omap_dsi_release_vc(dssdev, td->channel);
993err_req_vc: 1014err_req_vc:
994 if (panel_data->use_ext_te)
995 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
996err_irq:
997 if (panel_data->use_ext_te)
998 gpio_free(panel_data->ext_te_gpio);
999err_gpio:
1000 if (bldev != NULL) 1015 if (bldev != NULL)
1001 backlight_device_unregister(bldev); 1016 backlight_device_unregister(bldev);
1002err_bl: 1017err_bl:
1003 if (gpio_is_valid(panel_data->reset_gpio))
1004 gpio_free(panel_data->reset_gpio);
1005err_rst_gpio:
1006 destroy_workqueue(td->workqueue); 1018 destroy_workqueue(td->workqueue);
1007err_wq:
1008 kfree(td);
1009err:
1010 return r; 1019 return r;
1011} 1020}
1012 1021
1013static void __exit taal_remove(struct omap_dss_device *dssdev) 1022static void __exit taal_remove(struct omap_dss_device *dssdev)
1014{ 1023{
1015 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1024 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1016 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1017 struct backlight_device *bldev; 1025 struct backlight_device *bldev;
1018 1026
1019 dev_dbg(&dssdev->dev, "remove\n"); 1027 dev_dbg(&dssdev->dev, "remove\n");
@@ -1021,12 +1029,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
1021 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 1029 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
1022 omap_dsi_release_vc(dssdev, td->channel); 1030 omap_dsi_release_vc(dssdev, td->channel);
1023 1031
1024 if (panel_data->use_ext_te) {
1025 int gpio = panel_data->ext_te_gpio;
1026 free_irq(gpio_to_irq(gpio), dssdev);
1027 gpio_free(gpio);
1028 }
1029
1030 bldev = td->bldev; 1032 bldev = td->bldev;
1031 if (bldev != NULL) { 1033 if (bldev != NULL) {
1032 bldev->props.power = FB_BLANK_POWERDOWN; 1034 bldev->props.power = FB_BLANK_POWERDOWN;
@@ -1040,21 +1042,15 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
1040 1042
1041 /* reset, to be sure that the panel is in a valid state */ 1043 /* reset, to be sure that the panel is in a valid state */
1042 taal_hw_reset(dssdev); 1044 taal_hw_reset(dssdev);
1043
1044 if (gpio_is_valid(panel_data->reset_gpio))
1045 gpio_free(panel_data->reset_gpio);
1046
1047 kfree(td);
1048} 1045}
1049 1046
1050static int taal_power_on(struct omap_dss_device *dssdev) 1047static int taal_power_on(struct omap_dss_device *dssdev)
1051{ 1048{
1052 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1049 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1053 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1054 u8 id1, id2, id3; 1050 u8 id1, id2, id3;
1055 int r; 1051 int r;
1056 1052
1057 r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config); 1053 r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
1058 if (r) { 1054 if (r) {
1059 dev_err(&dssdev->dev, "failed to configure DSI pins\n"); 1055 dev_err(&dssdev->dev, "failed to configure DSI pins\n");
1060 goto err0; 1056 goto err0;
@@ -1065,6 +1061,12 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1065 omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888); 1061 omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
1066 omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE); 1062 omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
1067 1063
1064 r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
1065 if (r) {
1066 dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
1067 goto err0;
1068 }
1069
1068 r = omapdss_dsi_display_enable(dssdev); 1070 r = omapdss_dsi_display_enable(dssdev);
1069 if (r) { 1071 if (r) {
1070 dev_err(&dssdev->dev, "failed to enable DSI\n"); 1072 dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -1361,7 +1363,6 @@ static int taal_update(struct omap_dss_device *dssdev,
1361 u16 x, u16 y, u16 w, u16 h) 1363 u16 x, u16 y, u16 w, u16 h)
1362{ 1364{
1363 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1365 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1364 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1365 int r; 1366 int r;
1366 1367
1367 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); 1368 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -1385,7 +1386,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1385 if (r) 1386 if (r)
1386 goto err; 1387 goto err;
1387 1388
1388 if (td->te_enabled && panel_data->use_ext_te) { 1389 if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
1389 schedule_delayed_work(&td->te_timeout_work, 1390 schedule_delayed_work(&td->te_timeout_work,
1390 msecs_to_jiffies(250)); 1391 msecs_to_jiffies(250));
1391 atomic_set(&td->do_update, 1); 1392 atomic_set(&td->do_update, 1);
@@ -1424,7 +1425,6 @@ static int taal_sync(struct omap_dss_device *dssdev)
1424static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) 1425static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1425{ 1426{
1426 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1427 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1427 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1428 int r; 1428 int r;
1429 1429
1430 if (enable) 1430 if (enable)
@@ -1432,7 +1432,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1432 else 1432 else
1433 r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF); 1433 r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
1434 1434
1435 if (!panel_data->use_ext_te) 1435 if (!gpio_is_valid(td->ext_te_gpio))
1436 omapdss_dsi_enable_te(dssdev, enable); 1436 omapdss_dsi_enable_te(dssdev, enable);
1437 1437
1438 if (td->panel_config->sleep.enable_te) 1438 if (td->panel_config->sleep.enable_te)
@@ -1742,7 +1742,6 @@ static void taal_esd_work(struct work_struct *work)
1742 struct taal_data *td = container_of(work, struct taal_data, 1742 struct taal_data *td = container_of(work, struct taal_data,
1743 esd_work.work); 1743 esd_work.work);
1744 struct omap_dss_device *dssdev = td->dssdev; 1744 struct omap_dss_device *dssdev = td->dssdev;
1745 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1746 u8 state1, state2; 1745 u8 state1, state2;
1747 int r; 1746 int r;
1748 1747
@@ -1789,7 +1788,7 @@ static void taal_esd_work(struct work_struct *work)
1789 } 1788 }
1790 /* Self-diagnostics result is also shown on TE GPIO line. We need 1789 /* Self-diagnostics result is also shown on TE GPIO line. We need
1791 * to re-enable TE after self diagnostics */ 1790 * to re-enable TE after self diagnostics */
1792 if (td->te_enabled && panel_data->use_ext_te) { 1791 if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
1793 r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); 1792 r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1794 if (r) 1793 if (r)
1795 goto err; 1794 goto err;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 4be9a59664d5..383811cf8648 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -119,8 +119,8 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
119 } 119 }
120 120
121 if (gpio_is_valid(ddata->pd_gpio)) { 121 if (gpio_is_valid(ddata->pd_gpio)) {
122 r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, 122 r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio,
123 "tfp410 pd"); 123 GPIOF_OUT_INIT_LOW, "tfp410 pd");
124 if (r) { 124 if (r) {
125 dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", 125 dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
126 ddata->pd_gpio); 126 ddata->pd_gpio);
@@ -135,8 +135,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
135 if (!adapter) { 135 if (!adapter) {
136 dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n", 136 dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
137 i2c_bus_num); 137 i2c_bus_num);
138 r = -EINVAL; 138 return -EINVAL;
139 goto err_i2c;
140 } 139 }
141 140
142 ddata->i2c_adapter = adapter; 141 ddata->i2c_adapter = adapter;
@@ -145,10 +144,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
145 dev_set_drvdata(&dssdev->dev, ddata); 144 dev_set_drvdata(&dssdev->dev, ddata);
146 145
147 return 0; 146 return 0;
148err_i2c:
149 if (gpio_is_valid(ddata->pd_gpio))
150 gpio_free(ddata->pd_gpio);
151 return r;
152} 147}
153 148
154static void __exit tfp410_remove(struct omap_dss_device *dssdev) 149static void __exit tfp410_remove(struct omap_dss_device *dssdev)
@@ -160,9 +155,6 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev)
160 if (ddata->i2c_adapter) 155 if (ddata->i2c_adapter)
161 i2c_put_adapter(ddata->i2c_adapter); 156 i2c_put_adapter(ddata->i2c_adapter);
162 157
163 if (gpio_is_valid(ddata->pd_gpio))
164 gpio_free(ddata->pd_gpio);
165
166 dev_set_drvdata(&dssdev->dev, NULL); 158 dev_set_drvdata(&dssdev->dev, NULL);
167 159
168 mutex_unlock(&ddata->lock); 160 mutex_unlock(&ddata->lock);
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fba75b0..00a6eb566bb6 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
1obj-$(CONFIG_OMAP2_DSS) += omapdss.o 1obj-$(CONFIG_OMAP2_DSS) += omapdss.o
2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 2omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
3 manager.o overlay.o apply.o 3 manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o
4omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 4omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
5omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o 5omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
6omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o 6omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 52a5940a3773..6354bb842856 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -111,9 +111,6 @@ static struct {
111 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; 111 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
112 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; 112 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
113 113
114 bool fifo_merge_dirty;
115 bool fifo_merge;
116
117 bool irq_enabled; 114 bool irq_enabled;
118} dss_data; 115} dss_data;
119 116
@@ -677,40 +674,11 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
677 mp->shadow_extra_info_dirty = true; 674 mp->shadow_extra_info_dirty = true;
678} 675}
679 676
680static void dss_write_regs_common(void)
681{
682 const int num_mgrs = omap_dss_get_num_overlay_managers();
683 int i;
684
685 if (!dss_data.fifo_merge_dirty)
686 return;
687
688 for (i = 0; i < num_mgrs; ++i) {
689 struct omap_overlay_manager *mgr;
690 struct mgr_priv_data *mp;
691
692 mgr = omap_dss_get_overlay_manager(i);
693 mp = get_mgr_priv(mgr);
694
695 if (mp->enabled) {
696 if (dss_data.fifo_merge_dirty) {
697 dispc_enable_fifomerge(dss_data.fifo_merge);
698 dss_data.fifo_merge_dirty = false;
699 }
700
701 if (mp->updating)
702 mp->shadow_info_dirty = true;
703 }
704 }
705}
706
707static void dss_write_regs(void) 677static void dss_write_regs(void)
708{ 678{
709 const int num_mgrs = omap_dss_get_num_overlay_managers(); 679 const int num_mgrs = omap_dss_get_num_overlay_managers();
710 int i; 680 int i;
711 681
712 dss_write_regs_common();
713
714 for (i = 0; i < num_mgrs; ++i) { 682 for (i = 0; i < num_mgrs; ++i) {
715 struct omap_overlay_manager *mgr; 683 struct omap_overlay_manager *mgr;
716 struct mgr_priv_data *mp; 684 struct mgr_priv_data *mp;
@@ -799,8 +767,6 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
799 dss_mgr_write_regs(mgr); 767 dss_mgr_write_regs(mgr);
800 dss_mgr_write_regs_extra(mgr); 768 dss_mgr_write_regs_extra(mgr);
801 769
802 dss_write_regs_common();
803
804 mp->updating = true; 770 mp->updating = true;
805 771
806 if (!dss_data.irq_enabled && need_isr()) 772 if (!dss_data.irq_enabled && need_isr())
@@ -984,20 +950,11 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
984 op->extra_info_dirty = true; 950 op->extra_info_dirty = true;
985} 951}
986 952
987static void dss_apply_fifo_merge(bool use_fifo_merge) 953static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
988{
989 if (dss_data.fifo_merge == use_fifo_merge)
990 return;
991
992 dss_data.fifo_merge = use_fifo_merge;
993 dss_data.fifo_merge_dirty = true;
994}
995
996static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
997 bool use_fifo_merge)
998{ 954{
999 struct ovl_priv_data *op = get_ovl_priv(ovl); 955 struct ovl_priv_data *op = get_ovl_priv(ovl);
1000 u32 fifo_low, fifo_high; 956 u32 fifo_low, fifo_high;
957 bool use_fifo_merge = false;
1001 958
1002 if (!op->enabled && !op->enabling) 959 if (!op->enabled && !op->enabling)
1003 return; 960 return;
@@ -1008,8 +965,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
1008 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); 965 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
1009} 966}
1010 967
1011static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, 968static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
1012 bool use_fifo_merge)
1013{ 969{
1014 struct omap_overlay *ovl; 970 struct omap_overlay *ovl;
1015 struct mgr_priv_data *mp; 971 struct mgr_priv_data *mp;
@@ -1020,10 +976,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
1020 return; 976 return;
1021 977
1022 list_for_each_entry(ovl, &mgr->overlays, list) 978 list_for_each_entry(ovl, &mgr->overlays, list)
1023 dss_ovl_setup_fifo(ovl, use_fifo_merge); 979 dss_ovl_setup_fifo(ovl);
1024} 980}
1025 981
1026static void dss_setup_fifos(bool use_fifo_merge) 982static void dss_setup_fifos(void)
1027{ 983{
1028 const int num_mgrs = omap_dss_get_num_overlay_managers(); 984 const int num_mgrs = omap_dss_get_num_overlay_managers();
1029 struct omap_overlay_manager *mgr; 985 struct omap_overlay_manager *mgr;
@@ -1031,91 +987,15 @@ static void dss_setup_fifos(bool use_fifo_merge)
1031 987
1032 for (i = 0; i < num_mgrs; ++i) { 988 for (i = 0; i < num_mgrs; ++i) {
1033 mgr = omap_dss_get_overlay_manager(i); 989 mgr = omap_dss_get_overlay_manager(i);
1034 dss_mgr_setup_fifos(mgr, use_fifo_merge); 990 dss_mgr_setup_fifos(mgr);
1035 } 991 }
1036} 992}
1037 993
1038static int get_num_used_managers(void)
1039{
1040 const int num_mgrs = omap_dss_get_num_overlay_managers();
1041 struct omap_overlay_manager *mgr;
1042 struct mgr_priv_data *mp;
1043 int i;
1044 int enabled_mgrs;
1045
1046 enabled_mgrs = 0;
1047
1048 for (i = 0; i < num_mgrs; ++i) {
1049 mgr = omap_dss_get_overlay_manager(i);
1050 mp = get_mgr_priv(mgr);
1051
1052 if (!mp->enabled)
1053 continue;
1054
1055 enabled_mgrs++;
1056 }
1057
1058 return enabled_mgrs;
1059}
1060
1061static int get_num_used_overlays(void)
1062{
1063 const int num_ovls = omap_dss_get_num_overlays();
1064 struct omap_overlay *ovl;
1065 struct ovl_priv_data *op;
1066 struct mgr_priv_data *mp;
1067 int i;
1068 int enabled_ovls;
1069
1070 enabled_ovls = 0;
1071
1072 for (i = 0; i < num_ovls; ++i) {
1073 ovl = omap_dss_get_overlay(i);
1074 op = get_ovl_priv(ovl);
1075
1076 if (!op->enabled && !op->enabling)
1077 continue;
1078
1079 mp = get_mgr_priv(ovl->manager);
1080
1081 if (!mp->enabled)
1082 continue;
1083
1084 enabled_ovls++;
1085 }
1086
1087 return enabled_ovls;
1088}
1089
1090static bool get_use_fifo_merge(void)
1091{
1092 int enabled_mgrs = get_num_used_managers();
1093 int enabled_ovls = get_num_used_overlays();
1094
1095 if (!dss_has_feature(FEAT_FIFO_MERGE))
1096 return false;
1097
1098 /*
1099 * In theory the only requirement for fifomerge is enabled_ovls <= 1.
1100 * However, if we have two managers enabled and set/unset the fifomerge,
1101 * we need to set the GO bits in particular sequence for the managers,
1102 * and wait in between.
1103 *
1104 * This is rather difficult as new apply calls can happen at any time,
1105 * so we simplify the problem by requiring also that enabled_mgrs <= 1.
1106 * In practice this shouldn't matter, because when only one overlay is
1107 * enabled, most likely only one output is enabled.
1108 */
1109
1110 return enabled_mgrs <= 1 && enabled_ovls <= 1;
1111}
1112
1113int dss_mgr_enable(struct omap_overlay_manager *mgr) 994int dss_mgr_enable(struct omap_overlay_manager *mgr)
1114{ 995{
1115 struct mgr_priv_data *mp = get_mgr_priv(mgr); 996 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1116 unsigned long flags; 997 unsigned long flags;
1117 int r; 998 int r;
1118 bool fifo_merge;
1119 999
1120 mutex_lock(&apply_lock); 1000 mutex_lock(&apply_lock);
1121 1001
@@ -1133,23 +1013,11 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
1133 goto err; 1013 goto err;
1134 } 1014 }
1135 1015
1136 /* step 1: setup fifos/fifomerge before enabling the manager */ 1016 dss_setup_fifos();
1137
1138 fifo_merge = get_use_fifo_merge();
1139 dss_setup_fifos(fifo_merge);
1140 dss_apply_fifo_merge(fifo_merge);
1141 1017
1142 dss_write_regs(); 1018 dss_write_regs();
1143 dss_set_go_bits(); 1019 dss_set_go_bits();
1144 1020
1145 spin_unlock_irqrestore(&data_lock, flags);
1146
1147 /* wait until fifo config is in */
1148 wait_pending_extra_info_updates();
1149
1150 /* step 2: enable the manager */
1151 spin_lock_irqsave(&data_lock, flags);
1152
1153 if (!mgr_manual_update(mgr)) 1021 if (!mgr_manual_update(mgr))
1154 mp->updating = true; 1022 mp->updating = true;
1155 1023
@@ -1174,7 +1042,6 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
1174{ 1042{
1175 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1043 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1176 unsigned long flags; 1044 unsigned long flags;
1177 bool fifo_merge;
1178 1045
1179 mutex_lock(&apply_lock); 1046 mutex_lock(&apply_lock);
1180 1047
@@ -1189,16 +1056,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
1189 mp->updating = false; 1056 mp->updating = false;
1190 mp->enabled = false; 1057 mp->enabled = false;
1191 1058
1192 fifo_merge = get_use_fifo_merge();
1193 dss_setup_fifos(fifo_merge);
1194 dss_apply_fifo_merge(fifo_merge);
1195
1196 dss_write_regs();
1197 dss_set_go_bits();
1198
1199 spin_unlock_irqrestore(&data_lock, flags); 1059 spin_unlock_irqrestore(&data_lock, flags);
1200 1060
1201 wait_pending_extra_info_updates();
1202out: 1061out:
1203 mutex_unlock(&apply_lock); 1062 mutex_unlock(&apply_lock);
1204} 1063}
@@ -1314,21 +1173,19 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1314 const struct omap_video_timings *timings) 1173 const struct omap_video_timings *timings)
1315{ 1174{
1316 unsigned long flags; 1175 unsigned long flags;
1317 1176 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1318 mutex_lock(&apply_lock);
1319 1177
1320 spin_lock_irqsave(&data_lock, flags); 1178 spin_lock_irqsave(&data_lock, flags);
1321 1179
1322 dss_apply_mgr_timings(mgr, timings); 1180 if (mp->updating) {
1323 1181 DSSERR("cannot set timings for %s: manager needs to be disabled\n",
1324 dss_write_regs(); 1182 mgr->name);
1325 dss_set_go_bits(); 1183 goto out;
1184 }
1326 1185
1186 dss_apply_mgr_timings(mgr, timings);
1187out:
1327 spin_unlock_irqrestore(&data_lock, flags); 1188 spin_unlock_irqrestore(&data_lock, flags);
1328
1329 wait_pending_extra_info_updates();
1330
1331 mutex_unlock(&apply_lock);
1332} 1189}
1333 1190
1334static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, 1191static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
@@ -1346,7 +1203,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
1346 unsigned long flags; 1203 unsigned long flags;
1347 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1204 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1348 1205
1349 mutex_lock(&apply_lock); 1206 spin_lock_irqsave(&data_lock, flags);
1350 1207
1351 if (mp->enabled) { 1208 if (mp->enabled) {
1352 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n", 1209 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
@@ -1354,19 +1211,9 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
1354 goto out; 1211 goto out;
1355 } 1212 }
1356 1213
1357 spin_lock_irqsave(&data_lock, flags);
1358
1359 dss_apply_mgr_lcd_config(mgr, config); 1214 dss_apply_mgr_lcd_config(mgr, config);
1360
1361 dss_write_regs();
1362 dss_set_go_bits();
1363
1364 spin_unlock_irqrestore(&data_lock, flags);
1365
1366 wait_pending_extra_info_updates();
1367
1368out: 1215out:
1369 mutex_unlock(&apply_lock); 1216 spin_unlock_irqrestore(&data_lock, flags);
1370} 1217}
1371 1218
1372int dss_ovl_set_info(struct omap_overlay *ovl, 1219int dss_ovl_set_info(struct omap_overlay *ovl,
@@ -1483,6 +1330,13 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl)
1483 goto err; 1330 goto err;
1484 } 1331 }
1485 1332
1333 spin_unlock_irqrestore(&data_lock, flags);
1334
1335 /* wait for pending extra_info updates to ensure the ovl is disabled */
1336 wait_pending_extra_info_updates();
1337
1338 spin_lock_irqsave(&data_lock, flags);
1339
1486 op->channel = -1; 1340 op->channel = -1;
1487 1341
1488 ovl->manager = NULL; 1342 ovl->manager = NULL;
@@ -1517,7 +1371,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1517{ 1371{
1518 struct ovl_priv_data *op = get_ovl_priv(ovl); 1372 struct ovl_priv_data *op = get_ovl_priv(ovl);
1519 unsigned long flags; 1373 unsigned long flags;
1520 bool fifo_merge;
1521 int r; 1374 int r;
1522 1375
1523 mutex_lock(&apply_lock); 1376 mutex_lock(&apply_lock);
@@ -1543,22 +1396,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1543 goto err2; 1396 goto err2;
1544 } 1397 }
1545 1398
1546 /* step 1: configure fifos/fifomerge for currently enabled ovls */ 1399 dss_setup_fifos();
1547
1548 fifo_merge = get_use_fifo_merge();
1549 dss_setup_fifos(fifo_merge);
1550 dss_apply_fifo_merge(fifo_merge);
1551
1552 dss_write_regs();
1553 dss_set_go_bits();
1554
1555 spin_unlock_irqrestore(&data_lock, flags);
1556
1557 /* wait for fifo configs to go in */
1558 wait_pending_extra_info_updates();
1559
1560 /* step 2: enable the overlay */
1561 spin_lock_irqsave(&data_lock, flags);
1562 1400
1563 op->enabling = false; 1401 op->enabling = false;
1564 dss_apply_ovl_enable(ovl, true); 1402 dss_apply_ovl_enable(ovl, true);
@@ -1568,9 +1406,6 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1568 1406
1569 spin_unlock_irqrestore(&data_lock, flags); 1407 spin_unlock_irqrestore(&data_lock, flags);
1570 1408
1571 /* wait for overlay to be enabled */
1572 wait_pending_extra_info_updates();
1573
1574 mutex_unlock(&apply_lock); 1409 mutex_unlock(&apply_lock);
1575 1410
1576 return 0; 1411 return 0;
@@ -1586,7 +1421,6 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1586{ 1421{
1587 struct ovl_priv_data *op = get_ovl_priv(ovl); 1422 struct ovl_priv_data *op = get_ovl_priv(ovl);
1588 unsigned long flags; 1423 unsigned long flags;
1589 bool fifo_merge;
1590 int r; 1424 int r;
1591 1425
1592 mutex_lock(&apply_lock); 1426 mutex_lock(&apply_lock);
@@ -1601,34 +1435,14 @@ int dss_ovl_disable(struct omap_overlay *ovl)
1601 goto err; 1435 goto err;
1602 } 1436 }
1603 1437
1604 /* step 1: disable the overlay */
1605 spin_lock_irqsave(&data_lock, flags); 1438 spin_lock_irqsave(&data_lock, flags);
1606 1439
1607 dss_apply_ovl_enable(ovl, false); 1440 dss_apply_ovl_enable(ovl, false);
1608
1609 dss_write_regs();
1610 dss_set_go_bits();
1611
1612 spin_unlock_irqrestore(&data_lock, flags);
1613
1614 /* wait for the overlay to be disabled */
1615 wait_pending_extra_info_updates();
1616
1617 /* step 2: configure fifos/fifomerge */
1618 spin_lock_irqsave(&data_lock, flags);
1619
1620 fifo_merge = get_use_fifo_merge();
1621 dss_setup_fifos(fifo_merge);
1622 dss_apply_fifo_merge(fifo_merge);
1623
1624 dss_write_regs(); 1441 dss_write_regs();
1625 dss_set_go_bits(); 1442 dss_set_go_bits();
1626 1443
1627 spin_unlock_irqrestore(&data_lock, flags); 1444 spin_unlock_irqrestore(&data_lock, flags);
1628 1445
1629 /* wait for fifo config to go in */
1630 wait_pending_extra_info_updates();
1631
1632 mutex_unlock(&apply_lock); 1446 mutex_unlock(&apply_lock);
1633 1447
1634 return 0; 1448 return 0;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0de9a7efcbc4..d512c389741e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,8 +37,6 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/pm_runtime.h> 38#include <linux/pm_runtime.h>
39 39
40#include <plat/clock.h>
41
42#include <video/omapdss.h> 40#include <video/omapdss.h>
43 41
44#include "dss.h" 42#include "dss.h"
@@ -96,8 +94,14 @@ struct dispc_features {
96 u16 pos_x, unsigned long *core_clk); 94 u16 pos_x, unsigned long *core_clk);
97 unsigned long (*calc_core_clk) (enum omap_channel channel, 95 unsigned long (*calc_core_clk) (enum omap_channel channel,
98 u16 width, u16 height, u16 out_width, u16 out_height); 96 u16 width, u16 height, u16 out_width, u16 out_height);
97 u8 num_fifos;
98
99 /* swap GFX & WB fifos */
100 bool gfx_fifo_workaround:1;
99}; 101};
100 102
103#define DISPC_MAX_NR_FIFOS 5
104
101static struct { 105static struct {
102 struct platform_device *pdev; 106 struct platform_device *pdev;
103 void __iomem *base; 107 void __iomem *base;
@@ -107,7 +111,9 @@ static struct {
107 int irq; 111 int irq;
108 struct clk *dss_clk; 112 struct clk *dss_clk;
109 113
110 u32 fifo_size[MAX_DSS_OVERLAYS]; 114 u32 fifo_size[DISPC_MAX_NR_FIFOS];
115 /* maps which plane is using a fifo. fifo-id -> plane-id */
116 int fifo_assignment[DISPC_MAX_NR_FIFOS];
111 117
112 spinlock_t irq_lock; 118 spinlock_t irq_lock;
113 u32 irq_error_mask; 119 u32 irq_error_mask;
@@ -1063,10 +1069,10 @@ static void dispc_mgr_set_size(enum omap_channel channel, u16 width,
1063 dispc_write_reg(DISPC_SIZE_MGR(channel), val); 1069 dispc_write_reg(DISPC_SIZE_MGR(channel), val);
1064} 1070}
1065 1071
1066static void dispc_read_plane_fifo_sizes(void) 1072static void dispc_init_fifos(void)
1067{ 1073{
1068 u32 size; 1074 u32 size;
1069 int plane; 1075 int fifo;
1070 u8 start, end; 1076 u8 start, end;
1071 u32 unit; 1077 u32 unit;
1072 1078
@@ -1074,16 +1080,53 @@ static void dispc_read_plane_fifo_sizes(void)
1074 1080
1075 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); 1081 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
1076 1082
1077 for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) { 1083 for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
1078 size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end); 1084 size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
1079 size *= unit; 1085 size *= unit;
1080 dispc.fifo_size[plane] = size; 1086 dispc.fifo_size[fifo] = size;
1087
1088 /*
1089 * By default fifos are mapped directly to overlays, fifo 0 to
1090 * ovl 0, fifo 1 to ovl 1, etc.
1091 */
1092 dispc.fifo_assignment[fifo] = fifo;
1093 }
1094
1095 /*
1096 * The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo
1097 * causes problems with certain use cases, like using the tiler in 2D
1098 * mode. The below hack swaps the fifos of GFX and WB planes, thus
1099 * giving GFX plane a larger fifo. WB but should work fine with a
1100 * smaller fifo.
1101 */
1102 if (dispc.feat->gfx_fifo_workaround) {
1103 u32 v;
1104
1105 v = dispc_read_reg(DISPC_GLOBAL_BUFFER);
1106
1107 v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */
1108 v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */
1109 v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */
1110 v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */
1111
1112 dispc_write_reg(DISPC_GLOBAL_BUFFER, v);
1113
1114 dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
1115 dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
1081 } 1116 }
1082} 1117}
1083 1118
1084static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) 1119static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
1085{ 1120{
1086 return dispc.fifo_size[plane]; 1121 int fifo;
1122 u32 size = 0;
1123
1124 for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
1125 if (dispc.fifo_assignment[fifo] == plane)
1126 size += dispc.fifo_size[fifo];
1127 }
1128
1129 return size;
1087} 1130}
1088 1131
1089void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) 1132void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
@@ -3710,7 +3753,7 @@ static void _omap_dispc_initial_config(void)
3710 3753
3711 dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); 3754 dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
3712 3755
3713 dispc_read_plane_fifo_sizes(); 3756 dispc_init_fifos();
3714 3757
3715 dispc_configure_burst_sizes(); 3758 dispc_configure_burst_sizes();
3716 3759
@@ -3726,6 +3769,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
3726 .hp_max = 256, 3769 .hp_max = 256,
3727 .calc_scaling = dispc_ovl_calc_scaling_24xx, 3770 .calc_scaling = dispc_ovl_calc_scaling_24xx,
3728 .calc_core_clk = calc_core_clk_24xx, 3771 .calc_core_clk = calc_core_clk_24xx,
3772 .num_fifos = 3,
3729}; 3773};
3730 3774
3731static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { 3775static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
@@ -3737,6 +3781,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
3737 .hp_max = 256, 3781 .hp_max = 256,
3738 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3782 .calc_scaling = dispc_ovl_calc_scaling_34xx,
3739 .calc_core_clk = calc_core_clk_34xx, 3783 .calc_core_clk = calc_core_clk_34xx,
3784 .num_fifos = 3,
3740}; 3785};
3741 3786
3742static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { 3787static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
@@ -3748,6 +3793,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
3748 .hp_max = 4096, 3793 .hp_max = 4096,
3749 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3794 .calc_scaling = dispc_ovl_calc_scaling_34xx,
3750 .calc_core_clk = calc_core_clk_34xx, 3795 .calc_core_clk = calc_core_clk_34xx,
3796 .num_fifos = 3,
3751}; 3797};
3752 3798
3753static const struct dispc_features omap44xx_dispc_feats __initconst = { 3799static const struct dispc_features omap44xx_dispc_feats __initconst = {
@@ -3759,6 +3805,8 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
3759 .hp_max = 4096, 3805 .hp_max = 4096,
3760 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3806 .calc_scaling = dispc_ovl_calc_scaling_44xx,
3761 .calc_core_clk = calc_core_clk_44xx, 3807 .calc_core_clk = calc_core_clk_44xx,
3808 .num_fifos = 5,
3809 .gfx_fifo_workaround = true,
3762}; 3810};
3763 3811
3764static int __init dispc_init_features(struct device *dev) 3812static int __init dispc_init_features(struct device *dev)
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 92d8a9be86fc..42e56cc7cdbc 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,7 @@
36#define DISPC_CONTROL2 0x0238 36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620 37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804 38#define DISPC_DIVISOR 0x0804
39#define DISPC_GLOBAL_BUFFER 0x0800
39#define DISPC_CONTROL3 0x0848 40#define DISPC_CONTROL3 0x0848
40#define DISPC_CONFIG3 0x084C 41#define DISPC_CONFIG3 0x084C
41 42
@@ -355,6 +356,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
355 return 0x014C; 356 return 0x014C;
356 case OMAP_DSS_VIDEO3: 357 case OMAP_DSS_VIDEO3:
357 return 0x0300; 358 return 0x0300;
359 case OMAP_DSS_WB:
360 return 0x0500;
358 default: 361 default:
359 BUG(); 362 BUG();
360 return 0; 363 return 0;
@@ -517,6 +520,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
517 case OMAP_DSS_VIDEO2: 520 case OMAP_DSS_VIDEO2:
518 return 0x0018; 521 return 0x0018;
519 case OMAP_DSS_VIDEO3: 522 case OMAP_DSS_VIDEO3:
523 case OMAP_DSS_WB:
520 return 0x0088; 524 return 0x0088;
521 default: 525 default:
522 BUG(); 526 BUG();
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 5bd957e85505..5f09d503d619 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -142,7 +142,11 @@ static ssize_t display_timings_store(struct device *dev,
142 if (r) 142 if (r)
143 return r; 143 return r;
144 144
145 dssdev->driver->disable(dssdev);
145 dssdev->driver->set_timings(dssdev, &t); 146 dssdev->driver->set_timings(dssdev, &t);
147 r = dssdev->driver->enable(dssdev);
148 if (r)
149 return r;
146 150
147 return size; 151 return size;
148} 152}
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 25fb8953b80a..5ccce9b69e42 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -31,7 +31,6 @@
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32 32
33#include <video/omapdss.h> 33#include <video/omapdss.h>
34#include <plat/cpu.h>
35 34
36#include "dss.h" 35#include "dss.h"
37#include "dss_features.h" 36#include "dss_features.h"
@@ -278,26 +277,12 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
278void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, 277void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
279 struct omap_video_timings *timings) 278 struct omap_video_timings *timings)
280{ 279{
281 int r;
282
283 DSSDBG("dpi_set_timings\n"); 280 DSSDBG("dpi_set_timings\n");
284 281
285 mutex_lock(&dpi.lock); 282 mutex_lock(&dpi.lock);
286 283
287 dpi.timings = *timings; 284 dpi.timings = *timings;
288 285
289 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
290 r = dispc_runtime_get();
291 if (r)
292 return;
293
294 dpi_set_mode(dssdev);
295
296 dispc_runtime_put();
297 } else {
298 dss_mgr_set_timings(dssdev->manager, timings);
299 }
300
301 mutex_unlock(&dpi.lock); 286 mutex_unlock(&dpi.lock);
302} 287}
303EXPORT_SYMBOL(omapdss_dpi_set_timings); 288EXPORT_SYMBOL(omapdss_dpi_set_timings);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 96d0024ada40..8d815e39e45d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -41,7 +41,6 @@
41 41
42#include <video/omapdss.h> 42#include <video/omapdss.h>
43#include <video/mipi_display.h> 43#include <video/mipi_display.h>
44#include <plat/clock.h>
45 44
46#include "dss.h" 45#include "dss.h"
47#include "dss_features.h" 46#include "dss_features.h"
@@ -1454,6 +1453,68 @@ found:
1454 return 0; 1453 return 0;
1455} 1454}
1456 1455
1456static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
1457 unsigned long req_clk, struct dsi_clock_info *cinfo)
1458{
1459 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1460 struct dsi_clock_info cur, best;
1461 unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck;
1462 unsigned long req_clkin4ddr;
1463
1464 DSSDBG("dsi_pll_calc_ddrfreq\n");
1465
1466 dss_sys_clk = clk_get_rate(dsi->sys_clk);
1467
1468 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1469 max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
1470
1471 memset(&best, 0, sizeof(best));
1472 memset(&cur, 0, sizeof(cur));
1473
1474 cur.clkin = dss_sys_clk;
1475
1476 req_clkin4ddr = req_clk * 4;
1477
1478 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
1479 cur.fint = cur.clkin / cur.regn;
1480
1481 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
1482 continue;
1483
1484 /* DSIPHY(MHz) = (2 * regm / regn) * clkin */
1485 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
1486 unsigned long a, b;
1487
1488 a = 2 * cur.regm * (cur.clkin/1000);
1489 b = cur.regn;
1490 cur.clkin4ddr = a / b * 1000;
1491
1492 if (cur.clkin4ddr > 1800 * 1000 * 1000)
1493 break;
1494
1495 if (abs(cur.clkin4ddr - req_clkin4ddr) <
1496 abs(best.clkin4ddr - req_clkin4ddr)) {
1497 best = cur;
1498 DSSDBG("best %ld\n", best.clkin4ddr);
1499 }
1500
1501 if (cur.clkin4ddr == req_clkin4ddr)
1502 goto found;
1503 }
1504 }
1505found:
1506 best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck);
1507 best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc;
1508
1509 best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck);
1510 best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi;
1511
1512 if (cinfo)
1513 *cinfo = best;
1514
1515 return 0;
1516}
1517
1457int dsi_pll_set_clock_div(struct platform_device *dsidev, 1518int dsi_pll_set_clock_div(struct platform_device *dsidev,
1458 struct dsi_clock_info *cinfo) 1519 struct dsi_clock_info *cinfo)
1459{ 1520{
@@ -4110,6 +4171,70 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
4110} 4171}
4111EXPORT_SYMBOL(omapdss_dsi_configure_pins); 4172EXPORT_SYMBOL(omapdss_dsi_configure_pins);
4112 4173
4174int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
4175 unsigned long ddr_clk, unsigned long lp_clk)
4176{
4177 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4178 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4179 struct dsi_clock_info cinfo;
4180 struct dispc_clock_info dispc_cinfo;
4181 unsigned lp_clk_div;
4182 unsigned long dsi_fclk;
4183 int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
4184 unsigned long pck;
4185 int r;
4186
4187 DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
4188
4189 mutex_lock(&dsi->lock);
4190
4191 r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo);
4192 if (r)
4193 goto err;
4194
4195 dssdev->clocks.dsi.regn = cinfo.regn;
4196 dssdev->clocks.dsi.regm = cinfo.regm;
4197 dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
4198 dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
4199
4200
4201 dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
4202 lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
4203
4204 dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
4205
4206 /* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
4207
4208 pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
4209
4210 DSSDBG("finding dispc dividers for pck %lu\n", pck);
4211
4212 dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo);
4213
4214 dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
4215 dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
4216
4217
4218 dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
4219
4220 dssdev->clocks.dispc.channel.lcd_clk_src =
4221 dsi->module_id == 0 ?
4222 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
4223 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
4224
4225 dssdev->clocks.dsi.dsi_fclk_src =
4226 dsi->module_id == 0 ?
4227 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
4228 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
4229
4230 mutex_unlock(&dsi->lock);
4231 return 0;
4232err:
4233 mutex_unlock(&dsi->lock);
4234 return r;
4235}
4236EXPORT_SYMBOL(omapdss_dsi_set_clocks);
4237
4113int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) 4238int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4114{ 4239{
4115 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4240 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4740,11 +4865,6 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
4740 4865
4741 DSSDBG("DSI init\n"); 4866 DSSDBG("DSI init\n");
4742 4867
4743 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
4744 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
4745 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
4746 }
4747
4748 if (dsi->vdds_dsi_reg == NULL) { 4868 if (dsi->vdds_dsi_reg == NULL) {
4749 struct regulator *vdds_dsi; 4869 struct regulator *vdds_dsi;
4750 4870
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 31a553a6ee6f..759dbee48342 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -36,7 +36,6 @@
36#include <video/omapdss.h> 36#include <video/omapdss.h>
37 37
38#include <plat/cpu.h> 38#include <plat/cpu.h>
39#include <plat/clock.h>
40 39
41#include "dss.h" 40#include "dss.h"
42#include "dss_features.h" 41#include "dss_features.h"
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d6cca820723c..5e9fd7691728 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -254,6 +254,10 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
254 return false; 254 return false;
255} 255}
256 256
257int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
258 struct platform_device *pdev);
259void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
260
257/* overlay */ 261/* overlay */
258void dss_init_overlays(struct platform_device *pdev); 262void dss_init_overlays(struct platform_device *pdev);
259void dss_uninit_overlays(struct platform_device *pdev); 263void dss_uninit_overlays(struct platform_device *pdev);
@@ -265,6 +269,9 @@ int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
265 const struct omap_video_timings *mgr_timings); 269 const struct omap_video_timings *mgr_timings);
266bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, 270bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
267 enum omap_color_mode mode); 271 enum omap_color_mode mode);
272int dss_overlay_kobj_init(struct omap_overlay *ovl,
273 struct platform_device *pdev);
274void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
268 275
269/* DSS */ 276/* DSS */
270int dss_init_platform_driver(void) __init; 277int dss_init_platform_driver(void) __init;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 2fe39d65502f..c26fc1fb7dbc 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -326,6 +326,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
326 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 }, 326 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
327 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 }, 327 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
328 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, 328 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
329 [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
329 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 330 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
330 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 }, 331 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
331 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, 332 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
@@ -341,6 +342,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
341 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, 342 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
342 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, 343 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
343 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 344 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
345 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
344 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 346 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
345 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 347 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
346 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, 348 [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 },
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 26d43a4b9812..b81d603310a8 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -92,6 +92,7 @@ enum dss_range_param {
92 FEAT_PARAM_DSIPLL_REGM_DSI, 92 FEAT_PARAM_DSIPLL_REGM_DSI,
93 FEAT_PARAM_DSIPLL_FINT, 93 FEAT_PARAM_DSIPLL_FINT,
94 FEAT_PARAM_DSIPLL_LPDIV, 94 FEAT_PARAM_DSIPLL_LPDIV,
95 FEAT_PARAM_DSI_FCK,
95 FEAT_PARAM_DOWNSCALE, 96 FEAT_PARAM_DOWNSCALE,
96 FEAT_PARAM_LINEWIDTH, 97 FEAT_PARAM_LINEWIDTH,
97 FEAT_PARAM_MGR_WIDTH, 98 FEAT_PARAM_MGR_WIDTH,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf24673d48..83f18458a406 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -32,6 +32,8 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <linux/clk.h> 34#include <linux/clk.h>
35#include <linux/gpio.h>
36#include <linux/regulator/consumer.h>
35#include <video/omapdss.h> 37#include <video/omapdss.h>
36 38
37#include "ti_hdmi.h" 39#include "ti_hdmi.h"
@@ -61,6 +63,11 @@ static struct {
61 struct hdmi_ip_data ip_data; 63 struct hdmi_ip_data ip_data;
62 64
63 struct clk *sys_clk; 65 struct clk *sys_clk;
66 struct regulator *vdda_hdmi_dac_reg;
67
68 int ct_cp_hpd_gpio;
69 int ls_oe_gpio;
70 int hpd_gpio;
64} hdmi; 71} hdmi;
65 72
66/* 73/*
@@ -314,12 +321,47 @@ static void hdmi_runtime_put(void)
314 321
315static int __init hdmi_init_display(struct omap_dss_device *dssdev) 322static int __init hdmi_init_display(struct omap_dss_device *dssdev)
316{ 323{
324 int r;
325
326 struct gpio gpios[] = {
327 { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
328 { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
329 { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
330 };
331
317 DSSDBG("init_display\n"); 332 DSSDBG("init_display\n");
318 333
319 dss_init_hdmi_ip_ops(&hdmi.ip_data); 334 dss_init_hdmi_ip_ops(&hdmi.ip_data);
335
336 if (hdmi.vdda_hdmi_dac_reg == NULL) {
337 struct regulator *reg;
338
339 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
340
341 if (IS_ERR(reg)) {
342 DSSERR("can't get VDDA_HDMI_DAC regulator\n");
343 return PTR_ERR(reg);
344 }
345
346 hdmi.vdda_hdmi_dac_reg = reg;
347 }
348
349 r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
350 if (r)
351 return r;
352
320 return 0; 353 return 0;
321} 354}
322 355
356static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
357{
358 DSSDBG("uninit_display\n");
359
360 gpio_free(hdmi.ct_cp_hpd_gpio);
361 gpio_free(hdmi.ls_oe_gpio);
362 gpio_free(hdmi.hpd_gpio);
363}
364
323static const struct hdmi_config *hdmi_find_timing( 365static const struct hdmi_config *hdmi_find_timing(
324 const struct hdmi_config *timings_arr, 366 const struct hdmi_config *timings_arr,
325 int len) 367 int len)
@@ -462,9 +504,19 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
462 struct omap_video_timings *p; 504 struct omap_video_timings *p;
463 unsigned long phy; 505 unsigned long phy;
464 506
507 gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
508 gpio_set_value(hdmi.ls_oe_gpio, 1);
509
510 /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
511 udelay(300);
512
513 r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
514 if (r)
515 goto err_vdac_enable;
516
465 r = hdmi_runtime_get(); 517 r = hdmi_runtime_get();
466 if (r) 518 if (r)
467 return r; 519 goto err_runtime_get;
468 520
469 dss_mgr_disable(dssdev->manager); 521 dss_mgr_disable(dssdev->manager);
470 522
@@ -482,7 +534,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
482 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); 534 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
483 if (r) { 535 if (r) {
484 DSSDBG("Failed to lock PLL\n"); 536 DSSDBG("Failed to lock PLL\n");
485 goto err; 537 goto err_pll_enable;
486 } 538 }
487 539
488 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); 540 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
@@ -526,8 +578,13 @@ err_vid_enable:
526 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 578 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
527err_phy_enable: 579err_phy_enable:
528 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 580 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
529err: 581err_pll_enable:
530 hdmi_runtime_put(); 582 hdmi_runtime_put();
583err_runtime_get:
584 regulator_disable(hdmi.vdda_hdmi_dac_reg);
585err_vdac_enable:
586 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
587 gpio_set_value(hdmi.ls_oe_gpio, 0);
531 return -EIO; 588 return -EIO;
532} 589}
533 590
@@ -539,6 +596,11 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
539 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 596 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
540 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 597 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
541 hdmi_runtime_put(); 598 hdmi_runtime_put();
599
600 regulator_disable(hdmi.vdda_hdmi_dac_reg);
601
602 gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
603 gpio_set_value(hdmi.ls_oe_gpio, 0);
542} 604}
543 605
544int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 606int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -570,18 +632,6 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
570 if (t != NULL) 632 if (t != NULL)
571 hdmi.ip_data.cfg = *t; 633 hdmi.ip_data.cfg = *t;
572 634
573 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
574 int r;
575
576 hdmi_power_off(dssdev);
577
578 r = hdmi_power_on(dssdev);
579 if (r)
580 DSSERR("failed to power on device\n");
581 } else {
582 dss_mgr_set_timings(dssdev->manager, &t->timings);
583 }
584
585 mutex_unlock(&hdmi.lock); 635 mutex_unlock(&hdmi.lock);
586} 636}
587 637
@@ -637,7 +687,6 @@ bool omapdss_hdmi_detect(void)
637 687
638int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) 688int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
639{ 689{
640 struct omap_dss_hdmi_data *priv = dssdev->data;
641 int r = 0; 690 int r = 0;
642 691
643 DSSDBG("ENTER hdmi_display_enable\n"); 692 DSSDBG("ENTER hdmi_display_enable\n");
@@ -650,7 +699,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
650 goto err0; 699 goto err0;
651 } 700 }
652 701
653 hdmi.ip_data.hpd_gpio = priv->hpd_gpio; 702 hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
654 703
655 r = omap_dss_start_device(dssdev); 704 r = omap_dss_start_device(dssdev);
656 if (r) { 705 if (r) {
@@ -658,26 +707,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
658 goto err0; 707 goto err0;
659 } 708 }
660 709
661 if (dssdev->platform_enable) {
662 r = dssdev->platform_enable(dssdev);
663 if (r) {
664 DSSERR("failed to enable GPIO's\n");
665 goto err1;
666 }
667 }
668
669 r = hdmi_power_on(dssdev); 710 r = hdmi_power_on(dssdev);
670 if (r) { 711 if (r) {
671 DSSERR("failed to power on device\n"); 712 DSSERR("failed to power on device\n");
672 goto err2; 713 goto err1;
673 } 714 }
674 715
675 mutex_unlock(&hdmi.lock); 716 mutex_unlock(&hdmi.lock);
676 return 0; 717 return 0;
677 718
678err2:
679 if (dssdev->platform_disable)
680 dssdev->platform_disable(dssdev);
681err1: 719err1:
682 omap_dss_stop_device(dssdev); 720 omap_dss_stop_device(dssdev);
683err0: 721err0:
@@ -693,9 +731,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
693 731
694 hdmi_power_off(dssdev); 732 hdmi_power_off(dssdev);
695 733
696 if (dssdev->platform_disable)
697 dssdev->platform_disable(dssdev);
698
699 omap_dss_stop_device(dssdev); 734 omap_dss_stop_device(dssdev);
700 735
701 mutex_unlock(&hdmi.lock); 736 mutex_unlock(&hdmi.lock);
@@ -873,10 +908,15 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
873 908
874 for (i = 0; i < pdata->num_devices; ++i) { 909 for (i = 0; i < pdata->num_devices; ++i) {
875 struct omap_dss_device *dssdev = pdata->devices[i]; 910 struct omap_dss_device *dssdev = pdata->devices[i];
911 struct omap_dss_hdmi_data *priv = dssdev->data;
876 912
877 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) 913 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
878 continue; 914 continue;
879 915
916 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
917 hdmi.ls_oe_gpio = priv->ls_oe_gpio;
918 hdmi.hpd_gpio = priv->hpd_gpio;
919
880 r = hdmi_init_display(dssdev); 920 r = hdmi_init_display(dssdev);
881 if (r) { 921 if (r) {
882 DSSERR("device %s init failed: %d\n", dssdev->name, r); 922 DSSERR("device %s init failed: %d\n", dssdev->name, r);
@@ -938,8 +978,17 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
938 return 0; 978 return 0;
939} 979}
940 980
981static int __exit hdmi_remove_child(struct device *dev, void *data)
982{
983 struct omap_dss_device *dssdev = to_dss_device(dev);
984 hdmi_uninit_display(dssdev);
985 return 0;
986}
987
941static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 988static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
942{ 989{
990 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
991
943 omap_dss_unregister_child_devices(&pdev->dev); 992 omap_dss_unregister_child_devices(&pdev->dev);
944 993
945 hdmi_panel_exit(); 994 hdmi_panel_exit();
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
new file mode 100644
index 000000000000..9b875fbe757e
--- /dev/null
+++ b/drivers/video/omap2/dss/manager-sysfs.c
@@ -0,0 +1,499 @@
1/*
2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
4 *
5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define DSS_SUBSYS_NAME "MANAGER"
22
23#include <linux/kernel.h>
24#include <linux/slab.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/jiffies.h>
28
29#include <video/omapdss.h>
30
31#include "dss.h"
32#include "dss_features.h"
33
34static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
35{
36 return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
37}
38
39static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
40{
41 return snprintf(buf, PAGE_SIZE, "%s\n",
42 mgr->device ? mgr->device->name : "<none>");
43}
44
45static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
46 const char *buf, size_t size)
47{
48 int r = 0;
49 size_t len = size;
50 struct omap_dss_device *dssdev = NULL;
51
52 int match(struct omap_dss_device *dssdev, void *data)
53 {
54 const char *str = data;
55 return sysfs_streq(dssdev->name, str);
56 }
57
58 if (buf[size-1] == '\n')
59 --len;
60
61 if (len > 0)
62 dssdev = omap_dss_find_device((void *)buf, match);
63
64 if (len > 0 && dssdev == NULL)
65 return -EINVAL;
66
67 if (dssdev)
68 DSSDBG("display %s found\n", dssdev->name);
69
70 if (mgr->device) {
71 r = mgr->unset_device(mgr);
72 if (r) {
73 DSSERR("failed to unset display\n");
74 goto put_device;
75 }
76 }
77
78 if (dssdev) {
79 r = mgr->set_device(mgr, dssdev);
80 if (r) {
81 DSSERR("failed to set manager\n");
82 goto put_device;
83 }
84
85 r = mgr->apply(mgr);
86 if (r) {
87 DSSERR("failed to apply dispc config\n");
88 goto put_device;
89 }
90 }
91
92put_device:
93 if (dssdev)
94 omap_dss_put_device(dssdev);
95
96 return r ? r : size;
97}
98
99static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
100 char *buf)
101{
102 struct omap_overlay_manager_info info;
103
104 mgr->get_manager_info(mgr, &info);
105
106 return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
107}
108
109static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
110 const char *buf, size_t size)
111{
112 struct omap_overlay_manager_info info;
113 u32 color;
114 int r;
115
116 r = kstrtouint(buf, 0, &color);
117 if (r)
118 return r;
119
120 mgr->get_manager_info(mgr, &info);
121
122 info.default_color = color;
123
124 r = mgr->set_manager_info(mgr, &info);
125 if (r)
126 return r;
127
128 r = mgr->apply(mgr);
129 if (r)
130 return r;
131
132 return size;
133}
134
135static const char *trans_key_type_str[] = {
136 "gfx-destination",
137 "video-source",
138};
139
140static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
141 char *buf)
142{
143 enum omap_dss_trans_key_type key_type;
144 struct omap_overlay_manager_info info;
145
146 mgr->get_manager_info(mgr, &info);
147
148 key_type = info.trans_key_type;
149 BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
150
151 return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
152}
153
154static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
155 const char *buf, size_t size)
156{
157 enum omap_dss_trans_key_type key_type;
158 struct omap_overlay_manager_info info;
159 int r;
160
161 for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
162 key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
163 if (sysfs_streq(buf, trans_key_type_str[key_type]))
164 break;
165 }
166
167 if (key_type == ARRAY_SIZE(trans_key_type_str))
168 return -EINVAL;
169
170 mgr->get_manager_info(mgr, &info);
171
172 info.trans_key_type = key_type;
173
174 r = mgr->set_manager_info(mgr, &info);
175 if (r)
176 return r;
177
178 r = mgr->apply(mgr);
179 if (r)
180 return r;
181
182 return size;
183}
184
185static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
186 char *buf)
187{
188 struct omap_overlay_manager_info info;
189
190 mgr->get_manager_info(mgr, &info);
191
192 return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
193}
194
195static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
196 const char *buf, size_t size)
197{
198 struct omap_overlay_manager_info info;
199 u32 key_value;
200 int r;
201
202 r = kstrtouint(buf, 0, &key_value);
203 if (r)
204 return r;
205
206 mgr->get_manager_info(mgr, &info);
207
208 info.trans_key = key_value;
209
210 r = mgr->set_manager_info(mgr, &info);
211 if (r)
212 return r;
213
214 r = mgr->apply(mgr);
215 if (r)
216 return r;
217
218 return size;
219}
220
221static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
222 char *buf)
223{
224 struct omap_overlay_manager_info info;
225
226 mgr->get_manager_info(mgr, &info);
227
228 return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
229}
230
231static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
232 const char *buf, size_t size)
233{
234 struct omap_overlay_manager_info info;
235 bool enable;
236 int r;
237
238 r = strtobool(buf, &enable);
239 if (r)
240 return r;
241
242 mgr->get_manager_info(mgr, &info);
243
244 info.trans_enabled = enable;
245
246 r = mgr->set_manager_info(mgr, &info);
247 if (r)
248 return r;
249
250 r = mgr->apply(mgr);
251 if (r)
252 return r;
253
254 return size;
255}
256
257static ssize_t manager_alpha_blending_enabled_show(
258 struct omap_overlay_manager *mgr, char *buf)
259{
260 struct omap_overlay_manager_info info;
261
262 mgr->get_manager_info(mgr, &info);
263
264 WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
265
266 return snprintf(buf, PAGE_SIZE, "%d\n",
267 info.partial_alpha_enabled);
268}
269
270static ssize_t manager_alpha_blending_enabled_store(
271 struct omap_overlay_manager *mgr,
272 const char *buf, size_t size)
273{
274 struct omap_overlay_manager_info info;
275 bool enable;
276 int r;
277
278 WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
279
280 r = strtobool(buf, &enable);
281 if (r)
282 return r;
283
284 mgr->get_manager_info(mgr, &info);
285
286 info.partial_alpha_enabled = enable;
287
288 r = mgr->set_manager_info(mgr, &info);
289 if (r)
290 return r;
291
292 r = mgr->apply(mgr);
293 if (r)
294 return r;
295
296 return size;
297}
298
299static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
300 char *buf)
301{
302 struct omap_overlay_manager_info info;
303
304 mgr->get_manager_info(mgr, &info);
305
306 return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
307}
308
309static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
310 const char *buf, size_t size)
311{
312 struct omap_overlay_manager_info info;
313 int r;
314 bool enable;
315
316 if (!dss_has_feature(FEAT_CPR))
317 return -ENODEV;
318
319 r = strtobool(buf, &enable);
320 if (r)
321 return r;
322
323 mgr->get_manager_info(mgr, &info);
324
325 if (info.cpr_enable == enable)
326 return size;
327
328 info.cpr_enable = enable;
329
330 r = mgr->set_manager_info(mgr, &info);
331 if (r)
332 return r;
333
334 r = mgr->apply(mgr);
335 if (r)
336 return r;
337
338 return size;
339}
340
341static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
342 char *buf)
343{
344 struct omap_overlay_manager_info info;
345
346 mgr->get_manager_info(mgr, &info);
347
348 return snprintf(buf, PAGE_SIZE,
349 "%d %d %d %d %d %d %d %d %d\n",
350 info.cpr_coefs.rr,
351 info.cpr_coefs.rg,
352 info.cpr_coefs.rb,
353 info.cpr_coefs.gr,
354 info.cpr_coefs.gg,
355 info.cpr_coefs.gb,
356 info.cpr_coefs.br,
357 info.cpr_coefs.bg,
358 info.cpr_coefs.bb);
359}
360
361static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
362 const char *buf, size_t size)
363{
364 struct omap_overlay_manager_info info;
365 struct omap_dss_cpr_coefs coefs;
366 int r, i;
367 s16 *arr;
368
369 if (!dss_has_feature(FEAT_CPR))
370 return -ENODEV;
371
372 if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
373 &coefs.rr, &coefs.rg, &coefs.rb,
374 &coefs.gr, &coefs.gg, &coefs.gb,
375 &coefs.br, &coefs.bg, &coefs.bb) != 9)
376 return -EINVAL;
377
378 arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
379 coefs.gr, coefs.gg, coefs.gb,
380 coefs.br, coefs.bg, coefs.bb };
381
382 for (i = 0; i < 9; ++i) {
383 if (arr[i] < -512 || arr[i] > 511)
384 return -EINVAL;
385 }
386
387 mgr->get_manager_info(mgr, &info);
388
389 info.cpr_coefs = coefs;
390
391 r = mgr->set_manager_info(mgr, &info);
392 if (r)
393 return r;
394
395 r = mgr->apply(mgr);
396 if (r)
397 return r;
398
399 return size;
400}
401
402struct manager_attribute {
403 struct attribute attr;
404 ssize_t (*show)(struct omap_overlay_manager *, char *);
405 ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
406};
407
408#define MANAGER_ATTR(_name, _mode, _show, _store) \
409 struct manager_attribute manager_attr_##_name = \
410 __ATTR(_name, _mode, _show, _store)
411
412static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
413static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
414 manager_display_show, manager_display_store);
415static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
416 manager_default_color_show, manager_default_color_store);
417static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
418 manager_trans_key_type_show, manager_trans_key_type_store);
419static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
420 manager_trans_key_value_show, manager_trans_key_value_store);
421static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
422 manager_trans_key_enabled_show,
423 manager_trans_key_enabled_store);
424static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
425 manager_alpha_blending_enabled_show,
426 manager_alpha_blending_enabled_store);
427static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
428 manager_cpr_enable_show,
429 manager_cpr_enable_store);
430static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
431 manager_cpr_coef_show,
432 manager_cpr_coef_store);
433
434
435static struct attribute *manager_sysfs_attrs[] = {
436 &manager_attr_name.attr,
437 &manager_attr_display.attr,
438 &manager_attr_default_color.attr,
439 &manager_attr_trans_key_type.attr,
440 &manager_attr_trans_key_value.attr,
441 &manager_attr_trans_key_enabled.attr,
442 &manager_attr_alpha_blending_enabled.attr,
443 &manager_attr_cpr_enable.attr,
444 &manager_attr_cpr_coef.attr,
445 NULL
446};
447
448static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
449 char *buf)
450{
451 struct omap_overlay_manager *manager;
452 struct manager_attribute *manager_attr;
453
454 manager = container_of(kobj, struct omap_overlay_manager, kobj);
455 manager_attr = container_of(attr, struct manager_attribute, attr);
456
457 if (!manager_attr->show)
458 return -ENOENT;
459
460 return manager_attr->show(manager, buf);
461}
462
463static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
464 const char *buf, size_t size)
465{
466 struct omap_overlay_manager *manager;
467 struct manager_attribute *manager_attr;
468
469 manager = container_of(kobj, struct omap_overlay_manager, kobj);
470 manager_attr = container_of(attr, struct manager_attribute, attr);
471
472 if (!manager_attr->store)
473 return -ENOENT;
474
475 return manager_attr->store(manager, buf, size);
476}
477
478static const struct sysfs_ops manager_sysfs_ops = {
479 .show = manager_attr_show,
480 .store = manager_attr_store,
481};
482
483static struct kobj_type manager_ktype = {
484 .sysfs_ops = &manager_sysfs_ops,
485 .default_attrs = manager_sysfs_attrs,
486};
487
488int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
489 struct platform_device *pdev)
490{
491 return kobject_init_and_add(&mgr->kobj, &manager_ktype,
492 &pdev->dev.kobj, "manager%d", mgr->id);
493}
494
495void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
496{
497 kobject_del(&mgr->kobj);
498 kobject_put(&mgr->kobj);
499}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fadc82d..383314f222b0 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,460 +36,6 @@
36static int num_managers; 36static int num_managers;
37static struct omap_overlay_manager *managers; 37static struct omap_overlay_manager *managers;
38 38
39static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
40{
41 return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
42}
43
44static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
45{
46 return snprintf(buf, PAGE_SIZE, "%s\n",
47 mgr->device ? mgr->device->name : "<none>");
48}
49
50static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
51 const char *buf, size_t size)
52{
53 int r = 0;
54 size_t len = size;
55 struct omap_dss_device *dssdev = NULL;
56
57 int match(struct omap_dss_device *dssdev, void *data)
58 {
59 const char *str = data;
60 return sysfs_streq(dssdev->name, str);
61 }
62
63 if (buf[size-1] == '\n')
64 --len;
65
66 if (len > 0)
67 dssdev = omap_dss_find_device((void *)buf, match);
68
69 if (len > 0 && dssdev == NULL)
70 return -EINVAL;
71
72 if (dssdev)
73 DSSDBG("display %s found\n", dssdev->name);
74
75 if (mgr->device) {
76 r = mgr->unset_device(mgr);
77 if (r) {
78 DSSERR("failed to unset display\n");
79 goto put_device;
80 }
81 }
82
83 if (dssdev) {
84 r = mgr->set_device(mgr, dssdev);
85 if (r) {
86 DSSERR("failed to set manager\n");
87 goto put_device;
88 }
89
90 r = mgr->apply(mgr);
91 if (r) {
92 DSSERR("failed to apply dispc config\n");
93 goto put_device;
94 }
95 }
96
97put_device:
98 if (dssdev)
99 omap_dss_put_device(dssdev);
100
101 return r ? r : size;
102}
103
104static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
105 char *buf)
106{
107 struct omap_overlay_manager_info info;
108
109 mgr->get_manager_info(mgr, &info);
110
111 return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
112}
113
114static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
115 const char *buf, size_t size)
116{
117 struct omap_overlay_manager_info info;
118 u32 color;
119 int r;
120
121 r = kstrtouint(buf, 0, &color);
122 if (r)
123 return r;
124
125 mgr->get_manager_info(mgr, &info);
126
127 info.default_color = color;
128
129 r = mgr->set_manager_info(mgr, &info);
130 if (r)
131 return r;
132
133 r = mgr->apply(mgr);
134 if (r)
135 return r;
136
137 return size;
138}
139
140static const char *trans_key_type_str[] = {
141 "gfx-destination",
142 "video-source",
143};
144
145static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
146 char *buf)
147{
148 enum omap_dss_trans_key_type key_type;
149 struct omap_overlay_manager_info info;
150
151 mgr->get_manager_info(mgr, &info);
152
153 key_type = info.trans_key_type;
154 BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
155
156 return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
157}
158
159static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
160 const char *buf, size_t size)
161{
162 enum omap_dss_trans_key_type key_type;
163 struct omap_overlay_manager_info info;
164 int r;
165
166 for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
167 key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
168 if (sysfs_streq(buf, trans_key_type_str[key_type]))
169 break;
170 }
171
172 if (key_type == ARRAY_SIZE(trans_key_type_str))
173 return -EINVAL;
174
175 mgr->get_manager_info(mgr, &info);
176
177 info.trans_key_type = key_type;
178
179 r = mgr->set_manager_info(mgr, &info);
180 if (r)
181 return r;
182
183 r = mgr->apply(mgr);
184 if (r)
185 return r;
186
187 return size;
188}
189
190static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
191 char *buf)
192{
193 struct omap_overlay_manager_info info;
194
195 mgr->get_manager_info(mgr, &info);
196
197 return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
198}
199
200static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
201 const char *buf, size_t size)
202{
203 struct omap_overlay_manager_info info;
204 u32 key_value;
205 int r;
206
207 r = kstrtouint(buf, 0, &key_value);
208 if (r)
209 return r;
210
211 mgr->get_manager_info(mgr, &info);
212
213 info.trans_key = key_value;
214
215 r = mgr->set_manager_info(mgr, &info);
216 if (r)
217 return r;
218
219 r = mgr->apply(mgr);
220 if (r)
221 return r;
222
223 return size;
224}
225
226static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
227 char *buf)
228{
229 struct omap_overlay_manager_info info;
230
231 mgr->get_manager_info(mgr, &info);
232
233 return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
234}
235
236static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
237 const char *buf, size_t size)
238{
239 struct omap_overlay_manager_info info;
240 bool enable;
241 int r;
242
243 r = strtobool(buf, &enable);
244 if (r)
245 return r;
246
247 mgr->get_manager_info(mgr, &info);
248
249 info.trans_enabled = enable;
250
251 r = mgr->set_manager_info(mgr, &info);
252 if (r)
253 return r;
254
255 r = mgr->apply(mgr);
256 if (r)
257 return r;
258
259 return size;
260}
261
262static ssize_t manager_alpha_blending_enabled_show(
263 struct omap_overlay_manager *mgr, char *buf)
264{
265 struct omap_overlay_manager_info info;
266
267 mgr->get_manager_info(mgr, &info);
268
269 WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
270
271 return snprintf(buf, PAGE_SIZE, "%d\n",
272 info.partial_alpha_enabled);
273}
274
275static ssize_t manager_alpha_blending_enabled_store(
276 struct omap_overlay_manager *mgr,
277 const char *buf, size_t size)
278{
279 struct omap_overlay_manager_info info;
280 bool enable;
281 int r;
282
283 WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
284
285 r = strtobool(buf, &enable);
286 if (r)
287 return r;
288
289 mgr->get_manager_info(mgr, &info);
290
291 info.partial_alpha_enabled = enable;
292
293 r = mgr->set_manager_info(mgr, &info);
294 if (r)
295 return r;
296
297 r = mgr->apply(mgr);
298 if (r)
299 return r;
300
301 return size;
302}
303
304static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
305 char *buf)
306{
307 struct omap_overlay_manager_info info;
308
309 mgr->get_manager_info(mgr, &info);
310
311 return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
312}
313
314static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
315 const char *buf, size_t size)
316{
317 struct omap_overlay_manager_info info;
318 int r;
319 bool enable;
320
321 if (!dss_has_feature(FEAT_CPR))
322 return -ENODEV;
323
324 r = strtobool(buf, &enable);
325 if (r)
326 return r;
327
328 mgr->get_manager_info(mgr, &info);
329
330 if (info.cpr_enable == enable)
331 return size;
332
333 info.cpr_enable = enable;
334
335 r = mgr->set_manager_info(mgr, &info);
336 if (r)
337 return r;
338
339 r = mgr->apply(mgr);
340 if (r)
341 return r;
342
343 return size;
344}
345
346static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
347 char *buf)
348{
349 struct omap_overlay_manager_info info;
350
351 mgr->get_manager_info(mgr, &info);
352
353 return snprintf(buf, PAGE_SIZE,
354 "%d %d %d %d %d %d %d %d %d\n",
355 info.cpr_coefs.rr,
356 info.cpr_coefs.rg,
357 info.cpr_coefs.rb,
358 info.cpr_coefs.gr,
359 info.cpr_coefs.gg,
360 info.cpr_coefs.gb,
361 info.cpr_coefs.br,
362 info.cpr_coefs.bg,
363 info.cpr_coefs.bb);
364}
365
366static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
367 const char *buf, size_t size)
368{
369 struct omap_overlay_manager_info info;
370 struct omap_dss_cpr_coefs coefs;
371 int r, i;
372 s16 *arr;
373
374 if (!dss_has_feature(FEAT_CPR))
375 return -ENODEV;
376
377 if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
378 &coefs.rr, &coefs.rg, &coefs.rb,
379 &coefs.gr, &coefs.gg, &coefs.gb,
380 &coefs.br, &coefs.bg, &coefs.bb) != 9)
381 return -EINVAL;
382
383 arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
384 coefs.gr, coefs.gg, coefs.gb,
385 coefs.br, coefs.bg, coefs.bb };
386
387 for (i = 0; i < 9; ++i) {
388 if (arr[i] < -512 || arr[i] > 511)
389 return -EINVAL;
390 }
391
392 mgr->get_manager_info(mgr, &info);
393
394 info.cpr_coefs = coefs;
395
396 r = mgr->set_manager_info(mgr, &info);
397 if (r)
398 return r;
399
400 r = mgr->apply(mgr);
401 if (r)
402 return r;
403
404 return size;
405}
406
407struct manager_attribute {
408 struct attribute attr;
409 ssize_t (*show)(struct omap_overlay_manager *, char *);
410 ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
411};
412
413#define MANAGER_ATTR(_name, _mode, _show, _store) \
414 struct manager_attribute manager_attr_##_name = \
415 __ATTR(_name, _mode, _show, _store)
416
417static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
418static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
419 manager_display_show, manager_display_store);
420static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
421 manager_default_color_show, manager_default_color_store);
422static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
423 manager_trans_key_type_show, manager_trans_key_type_store);
424static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
425 manager_trans_key_value_show, manager_trans_key_value_store);
426static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
427 manager_trans_key_enabled_show,
428 manager_trans_key_enabled_store);
429static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
430 manager_alpha_blending_enabled_show,
431 manager_alpha_blending_enabled_store);
432static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
433 manager_cpr_enable_show,
434 manager_cpr_enable_store);
435static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
436 manager_cpr_coef_show,
437 manager_cpr_coef_store);
438
439
440static struct attribute *manager_sysfs_attrs[] = {
441 &manager_attr_name.attr,
442 &manager_attr_display.attr,
443 &manager_attr_default_color.attr,
444 &manager_attr_trans_key_type.attr,
445 &manager_attr_trans_key_value.attr,
446 &manager_attr_trans_key_enabled.attr,
447 &manager_attr_alpha_blending_enabled.attr,
448 &manager_attr_cpr_enable.attr,
449 &manager_attr_cpr_coef.attr,
450 NULL
451};
452
453static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
454 char *buf)
455{
456 struct omap_overlay_manager *manager;
457 struct manager_attribute *manager_attr;
458
459 manager = container_of(kobj, struct omap_overlay_manager, kobj);
460 manager_attr = container_of(attr, struct manager_attribute, attr);
461
462 if (!manager_attr->show)
463 return -ENOENT;
464
465 return manager_attr->show(manager, buf);
466}
467
468static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
469 const char *buf, size_t size)
470{
471 struct omap_overlay_manager *manager;
472 struct manager_attribute *manager_attr;
473
474 manager = container_of(kobj, struct omap_overlay_manager, kobj);
475 manager_attr = container_of(attr, struct manager_attribute, attr);
476
477 if (!manager_attr->store)
478 return -ENOENT;
479
480 return manager_attr->store(manager, buf, size);
481}
482
483static const struct sysfs_ops manager_sysfs_ops = {
484 .show = manager_attr_show,
485 .store = manager_attr_store,
486};
487
488static struct kobj_type manager_ktype = {
489 .sysfs_ops = &manager_sysfs_ops,
490 .default_attrs = manager_sysfs_attrs,
491};
492
493static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) 39static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
494{ 40{
495 unsigned long timeout = msecs_to_jiffies(500); 41 unsigned long timeout = msecs_to_jiffies(500);
@@ -561,9 +107,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
561 107
562 INIT_LIST_HEAD(&mgr->overlays); 108 INIT_LIST_HEAD(&mgr->overlays);
563 109
564 r = kobject_init_and_add(&mgr->kobj, &manager_ktype, 110 r = dss_manager_kobj_init(mgr, pdev);
565 &pdev->dev.kobj, "manager%d", i);
566
567 if (r) 111 if (r)
568 DSSERR("failed to create sysfs file\n"); 112 DSSERR("failed to create sysfs file\n");
569 } 113 }
@@ -577,9 +121,7 @@ void dss_uninit_overlay_managers(struct platform_device *pdev)
577 121
578 for (i = 0; i < num_managers; ++i) { 122 for (i = 0; i < num_managers; ++i) {
579 struct omap_overlay_manager *mgr = &managers[i]; 123 struct omap_overlay_manager *mgr = &managers[i];
580 124 dss_manager_kobj_uninit(mgr);
581 kobject_del(&mgr->kobj);
582 kobject_put(&mgr->kobj);
583 } 125 }
584 126
585 kfree(managers); 127 kfree(managers);
diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/omap2/dss/overlay-sysfs.c
new file mode 100644
index 000000000000..4cc5ddebfb34
--- /dev/null
+++ b/drivers/video/omap2/dss/overlay-sysfs.c
@@ -0,0 +1,456 @@
1/*
2 * Copyright (C) 2009 Nokia Corporation
3 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
4 *
5 * Some code and ideas taken from drivers/video/omap/ driver
6 * by Imre Deak.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#define DSS_SUBSYS_NAME "OVERLAY"
22
23#include <linux/module.h>
24#include <linux/err.h>
25#include <linux/sysfs.h>
26#include <linux/kobject.h>
27#include <linux/platform_device.h>
28
29#include <video/omapdss.h>
30
31#include "dss.h"
32#include "dss_features.h"
33
34static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
35{
36 return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
37}
38
39static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
40{
41 return snprintf(buf, PAGE_SIZE, "%s\n",
42 ovl->manager ? ovl->manager->name : "<none>");
43}
44
45static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
46 size_t size)
47{
48 int i, r;
49 struct omap_overlay_manager *mgr = NULL;
50 struct omap_overlay_manager *old_mgr;
51 int len = size;
52
53 if (buf[size-1] == '\n')
54 --len;
55
56 if (len > 0) {
57 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
58 mgr = omap_dss_get_overlay_manager(i);
59
60 if (sysfs_streq(buf, mgr->name))
61 break;
62
63 mgr = NULL;
64 }
65 }
66
67 if (len > 0 && mgr == NULL)
68 return -EINVAL;
69
70 if (mgr)
71 DSSDBG("manager %s found\n", mgr->name);
72
73 if (mgr == ovl->manager)
74 return size;
75
76 old_mgr = ovl->manager;
77
78 r = dispc_runtime_get();
79 if (r)
80 return r;
81
82 /* detach old manager */
83 if (old_mgr) {
84 r = ovl->unset_manager(ovl);
85 if (r) {
86 DSSERR("detach failed\n");
87 goto err;
88 }
89
90 r = old_mgr->apply(old_mgr);
91 if (r)
92 goto err;
93 }
94
95 if (mgr) {
96 r = ovl->set_manager(ovl, mgr);
97 if (r) {
98 DSSERR("Failed to attach overlay\n");
99 goto err;
100 }
101
102 r = mgr->apply(mgr);
103 if (r)
104 goto err;
105 }
106
107 dispc_runtime_put();
108
109 return size;
110
111err:
112 dispc_runtime_put();
113 return r;
114}
115
116static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
117{
118 struct omap_overlay_info info;
119
120 ovl->get_overlay_info(ovl, &info);
121
122 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
123 info.width, info.height);
124}
125
126static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
127{
128 struct omap_overlay_info info;
129
130 ovl->get_overlay_info(ovl, &info);
131
132 return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
133}
134
135static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
136{
137 struct omap_overlay_info info;
138
139 ovl->get_overlay_info(ovl, &info);
140
141 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
142 info.pos_x, info.pos_y);
143}
144
145static ssize_t overlay_position_store(struct omap_overlay *ovl,
146 const char *buf, size_t size)
147{
148 int r;
149 char *last;
150 struct omap_overlay_info info;
151
152 ovl->get_overlay_info(ovl, &info);
153
154 info.pos_x = simple_strtoul(buf, &last, 10);
155 ++last;
156 if (last - buf >= size)
157 return -EINVAL;
158
159 info.pos_y = simple_strtoul(last, &last, 10);
160
161 r = ovl->set_overlay_info(ovl, &info);
162 if (r)
163 return r;
164
165 if (ovl->manager) {
166 r = ovl->manager->apply(ovl->manager);
167 if (r)
168 return r;
169 }
170
171 return size;
172}
173
174static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
175{
176 struct omap_overlay_info info;
177
178 ovl->get_overlay_info(ovl, &info);
179
180 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
181 info.out_width, info.out_height);
182}
183
184static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
185 const char *buf, size_t size)
186{
187 int r;
188 char *last;
189 struct omap_overlay_info info;
190
191 ovl->get_overlay_info(ovl, &info);
192
193 info.out_width = simple_strtoul(buf, &last, 10);
194 ++last;
195 if (last - buf >= size)
196 return -EINVAL;
197
198 info.out_height = simple_strtoul(last, &last, 10);
199
200 r = ovl->set_overlay_info(ovl, &info);
201 if (r)
202 return r;
203
204 if (ovl->manager) {
205 r = ovl->manager->apply(ovl->manager);
206 if (r)
207 return r;
208 }
209
210 return size;
211}
212
213static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
214{
215 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
216}
217
218static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
219 size_t size)
220{
221 int r;
222 bool enable;
223
224 r = strtobool(buf, &enable);
225 if (r)
226 return r;
227
228 if (enable)
229 r = ovl->enable(ovl);
230 else
231 r = ovl->disable(ovl);
232
233 if (r)
234 return r;
235
236 return size;
237}
238
239static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
240{
241 struct omap_overlay_info info;
242
243 ovl->get_overlay_info(ovl, &info);
244
245 return snprintf(buf, PAGE_SIZE, "%d\n",
246 info.global_alpha);
247}
248
249static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
250 const char *buf, size_t size)
251{
252 int r;
253 u8 alpha;
254 struct omap_overlay_info info;
255
256 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
257 return -ENODEV;
258
259 r = kstrtou8(buf, 0, &alpha);
260 if (r)
261 return r;
262
263 ovl->get_overlay_info(ovl, &info);
264
265 info.global_alpha = alpha;
266
267 r = ovl->set_overlay_info(ovl, &info);
268 if (r)
269 return r;
270
271 if (ovl->manager) {
272 r = ovl->manager->apply(ovl->manager);
273 if (r)
274 return r;
275 }
276
277 return size;
278}
279
280static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
281 char *buf)
282{
283 struct omap_overlay_info info;
284
285 ovl->get_overlay_info(ovl, &info);
286
287 return snprintf(buf, PAGE_SIZE, "%d\n",
288 info.pre_mult_alpha);
289}
290
291static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
292 const char *buf, size_t size)
293{
294 int r;
295 u8 alpha;
296 struct omap_overlay_info info;
297
298 if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
299 return -ENODEV;
300
301 r = kstrtou8(buf, 0, &alpha);
302 if (r)
303 return r;
304
305 ovl->get_overlay_info(ovl, &info);
306
307 info.pre_mult_alpha = alpha;
308
309 r = ovl->set_overlay_info(ovl, &info);
310 if (r)
311 return r;
312
313 if (ovl->manager) {
314 r = ovl->manager->apply(ovl->manager);
315 if (r)
316 return r;
317 }
318
319 return size;
320}
321
322static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
323{
324 struct omap_overlay_info info;
325
326 ovl->get_overlay_info(ovl, &info);
327
328 return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
329}
330
331static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
332 const char *buf, size_t size)
333{
334 int r;
335 u8 zorder;
336 struct omap_overlay_info info;
337
338 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
339 return -ENODEV;
340
341 r = kstrtou8(buf, 0, &zorder);
342 if (r)
343 return r;
344
345 ovl->get_overlay_info(ovl, &info);
346
347 info.zorder = zorder;
348
349 r = ovl->set_overlay_info(ovl, &info);
350 if (r)
351 return r;
352
353 if (ovl->manager) {
354 r = ovl->manager->apply(ovl->manager);
355 if (r)
356 return r;
357 }
358
359 return size;
360}
361
362struct overlay_attribute {
363 struct attribute attr;
364 ssize_t (*show)(struct omap_overlay *, char *);
365 ssize_t (*store)(struct omap_overlay *, const char *, size_t);
366};
367
368#define OVERLAY_ATTR(_name, _mode, _show, _store) \
369 struct overlay_attribute overlay_attr_##_name = \
370 __ATTR(_name, _mode, _show, _store)
371
372static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
373static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
374 overlay_manager_show, overlay_manager_store);
375static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
376static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
377static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
378 overlay_position_show, overlay_position_store);
379static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
380 overlay_output_size_show, overlay_output_size_store);
381static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
382 overlay_enabled_show, overlay_enabled_store);
383static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
384 overlay_global_alpha_show, overlay_global_alpha_store);
385static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
386 overlay_pre_mult_alpha_show,
387 overlay_pre_mult_alpha_store);
388static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
389 overlay_zorder_show, overlay_zorder_store);
390
391static struct attribute *overlay_sysfs_attrs[] = {
392 &overlay_attr_name.attr,
393 &overlay_attr_manager.attr,
394 &overlay_attr_input_size.attr,
395 &overlay_attr_screen_width.attr,
396 &overlay_attr_position.attr,
397 &overlay_attr_output_size.attr,
398 &overlay_attr_enabled.attr,
399 &overlay_attr_global_alpha.attr,
400 &overlay_attr_pre_mult_alpha.attr,
401 &overlay_attr_zorder.attr,
402 NULL
403};
404
405static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
406 char *buf)
407{
408 struct omap_overlay *overlay;
409 struct overlay_attribute *overlay_attr;
410
411 overlay = container_of(kobj, struct omap_overlay, kobj);
412 overlay_attr = container_of(attr, struct overlay_attribute, attr);
413
414 if (!overlay_attr->show)
415 return -ENOENT;
416
417 return overlay_attr->show(overlay, buf);
418}
419
420static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
421 const char *buf, size_t size)
422{
423 struct omap_overlay *overlay;
424 struct overlay_attribute *overlay_attr;
425
426 overlay = container_of(kobj, struct omap_overlay, kobj);
427 overlay_attr = container_of(attr, struct overlay_attribute, attr);
428
429 if (!overlay_attr->store)
430 return -ENOENT;
431
432 return overlay_attr->store(overlay, buf, size);
433}
434
435static const struct sysfs_ops overlay_sysfs_ops = {
436 .show = overlay_attr_show,
437 .store = overlay_attr_store,
438};
439
440static struct kobj_type overlay_ktype = {
441 .sysfs_ops = &overlay_sysfs_ops,
442 .default_attrs = overlay_sysfs_attrs,
443};
444
445int dss_overlay_kobj_init(struct omap_overlay *ovl,
446 struct platform_device *pdev)
447{
448 return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
449 &pdev->dev.kobj, "overlay%d", ovl->id);
450}
451
452void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
453{
454 kobject_del(&ovl->kobj);
455 kobject_put(&ovl->kobj);
456}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fad9a81..e3d406875afd 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -26,13 +26,11 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/sysfs.h> 28#include <linux/sysfs.h>
29#include <linux/kobject.h>
30#include <linux/platform_device.h> 29#include <linux/platform_device.h>
31#include <linux/delay.h> 30#include <linux/delay.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
33 32
34#include <video/omapdss.h> 33#include <video/omapdss.h>
35#include <plat/cpu.h>
36 34
37#include "dss.h" 35#include "dss.h"
38#include "dss_features.h" 36#include "dss_features.h"
@@ -40,417 +38,6 @@
40static int num_overlays; 38static int num_overlays;
41static struct omap_overlay *overlays; 39static struct omap_overlay *overlays;
42 40
43static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
44{
45 return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
46}
47
48static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
49{
50 return snprintf(buf, PAGE_SIZE, "%s\n",
51 ovl->manager ? ovl->manager->name : "<none>");
52}
53
54static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
55 size_t size)
56{
57 int i, r;
58 struct omap_overlay_manager *mgr = NULL;
59 struct omap_overlay_manager *old_mgr;
60 int len = size;
61
62 if (buf[size-1] == '\n')
63 --len;
64
65 if (len > 0) {
66 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
67 mgr = omap_dss_get_overlay_manager(i);
68
69 if (sysfs_streq(buf, mgr->name))
70 break;
71
72 mgr = NULL;
73 }
74 }
75
76 if (len > 0 && mgr == NULL)
77 return -EINVAL;
78
79 if (mgr)
80 DSSDBG("manager %s found\n", mgr->name);
81
82 if (mgr == ovl->manager)
83 return size;
84
85 old_mgr = ovl->manager;
86
87 r = dispc_runtime_get();
88 if (r)
89 return r;
90
91 /* detach old manager */
92 if (old_mgr) {
93 r = ovl->unset_manager(ovl);
94 if (r) {
95 DSSERR("detach failed\n");
96 goto err;
97 }
98
99 r = old_mgr->apply(old_mgr);
100 if (r)
101 goto err;
102 }
103
104 if (mgr) {
105 r = ovl->set_manager(ovl, mgr);
106 if (r) {
107 DSSERR("Failed to attach overlay\n");
108 goto err;
109 }
110
111 r = mgr->apply(mgr);
112 if (r)
113 goto err;
114 }
115
116 dispc_runtime_put();
117
118 return size;
119
120err:
121 dispc_runtime_put();
122 return r;
123}
124
125static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
126{
127 struct omap_overlay_info info;
128
129 ovl->get_overlay_info(ovl, &info);
130
131 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
132 info.width, info.height);
133}
134
135static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
136{
137 struct omap_overlay_info info;
138
139 ovl->get_overlay_info(ovl, &info);
140
141 return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
142}
143
144static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
145{
146 struct omap_overlay_info info;
147
148 ovl->get_overlay_info(ovl, &info);
149
150 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
151 info.pos_x, info.pos_y);
152}
153
154static ssize_t overlay_position_store(struct omap_overlay *ovl,
155 const char *buf, size_t size)
156{
157 int r;
158 char *last;
159 struct omap_overlay_info info;
160
161 ovl->get_overlay_info(ovl, &info);
162
163 info.pos_x = simple_strtoul(buf, &last, 10);
164 ++last;
165 if (last - buf >= size)
166 return -EINVAL;
167
168 info.pos_y = simple_strtoul(last, &last, 10);
169
170 r = ovl->set_overlay_info(ovl, &info);
171 if (r)
172 return r;
173
174 if (ovl->manager) {
175 r = ovl->manager->apply(ovl->manager);
176 if (r)
177 return r;
178 }
179
180 return size;
181}
182
183static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
184{
185 struct omap_overlay_info info;
186
187 ovl->get_overlay_info(ovl, &info);
188
189 return snprintf(buf, PAGE_SIZE, "%d,%d\n",
190 info.out_width, info.out_height);
191}
192
193static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
194 const char *buf, size_t size)
195{
196 int r;
197 char *last;
198 struct omap_overlay_info info;
199
200 ovl->get_overlay_info(ovl, &info);
201
202 info.out_width = simple_strtoul(buf, &last, 10);
203 ++last;
204 if (last - buf >= size)
205 return -EINVAL;
206
207 info.out_height = simple_strtoul(last, &last, 10);
208
209 r = ovl->set_overlay_info(ovl, &info);
210 if (r)
211 return r;
212
213 if (ovl->manager) {
214 r = ovl->manager->apply(ovl->manager);
215 if (r)
216 return r;
217 }
218
219 return size;
220}
221
222static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
223{
224 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
225}
226
227static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
228 size_t size)
229{
230 int r;
231 bool enable;
232
233 r = strtobool(buf, &enable);
234 if (r)
235 return r;
236
237 if (enable)
238 r = ovl->enable(ovl);
239 else
240 r = ovl->disable(ovl);
241
242 if (r)
243 return r;
244
245 return size;
246}
247
248static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
249{
250 struct omap_overlay_info info;
251
252 ovl->get_overlay_info(ovl, &info);
253
254 return snprintf(buf, PAGE_SIZE, "%d\n",
255 info.global_alpha);
256}
257
258static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
259 const char *buf, size_t size)
260{
261 int r;
262 u8 alpha;
263 struct omap_overlay_info info;
264
265 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
266 return -ENODEV;
267
268 r = kstrtou8(buf, 0, &alpha);
269 if (r)
270 return r;
271
272 ovl->get_overlay_info(ovl, &info);
273
274 info.global_alpha = alpha;
275
276 r = ovl->set_overlay_info(ovl, &info);
277 if (r)
278 return r;
279
280 if (ovl->manager) {
281 r = ovl->manager->apply(ovl->manager);
282 if (r)
283 return r;
284 }
285
286 return size;
287}
288
289static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
290 char *buf)
291{
292 struct omap_overlay_info info;
293
294 ovl->get_overlay_info(ovl, &info);
295
296 return snprintf(buf, PAGE_SIZE, "%d\n",
297 info.pre_mult_alpha);
298}
299
300static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
301 const char *buf, size_t size)
302{
303 int r;
304 u8 alpha;
305 struct omap_overlay_info info;
306
307 if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
308 return -ENODEV;
309
310 r = kstrtou8(buf, 0, &alpha);
311 if (r)
312 return r;
313
314 ovl->get_overlay_info(ovl, &info);
315
316 info.pre_mult_alpha = alpha;
317
318 r = ovl->set_overlay_info(ovl, &info);
319 if (r)
320 return r;
321
322 if (ovl->manager) {
323 r = ovl->manager->apply(ovl->manager);
324 if (r)
325 return r;
326 }
327
328 return size;
329}
330
331static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
332{
333 struct omap_overlay_info info;
334
335 ovl->get_overlay_info(ovl, &info);
336
337 return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
338}
339
340static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
341 const char *buf, size_t size)
342{
343 int r;
344 u8 zorder;
345 struct omap_overlay_info info;
346
347 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
348 return -ENODEV;
349
350 r = kstrtou8(buf, 0, &zorder);
351 if (r)
352 return r;
353
354 ovl->get_overlay_info(ovl, &info);
355
356 info.zorder = zorder;
357
358 r = ovl->set_overlay_info(ovl, &info);
359 if (r)
360 return r;
361
362 if (ovl->manager) {
363 r = ovl->manager->apply(ovl->manager);
364 if (r)
365 return r;
366 }
367
368 return size;
369}
370
371struct overlay_attribute {
372 struct attribute attr;
373 ssize_t (*show)(struct omap_overlay *, char *);
374 ssize_t (*store)(struct omap_overlay *, const char *, size_t);
375};
376
377#define OVERLAY_ATTR(_name, _mode, _show, _store) \
378 struct overlay_attribute overlay_attr_##_name = \
379 __ATTR(_name, _mode, _show, _store)
380
381static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
382static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
383 overlay_manager_show, overlay_manager_store);
384static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
385static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
386static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
387 overlay_position_show, overlay_position_store);
388static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
389 overlay_output_size_show, overlay_output_size_store);
390static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
391 overlay_enabled_show, overlay_enabled_store);
392static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
393 overlay_global_alpha_show, overlay_global_alpha_store);
394static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
395 overlay_pre_mult_alpha_show,
396 overlay_pre_mult_alpha_store);
397static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
398 overlay_zorder_show, overlay_zorder_store);
399
400static struct attribute *overlay_sysfs_attrs[] = {
401 &overlay_attr_name.attr,
402 &overlay_attr_manager.attr,
403 &overlay_attr_input_size.attr,
404 &overlay_attr_screen_width.attr,
405 &overlay_attr_position.attr,
406 &overlay_attr_output_size.attr,
407 &overlay_attr_enabled.attr,
408 &overlay_attr_global_alpha.attr,
409 &overlay_attr_pre_mult_alpha.attr,
410 &overlay_attr_zorder.attr,
411 NULL
412};
413
414static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
415 char *buf)
416{
417 struct omap_overlay *overlay;
418 struct overlay_attribute *overlay_attr;
419
420 overlay = container_of(kobj, struct omap_overlay, kobj);
421 overlay_attr = container_of(attr, struct overlay_attribute, attr);
422
423 if (!overlay_attr->show)
424 return -ENOENT;
425
426 return overlay_attr->show(overlay, buf);
427}
428
429static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
430 const char *buf, size_t size)
431{
432 struct omap_overlay *overlay;
433 struct overlay_attribute *overlay_attr;
434
435 overlay = container_of(kobj, struct omap_overlay, kobj);
436 overlay_attr = container_of(attr, struct overlay_attribute, attr);
437
438 if (!overlay_attr->store)
439 return -ENOENT;
440
441 return overlay_attr->store(overlay, buf, size);
442}
443
444static const struct sysfs_ops overlay_sysfs_ops = {
445 .show = overlay_attr_show,
446 .store = overlay_attr_store,
447};
448
449static struct kobj_type overlay_ktype = {
450 .sysfs_ops = &overlay_sysfs_ops,
451 .default_attrs = overlay_sysfs_attrs,
452};
453
454int omap_dss_get_num_overlays(void) 41int omap_dss_get_num_overlays(void)
455{ 42{
456 return num_overlays; 43 return num_overlays;
@@ -512,9 +99,7 @@ void dss_init_overlays(struct platform_device *pdev)
512 ovl->supported_modes = 99 ovl->supported_modes =
513 dss_feat_get_supported_color_modes(ovl->id); 100 dss_feat_get_supported_color_modes(ovl->id);
514 101
515 r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, 102 r = dss_overlay_kobj_init(ovl, pdev);
516 &pdev->dev.kobj, "overlay%d", i);
517
518 if (r) 103 if (r)
519 DSSERR("failed to create sysfs file\n"); 104 DSSERR("failed to create sysfs file\n");
520 } 105 }
@@ -595,9 +180,7 @@ void dss_uninit_overlays(struct platform_device *pdev)
595 180
596 for (i = 0; i < num_overlays; ++i) { 181 for (i = 0; i < num_overlays; ++i) {
597 struct omap_overlay *ovl = &overlays[i]; 182 struct omap_overlay *ovl = &overlays[i];
598 183 dss_overlay_kobj_uninit(ovl);
599 kobject_del(&ovl->kobj);
600 kobject_put(&ovl->kobj);
601 } 184 }
602 185
603 kfree(overlays); 186 kfree(overlays);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9d8710..2e520d3085c8 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -939,7 +939,6 @@ EXPORT_SYMBOL(omapdss_rfbi_display_disable);
939static int __init rfbi_init_display(struct omap_dss_device *dssdev) 939static int __init rfbi_init_display(struct omap_dss_device *dssdev)
940{ 940{
941 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; 941 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
942 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
943 return 0; 942 return 0;
944} 943}
945 944
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe29585..c87e07ebb16d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -152,17 +152,7 @@ EXPORT_SYMBOL(omapdss_sdi_display_disable);
152void omapdss_sdi_set_timings(struct omap_dss_device *dssdev, 152void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
153 struct omap_video_timings *timings) 153 struct omap_video_timings *timings)
154{ 154{
155 int r;
156
157 sdi.timings = *timings; 155 sdi.timings = *timings;
158
159 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
160 omapdss_sdi_display_disable(dssdev);
161
162 r = omapdss_sdi_display_enable(dssdev);
163 if (r)
164 DSSERR("failed to set new timings\n");
165 }
166} 156}
167EXPORT_SYMBOL(omapdss_sdi_set_timings); 157EXPORT_SYMBOL(omapdss_sdi_set_timings);
168 158
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 4a6caf9c6da3..17b31029a793 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -36,7 +36,6 @@
36#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37 37
38#include <video/omapdss.h> 38#include <video/omapdss.h>
39#include <plat/cpu.h>
40 39
41#include "dss.h" 40#include "dss.h"
42#include "dss_features.h" 41#include "dss_features.h"
@@ -565,19 +564,6 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
565 564
566 venc.timings = *timings; 565 venc.timings = *timings;
567 566
568 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
569 int r;
570
571 /* turn the venc off and on to get new timings to use */
572 venc_power_off(dssdev);
573
574 r = venc_power_on(dssdev);
575 if (r)
576 DSSERR("failed to power on VENC\n");
577 } else {
578 dss_mgr_set_timings(dssdev->manager, timings);
579 }
580
581 mutex_unlock(&venc.venc_lock); 567 mutex_unlock(&venc.venc_lock);
582} 568}
583 569
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3d8004..7afdfcf3bac8 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1592,6 +1592,20 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
1592 return 0; 1592 return 0;
1593} 1593}
1594 1594
1595static void omapfb_clear_fb(struct fb_info *fbi)
1596{
1597 const struct fb_fillrect rect = {
1598 .dx = 0,
1599 .dy = 0,
1600 .width = fbi->var.xres_virtual,
1601 .height = fbi->var.yres_virtual,
1602 .color = 0,
1603 .rop = ROP_COPY,
1604 };
1605
1606 cfb_fillrect(fbi, &rect);
1607}
1608
1595int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) 1609int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1596{ 1610{
1597 struct omapfb_info *ofbi = FB2OFB(fbi); 1611 struct omapfb_info *ofbi = FB2OFB(fbi);
@@ -1661,6 +1675,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1661 goto err; 1675 goto err;
1662 } 1676 }
1663 1677
1678 omapfb_clear_fb(fbi);
1679
1664 return 0; 1680 return 0;
1665err: 1681err:
1666 omapfb_free_fbmem(fbi); 1682 omapfb_free_fbmem(fbi);
@@ -1972,6 +1988,16 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1972 } 1988 }
1973 } 1989 }
1974 1990
1991 for (i = 0; i < fbdev->num_fbs; i++) {
1992 struct fb_info *fbi = fbdev->fbs[i];
1993 struct omapfb_info *ofbi = FB2OFB(fbi);
1994
1995 if (ofbi->region->size == 0)
1996 continue;
1997
1998 omapfb_clear_fb(fbi);
1999 }
2000
1975 /* Enable fb0 */ 2001 /* Enable fb0 */
1976 if (fbdev->num_fbs > 0) { 2002 if (fbdev->num_fbs > 0) {
1977 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]); 2003 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 87e421e25afe..f2b15c4a75bc 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -34,7 +34,6 @@
34#include <asm/setup.h> 34#include <asm/setup.h>
35 35
36#include <plat/vram.h> 36#include <plat/vram.h>
37#include <plat/dma.h>
38 37
39#ifdef DEBUG 38#ifdef DEBUG
40#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__) 39#define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
@@ -250,59 +249,6 @@ int omap_vram_reserve(unsigned long paddr, size_t size)
250} 249}
251EXPORT_SYMBOL(omap_vram_reserve); 250EXPORT_SYMBOL(omap_vram_reserve);
252 251
253static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
254{
255 struct completion *compl = data;
256 complete(compl);
257}
258
259static int _omap_vram_clear(u32 paddr, unsigned pages)
260{
261 struct completion compl;
262 unsigned elem_count;
263 unsigned frame_count;
264 int r;
265 int lch;
266
267 init_completion(&compl);
268
269 r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
270 _omap_vram_dma_cb,
271 &compl, &lch);
272 if (r) {
273 pr_err("VRAM: request_dma failed for memory clear\n");
274 return -EBUSY;
275 }
276
277 elem_count = pages * PAGE_SIZE / 4;
278 frame_count = 1;
279
280 omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
281 elem_count, frame_count,
282 OMAP_DMA_SYNC_ELEMENT,
283 0, 0);
284
285 omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
286 paddr, 0, 0);
287
288 omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
289
290 omap_start_dma(lch);
291
292 if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) {
293 omap_stop_dma(lch);
294 pr_err("VRAM: dma timeout while clearing memory\n");
295 r = -EIO;
296 goto err;
297 }
298
299 r = 0;
300err:
301 omap_free_dma(lch);
302
303 return r;
304}
305
306static int _omap_vram_alloc(unsigned pages, unsigned long *paddr) 252static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
307{ 253{
308 struct vram_region *rm; 254 struct vram_region *rm;
@@ -337,8 +283,6 @@ found:
337 283
338 *paddr = start; 284 *paddr = start;
339 285
340 _omap_vram_clear(start, pages);
341
342 return 0; 286 return 0;
343 } 287 }
344 288
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 9c7cca3746e1..ac2e4cca5a23 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -73,6 +73,7 @@ enum omap_plane {
73 OMAP_DSS_VIDEO1 = 1, 73 OMAP_DSS_VIDEO1 = 1,
74 OMAP_DSS_VIDEO2 = 2, 74 OMAP_DSS_VIDEO2 = 2,
75 OMAP_DSS_VIDEO3 = 3, 75 OMAP_DSS_VIDEO3 = 3,
76 OMAP_DSS_WB = 4,
76}; 77};
77 78
78enum omap_channel { 79enum omap_channel {
@@ -605,6 +606,8 @@ struct omap_dss_device {
605 606
606struct omap_dss_hdmi_data 607struct omap_dss_hdmi_data
607{ 608{
609 int ct_cp_hpd_gpio;
610 int ls_oe_gpio;
608 int hpd_gpio; 611 int hpd_gpio;
609}; 612};
610 613
@@ -736,6 +739,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
736void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); 739void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
737int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, 740int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
738 const struct omap_dsi_pin_config *pin_cfg); 741 const struct omap_dsi_pin_config *pin_cfg);
742int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
743 unsigned long ddr_clk, unsigned long lp_clk);
739 744
740int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); 745int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
741void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, 746void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,