diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-10 02:18:03 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-10 02:18:08 -0400 |
commit | 6cd05430eeab0668c55ff4693ab79ff559b2b5c7 (patch) | |
tree | 47f6de06e649c2fefaddf85c681a0d7e33b2a07a | |
parent | c50e86ce7c2961a41f2f7aa6e4fd6c99229ba205 (diff) | |
parent | b2f5976c109350977104f27211a7029ec67cd488 (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
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 | ||
604 | static 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 | |||
610 | static 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 | |||
622 | static 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 | |||
627 | static struct nokia_dsi_panel_data dsi1_panel = { | 604 | static 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 | ||
720 | static struct omap_dss_hdmi_data sdp4430_hdmi_data = { | 651 | static 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 | ||
411 | static 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 | |||
417 | static 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 | |||
429 | static 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 | |||
434 | static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { | 411 | static 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 | ||
261 | static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = { | ||
262 | REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"), | ||
263 | }; | ||
264 | |||
261 | static struct regulator_init_data omap4_vdac_idata = { | 265 | static 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 | ||
29 | static int palmte_panel_init(struct lcd_panel *panel, | 28 | static 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. */ | ||
135 | static 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 | ||
152 | static 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 | |||
158 | static void taal_esd_work(struct work_struct *work); | 162 | static void taal_esd_work(struct work_struct *work); |
159 | static void taal_ulps_work(struct work_struct *work); | 163 | static 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) | |||
371 | static int taal_enter_ulps(struct omap_dss_device *dssdev) | 375 | static 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: | |||
405 | static int taal_exit_ulps(struct omap_dss_device *dssdev) | 409 | static 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 | } |
444 | err1: | 449 | err1: |
@@ -835,94 +840,135 @@ static struct attribute_group taal_attr_group = { | |||
835 | static void taal_hw_reset(struct omap_dss_device *dssdev) | 840 | static 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 | ||
861 | static 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 | |||
857 | static int taal_probe(struct omap_dss_device *dssdev) | 879 | static 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) | |||
991 | err_vc_id: | 1012 | err_vc_id: |
992 | omap_dsi_release_vc(dssdev, td->channel); | 1013 | omap_dsi_release_vc(dssdev, td->channel); |
993 | err_req_vc: | 1014 | err_req_vc: |
994 | if (panel_data->use_ext_te) | ||
995 | free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); | ||
996 | err_irq: | ||
997 | if (panel_data->use_ext_te) | ||
998 | gpio_free(panel_data->ext_te_gpio); | ||
999 | err_gpio: | ||
1000 | if (bldev != NULL) | 1015 | if (bldev != NULL) |
1001 | backlight_device_unregister(bldev); | 1016 | backlight_device_unregister(bldev); |
1002 | err_bl: | 1017 | err_bl: |
1003 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
1004 | gpio_free(panel_data->reset_gpio); | ||
1005 | err_rst_gpio: | ||
1006 | destroy_workqueue(td->workqueue); | 1018 | destroy_workqueue(td->workqueue); |
1007 | err_wq: | ||
1008 | kfree(td); | ||
1009 | err: | ||
1010 | return r; | 1019 | return r; |
1011 | } | 1020 | } |
1012 | 1021 | ||
1013 | static void __exit taal_remove(struct omap_dss_device *dssdev) | 1022 | static 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 | ||
1050 | static int taal_power_on(struct omap_dss_device *dssdev) | 1047 | static 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) | |||
1424 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) | 1425 | static 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; |
148 | err_i2c: | ||
149 | if (gpio_is_valid(ddata->pd_gpio)) | ||
150 | gpio_free(ddata->pd_gpio); | ||
151 | return r; | ||
152 | } | 147 | } |
153 | 148 | ||
154 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) | 149 | static 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 @@ | |||
1 | obj-$(CONFIG_OMAP2_DSS) += omapdss.o | 1 | obj-$(CONFIG_OMAP2_DSS) += omapdss.o |
2 | omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ | 2 | omapdss-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 |
4 | omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o | 4 | omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o |
5 | omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o | 5 | omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o |
6 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o | 6 | omapdss-$(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 | ||
680 | static 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 | |||
707 | static void dss_write_regs(void) | 677 | static 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 | ||
987 | static void dss_apply_fifo_merge(bool use_fifo_merge) | 953 | static 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 | |||
996 | static 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 | ||
1011 | static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, | 968 | static 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 | ||
1026 | static void dss_setup_fifos(bool use_fifo_merge) | 982 | static 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 | ||
1038 | static 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 | |||
1061 | static 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 | |||
1090 | static 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 | |||
1113 | int dss_mgr_enable(struct omap_overlay_manager *mgr) | 994 | int 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(); | ||
1202 | out: | 1061 | out: |
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); | ||
1187 | out: | ||
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 | ||
1334 | static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, | 1191 | static 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 | |||
1368 | out: | 1215 | out: |
1369 | mutex_unlock(&apply_lock); | 1216 | spin_unlock_irqrestore(&data_lock, flags); |
1370 | } | 1217 | } |
1371 | 1218 | ||
1372 | int dss_ovl_set_info(struct omap_overlay *ovl, | 1219 | int 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 | |||
101 | static struct { | 105 | static 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 | ||
1066 | static void dispc_read_plane_fifo_sizes(void) | 1072 | static 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 | ||
1084 | static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) | 1119 | static 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 | ||
1089 | void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) | 1132 | void 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 | ||
3731 | static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { | 3775 | static 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 | ||
3742 | static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { | 3787 | static 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 | ||
3753 | static const struct dispc_features omap44xx_dispc_feats __initconst = { | 3799 | static 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 | ||
3764 | static int __init dispc_init_features(struct device *dev) | 3812 | static 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); | |||
278 | void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, | 277 | void 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 | } |
303 | EXPORT_SYMBOL(omapdss_dpi_set_timings); | 288 | EXPORT_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 | ||
1456 | static 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 | } | ||
1505 | found: | ||
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 | |||
1457 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 1518 | int 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 | } |
4111 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); | 4172 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); |
4112 | 4173 | ||
4174 | int 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; | ||
4232 | err: | ||
4233 | mutex_unlock(&dsi->lock); | ||
4234 | return r; | ||
4235 | } | ||
4236 | EXPORT_SYMBOL(omapdss_dsi_set_clocks); | ||
4237 | |||
4113 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | 4238 | int 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 | ||
257 | int dss_manager_kobj_init(struct omap_overlay_manager *mgr, | ||
258 | struct platform_device *pdev); | ||
259 | void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr); | ||
260 | |||
257 | /* overlay */ | 261 | /* overlay */ |
258 | void dss_init_overlays(struct platform_device *pdev); | 262 | void dss_init_overlays(struct platform_device *pdev); |
259 | void dss_uninit_overlays(struct platform_device *pdev); | 263 | void 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); |
266 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, | 270 | bool dss_ovl_use_replication(struct dss_lcd_mgr_config config, |
267 | enum omap_color_mode mode); | 271 | enum omap_color_mode mode); |
272 | int dss_overlay_kobj_init(struct omap_overlay *ovl, | ||
273 | struct platform_device *pdev); | ||
274 | void dss_overlay_kobj_uninit(struct omap_overlay *ovl); | ||
268 | 275 | ||
269 | /* DSS */ | 276 | /* DSS */ |
270 | int dss_init_platform_driver(void) __init; | 277 | int 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 | ||
315 | static int __init hdmi_init_display(struct omap_dss_device *dssdev) | 322 | static 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 | ||
356 | static 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 | |||
323 | static const struct hdmi_config *hdmi_find_timing( | 365 | static 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); |
527 | err_phy_enable: | 579 | err_phy_enable: |
528 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); | 580 | hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); |
529 | err: | 581 | err_pll_enable: |
530 | hdmi_runtime_put(); | 582 | hdmi_runtime_put(); |
583 | err_runtime_get: | ||
584 | regulator_disable(hdmi.vdda_hdmi_dac_reg); | ||
585 | err_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 | ||
544 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | 606 | int 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 | ||
638 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) | 688 | int 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 | ||
678 | err2: | ||
679 | if (dssdev->platform_disable) | ||
680 | dssdev->platform_disable(dssdev); | ||
681 | err1: | 719 | err1: |
682 | omap_dss_stop_device(dssdev); | 720 | omap_dss_stop_device(dssdev); |
683 | err0: | 721 | err0: |
@@ -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 | ||
981 | static 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 | |||
941 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | 988 | static 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 | |||
34 | static 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 | |||
39 | static 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 | |||
45 | static 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 | |||
92 | put_device: | ||
93 | if (dssdev) | ||
94 | omap_dss_put_device(dssdev); | ||
95 | |||
96 | return r ? r : size; | ||
97 | } | ||
98 | |||
99 | static 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 | |||
109 | static 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 | |||
135 | static const char *trans_key_type_str[] = { | ||
136 | "gfx-destination", | ||
137 | "video-source", | ||
138 | }; | ||
139 | |||
140 | static 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 | |||
154 | static 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 | |||
185 | static 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 | |||
195 | static 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 | |||
221 | static 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 | |||
231 | static 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 | |||
257 | static 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 | |||
270 | static 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 | |||
299 | static 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 | |||
309 | static 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 | |||
341 | static 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 | |||
361 | static 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 | |||
402 | struct 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 | |||
412 | static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); | ||
413 | static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, | ||
414 | manager_display_show, manager_display_store); | ||
415 | static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, | ||
416 | manager_default_color_show, manager_default_color_store); | ||
417 | static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, | ||
418 | manager_trans_key_type_show, manager_trans_key_type_store); | ||
419 | static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, | ||
420 | manager_trans_key_value_show, manager_trans_key_value_store); | ||
421 | static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, | ||
422 | manager_trans_key_enabled_show, | ||
423 | manager_trans_key_enabled_store); | ||
424 | static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, | ||
425 | manager_alpha_blending_enabled_show, | ||
426 | manager_alpha_blending_enabled_store); | ||
427 | static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, | ||
428 | manager_cpr_enable_show, | ||
429 | manager_cpr_enable_store); | ||
430 | static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, | ||
431 | manager_cpr_coef_show, | ||
432 | manager_cpr_coef_store); | ||
433 | |||
434 | |||
435 | static 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 | |||
448 | static 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 | |||
463 | static 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 | |||
478 | static const struct sysfs_ops manager_sysfs_ops = { | ||
479 | .show = manager_attr_show, | ||
480 | .store = manager_attr_store, | ||
481 | }; | ||
482 | |||
483 | static struct kobj_type manager_ktype = { | ||
484 | .sysfs_ops = &manager_sysfs_ops, | ||
485 | .default_attrs = manager_sysfs_attrs, | ||
486 | }; | ||
487 | |||
488 | int 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 | |||
495 | void 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 @@ | |||
36 | static int num_managers; | 36 | static int num_managers; |
37 | static struct omap_overlay_manager *managers; | 37 | static struct omap_overlay_manager *managers; |
38 | 38 | ||
39 | static 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 | |||
44 | static 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 | |||
50 | static 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 | |||
97 | put_device: | ||
98 | if (dssdev) | ||
99 | omap_dss_put_device(dssdev); | ||
100 | |||
101 | return r ? r : size; | ||
102 | } | ||
103 | |||
104 | static 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 | |||
114 | static 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 | |||
140 | static const char *trans_key_type_str[] = { | ||
141 | "gfx-destination", | ||
142 | "video-source", | ||
143 | }; | ||
144 | |||
145 | static 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 | |||
159 | static 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 | |||
190 | static 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 | |||
200 | static 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 | |||
226 | static 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 | |||
236 | static 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 | |||
262 | static 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 | |||
275 | static 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 | |||
304 | static 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 | |||
314 | static 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 | |||
346 | static 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 | |||
366 | static 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 | |||
407 | struct 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 | |||
417 | static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); | ||
418 | static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, | ||
419 | manager_display_show, manager_display_store); | ||
420 | static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, | ||
421 | manager_default_color_show, manager_default_color_store); | ||
422 | static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, | ||
423 | manager_trans_key_type_show, manager_trans_key_type_store); | ||
424 | static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, | ||
425 | manager_trans_key_value_show, manager_trans_key_value_store); | ||
426 | static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, | ||
427 | manager_trans_key_enabled_show, | ||
428 | manager_trans_key_enabled_store); | ||
429 | static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, | ||
430 | manager_alpha_blending_enabled_show, | ||
431 | manager_alpha_blending_enabled_store); | ||
432 | static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR, | ||
433 | manager_cpr_enable_show, | ||
434 | manager_cpr_enable_store); | ||
435 | static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR, | ||
436 | manager_cpr_coef_show, | ||
437 | manager_cpr_coef_store); | ||
438 | |||
439 | |||
440 | static 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 | |||
453 | static 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 | |||
468 | static 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 | |||
483 | static const struct sysfs_ops manager_sysfs_ops = { | ||
484 | .show = manager_attr_show, | ||
485 | .store = manager_attr_store, | ||
486 | }; | ||
487 | |||
488 | static struct kobj_type manager_ktype = { | ||
489 | .sysfs_ops = &manager_sysfs_ops, | ||
490 | .default_attrs = manager_sysfs_attrs, | ||
491 | }; | ||
492 | |||
493 | static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) | 39 | static 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 | |||
34 | static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf) | ||
35 | { | ||
36 | return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name); | ||
37 | } | ||
38 | |||
39 | static 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 | |||
45 | static 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 | |||
111 | err: | ||
112 | dispc_runtime_put(); | ||
113 | return r; | ||
114 | } | ||
115 | |||
116 | static 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 | |||
126 | static 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 | |||
135 | static 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 | |||
145 | static 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 | |||
174 | static 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 | |||
184 | static 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 | |||
213 | static 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 | |||
218 | static 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 | |||
239 | static 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 | |||
249 | static 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 | |||
280 | static 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 | |||
291 | static 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 | |||
322 | static 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 | |||
331 | static 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 | |||
362 | struct 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 | |||
372 | static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL); | ||
373 | static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR, | ||
374 | overlay_manager_show, overlay_manager_store); | ||
375 | static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL); | ||
376 | static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL); | ||
377 | static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR, | ||
378 | overlay_position_show, overlay_position_store); | ||
379 | static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR, | ||
380 | overlay_output_size_show, overlay_output_size_store); | ||
381 | static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR, | ||
382 | overlay_enabled_show, overlay_enabled_store); | ||
383 | static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, | ||
384 | overlay_global_alpha_show, overlay_global_alpha_store); | ||
385 | static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, | ||
386 | overlay_pre_mult_alpha_show, | ||
387 | overlay_pre_mult_alpha_store); | ||
388 | static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, | ||
389 | overlay_zorder_show, overlay_zorder_store); | ||
390 | |||
391 | static 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 | |||
405 | static 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 | |||
420 | static 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 | |||
435 | static const struct sysfs_ops overlay_sysfs_ops = { | ||
436 | .show = overlay_attr_show, | ||
437 | .store = overlay_attr_store, | ||
438 | }; | ||
439 | |||
440 | static struct kobj_type overlay_ktype = { | ||
441 | .sysfs_ops = &overlay_sysfs_ops, | ||
442 | .default_attrs = overlay_sysfs_attrs, | ||
443 | }; | ||
444 | |||
445 | int 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 | |||
452 | void 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 @@ | |||
40 | static int num_overlays; | 38 | static int num_overlays; |
41 | static struct omap_overlay *overlays; | 39 | static struct omap_overlay *overlays; |
42 | 40 | ||
43 | static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf) | ||
44 | { | ||
45 | return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name); | ||
46 | } | ||
47 | |||
48 | static 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 | |||
54 | static 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 | |||
120 | err: | ||
121 | dispc_runtime_put(); | ||
122 | return r; | ||
123 | } | ||
124 | |||
125 | static 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 | |||
135 | static 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 | |||
144 | static 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 | |||
154 | static 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 | |||
183 | static 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 | |||
193 | static 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 | |||
222 | static 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 | |||
227 | static 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 | |||
248 | static 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 | |||
258 | static 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 | |||
289 | static 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 | |||
300 | static 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 | |||
331 | static 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 | |||
340 | static 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 | |||
371 | struct 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 | |||
381 | static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL); | ||
382 | static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR, | ||
383 | overlay_manager_show, overlay_manager_store); | ||
384 | static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL); | ||
385 | static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL); | ||
386 | static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR, | ||
387 | overlay_position_show, overlay_position_store); | ||
388 | static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR, | ||
389 | overlay_output_size_show, overlay_output_size_store); | ||
390 | static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR, | ||
391 | overlay_enabled_show, overlay_enabled_store); | ||
392 | static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, | ||
393 | overlay_global_alpha_show, overlay_global_alpha_store); | ||
394 | static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, | ||
395 | overlay_pre_mult_alpha_show, | ||
396 | overlay_pre_mult_alpha_store); | ||
397 | static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, | ||
398 | overlay_zorder_show, overlay_zorder_store); | ||
399 | |||
400 | static 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 | |||
414 | static 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 | |||
429 | static 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 | |||
444 | static const struct sysfs_ops overlay_sysfs_ops = { | ||
445 | .show = overlay_attr_show, | ||
446 | .store = overlay_attr_store, | ||
447 | }; | ||
448 | |||
449 | static struct kobj_type overlay_ktype = { | ||
450 | .sysfs_ops = &overlay_sysfs_ops, | ||
451 | .default_attrs = overlay_sysfs_attrs, | ||
452 | }; | ||
453 | |||
454 | int omap_dss_get_num_overlays(void) | 41 | int 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); | |||
939 | static int __init rfbi_init_display(struct omap_dss_device *dssdev) | 939 | static 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); | |||
152 | void omapdss_sdi_set_timings(struct omap_dss_device *dssdev, | 152 | void 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 | } |
167 | EXPORT_SYMBOL(omapdss_sdi_set_timings); | 157 | EXPORT_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 | ||
1595 | static 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 | |||
1595 | int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) | 1609 | int 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; |
1665 | err: | 1681 | err: |
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 | } |
251 | EXPORT_SYMBOL(omap_vram_reserve); | 250 | EXPORT_SYMBOL(omap_vram_reserve); |
252 | 251 | ||
253 | static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data) | ||
254 | { | ||
255 | struct completion *compl = data; | ||
256 | complete(compl); | ||
257 | } | ||
258 | |||
259 | static 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; | ||
300 | err: | ||
301 | omap_free_dma(lch); | ||
302 | |||
303 | return r; | ||
304 | } | ||
305 | |||
306 | static int _omap_vram_alloc(unsigned pages, unsigned long *paddr) | 252 | static 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 | ||
78 | enum omap_channel { | 79 | enum omap_channel { |
@@ -605,6 +606,8 @@ struct omap_dss_device { | |||
605 | 606 | ||
606 | struct omap_dss_hdmi_data | 607 | struct 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); | |||
736 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); | 739 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); |
737 | int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | 740 | int 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); |
742 | int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, | ||
743 | unsigned long ddr_clk, unsigned long lp_clk); | ||
739 | 744 | ||
740 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); | 745 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); |
741 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, | 746 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, |