aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-04-03 15:45:49 -0400
committerDave Airlie <airlied@redhat.com>2017-04-03 15:45:49 -0400
commite1b489d207c73e67810659a88c45b8db4bd62773 (patch)
tree5b43e024c00391db18f83e6285b2b280953df39b
parent320d8c3d38739fa8e31a076b86cbdafcf8897d5e (diff)
parente8e13b1521678af0df7b07f30745d77e8de1820a (diff)
Merge tag 'omapdrm-4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux into drm-next
omapdrm changes for 4.12 Main changes include: * Add support for render nodes. * Refactor omapdss code to allow multiple DISPC implementations. This is pre-work for DSS6 support. * Fix replication logic bug, which caused RGB565 fb to be shown too dark on a 24bit display. * Improve detection of display stack readiness, which should remove the probe order issues. * Link panel-dpi with its backlight, so that they are turned on/off in sync. * Fix possibly incorrect setup of sync and data-enable signals. * Get rid of DRM_OMAP_NUM_CRTCS config option. * tag 'omapdrm-4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (34 commits) drm/omap: Major omap_modeset_init() cleanup drm/omap: Remove the obsolete #define omap_plane _omap_plane hack drm/omap: Fix one ugly indentation style break left by coccinelle drm/omap: Rename enum omap_plane to enum omap_plane_id drm/omap: Get rid of DRM_OMAP_NUM_CRTCS config option drm/omap: fix crash on module unload drm/omap: use drm_atomic_helper_shutdown() drm/omap: fix display SYNC/DE flags drm/omap: dispc: improve debug print of display flags drm/omap: displays: panel-dpi: Support for handling backlight devices drm/omap: poll only connectors where the connect/disconnect can be checked drm/omap: display: Add displays in sorted order to the panel_list drm/omap: Use omapdss_stack_is_ready() to check that the display stack is up drm/omap: dss: Support for detecting display stack readiness drm/omap: dss: Functions to check components in the display/output list drm/omap: fix replication logic drm/omap: remove unused dispc_wb_enable & dispc_wb_is_enabled drm/omap: remove all EXPORT_SYMBOLs from dispc.c drm/omap: use dispc_ops drm/omap: fill dispc_ops ...
-rw-r--r--Documentation/devicetree/bindings/display/panel/panel-dpi.txt3
-rw-r--r--drivers/gpu/drm/omapdrm/Kconfig9
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dpi.c37
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Kconfig4
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Makefile8
-rw-r--r--drivers/gpu/drm/omapdrm/dss/base.c140
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c278
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.h62
-rw-r--r--drivers/gpu/drm/omapdrm/dss/display.c36
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c58
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss-of.c3
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.c13
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h22
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.c9
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.h8
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_wp.c12
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h100
-rw-r--r--drivers/gpu/drm/omapdrm/dss/output.c27
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c17
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c18
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c119
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c257
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h6
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.c47
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c47
26 files changed, 802 insertions, 540 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/panel-dpi.txt b/Documentation/devicetree/bindings/display/panel/panel-dpi.txt
index d4add13e592d..6b203bc4d932 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-dpi.txt
+++ b/Documentation/devicetree/bindings/display/panel/panel-dpi.txt
@@ -9,6 +9,7 @@ Optional properties:
9- enable-gpios: panel enable gpio 9- enable-gpios: panel enable gpio
10- reset-gpios: GPIO to control the RESET pin 10- reset-gpios: GPIO to control the RESET pin
11- vcc-supply: phandle of regulator that will be used to enable power to the display 11- vcc-supply: phandle of regulator that will be used to enable power to the display
12- backlight: phandle of the backlight device
12 13
13Required nodes: 14Required nodes:
14- "panel-timing" containing video timings 15- "panel-timing" containing video timings
@@ -22,6 +23,8 @@ lcd0: display@0 {
22 compatible = "samsung,lte430wq-f0c", "panel-dpi"; 23 compatible = "samsung,lte430wq-f0c", "panel-dpi";
23 label = "lcd"; 24 label = "lcd";
24 25
26 backlight = <&backlight>;
27
25 port { 28 port {
26 lcd_in: endpoint { 29 lcd_in: endpoint {
27 remote-endpoint = <&dpi_out>; 30 remote-endpoint = <&dpi_out>;
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 556f81f6b2c7..b3d08c5f41d4 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -10,15 +10,6 @@ config DRM_OMAP
10 10
11if DRM_OMAP 11if DRM_OMAP
12 12
13config DRM_OMAP_NUM_CRTCS
14 int "Number of CRTCs"
15 range 1 10
16 default 1 if ARCH_OMAP2 || ARCH_OMAP3
17 default 2 if ARCH_OMAP4
18 help
19 Select the number of video overlays which can be used as framebuffers.
20 The remaining overlays are reserved for video.
21
22source "drivers/gpu/drm/omapdrm/dss/Kconfig" 13source "drivers/gpu/drm/omapdrm/dss/Kconfig"
23source "drivers/gpu/drm/omapdrm/displays/Kconfig" 14source "drivers/gpu/drm/omapdrm/displays/Kconfig"
24 15
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index 38003208d9ca..04ce8c5f2954 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -16,6 +16,7 @@
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/of_gpio.h> 17#include <linux/of_gpio.h>
18#include <linux/regulator/consumer.h> 18#include <linux/regulator/consumer.h>
19#include <linux/backlight.h>
19 20
20#include <video/omap-panel-data.h> 21#include <video/omap-panel-data.h>
21#include <video/of_display_timing.h> 22#include <video/of_display_timing.h>
@@ -30,6 +31,8 @@ struct panel_drv_data {
30 31
31 struct videomode vm; 32 struct videomode vm;
32 33
34 struct backlight_device *backlight;
35
33 /* used for non-DT boot, to be removed */ 36 /* used for non-DT boot, to be removed */
34 int backlight_gpio; 37 int backlight_gpio;
35 38
@@ -97,6 +100,11 @@ static int panel_dpi_enable(struct omap_dss_device *dssdev)
97 if (gpio_is_valid(ddata->backlight_gpio)) 100 if (gpio_is_valid(ddata->backlight_gpio))
98 gpio_set_value_cansleep(ddata->backlight_gpio, 1); 101 gpio_set_value_cansleep(ddata->backlight_gpio, 1);
99 102
103 if (ddata->backlight) {
104 ddata->backlight->props.power = FB_BLANK_UNBLANK;
105 backlight_update_status(ddata->backlight);
106 }
107
100 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 108 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
101 109
102 return 0; 110 return 0;
@@ -113,6 +121,11 @@ static void panel_dpi_disable(struct omap_dss_device *dssdev)
113 if (gpio_is_valid(ddata->backlight_gpio)) 121 if (gpio_is_valid(ddata->backlight_gpio))
114 gpio_set_value_cansleep(ddata->backlight_gpio, 0); 122 gpio_set_value_cansleep(ddata->backlight_gpio, 0);
115 123
124 if (ddata->backlight) {
125 ddata->backlight->props.power = FB_BLANK_POWERDOWN;
126 backlight_update_status(ddata->backlight);
127 }
128
116 gpiod_set_value_cansleep(ddata->enable_gpio, 0); 129 gpiod_set_value_cansleep(ddata->enable_gpio, 0);
117 regulator_disable(ddata->vcc_supply); 130 regulator_disable(ddata->vcc_supply);
118 131
@@ -209,6 +222,7 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
209{ 222{
210 struct panel_drv_data *ddata = platform_get_drvdata(pdev); 223 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
211 struct device_node *node = pdev->dev.of_node; 224 struct device_node *node = pdev->dev.of_node;
225 struct device_node *bl_node;
212 struct omap_dss_device *in; 226 struct omap_dss_device *in;
213 int r; 227 int r;
214 struct display_timing timing; 228 struct display_timing timing;
@@ -236,10 +250,19 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
236 250
237 ddata->backlight_gpio = -ENOENT; 251 ddata->backlight_gpio = -ENOENT;
238 252
253 bl_node = of_parse_phandle(node, "backlight", 0);
254 if (bl_node) {
255 ddata->backlight = of_find_backlight_by_node(bl_node);
256 of_node_put(bl_node);
257
258 if (!ddata->backlight)
259 return -EPROBE_DEFER;
260 }
261
239 r = of_get_display_timing(node, "panel-timing", &timing); 262 r = of_get_display_timing(node, "panel-timing", &timing);
240 if (r) { 263 if (r) {
241 dev_err(&pdev->dev, "failed to get video timing\n"); 264 dev_err(&pdev->dev, "failed to get video timing\n");
242 return r; 265 goto error_free_backlight;
243 } 266 }
244 267
245 videomode_from_timing(&timing, &ddata->vm); 268 videomode_from_timing(&timing, &ddata->vm);
@@ -247,12 +270,19 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
247 in = omapdss_of_find_source_for_first_ep(node); 270 in = omapdss_of_find_source_for_first_ep(node);
248 if (IS_ERR(in)) { 271 if (IS_ERR(in)) {
249 dev_err(&pdev->dev, "failed to find video source\n"); 272 dev_err(&pdev->dev, "failed to find video source\n");
250 return PTR_ERR(in); 273 r = PTR_ERR(in);
274 goto error_free_backlight;
251 } 275 }
252 276
253 ddata->in = in; 277 ddata->in = in;
254 278
255 return 0; 279 return 0;
280
281error_free_backlight:
282 if (ddata->backlight)
283 put_device(&ddata->backlight->dev);
284
285 return r;
256} 286}
257 287
258static int panel_dpi_probe(struct platform_device *pdev) 288static int panel_dpi_probe(struct platform_device *pdev)
@@ -321,6 +351,9 @@ static int __exit panel_dpi_remove(struct platform_device *pdev)
321 351
322 omap_dss_put_device(in); 352 omap_dss_put_device(in);
323 353
354 if (ddata->backlight)
355 put_device(&ddata->backlight->dev);
356
324 return 0; 357 return 0;
325} 358}
326 359
diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig
index d1fa730c7d54..f53adb944a0d 100644
--- a/drivers/gpu/drm/omapdrm/dss/Kconfig
+++ b/drivers/gpu/drm/omapdrm/dss/Kconfig
@@ -1,8 +1,12 @@
1config OMAP2_DSS_INIT 1config OMAP2_DSS_INIT
2 bool 2 bool
3 3
4config OMAP_DSS_BASE
5 tristate
6
4menuconfig OMAP2_DSS 7menuconfig OMAP2_DSS
5 tristate "OMAP2+ Display Subsystem support" 8 tristate "OMAP2+ Display Subsystem support"
9 select OMAP_DSS_BASE
6 select VIDEOMODE_HELPERS 10 select VIDEOMODE_HELPERS
7 select OMAP2_DSS_INIT 11 select OMAP2_DSS_INIT
8 select HDMI 12 select HDMI
diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile
index b651ec9751e6..75ec30f231c7 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -1,8 +1,12 @@
1obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o 1obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
2
3obj-$(CONFIG_OMAP_DSS_BASE) += omapdss-base.o
4omapdss-base-y := base.o display.o dss-of.o output.o
5
2obj-$(CONFIG_OMAP2_DSS) += omapdss.o 6obj-$(CONFIG_OMAP2_DSS) += omapdss.o
3# Core DSS files 7# Core DSS files
4omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 8omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \
5 output.o dss-of.o pll.o video-pll.o 9 pll.o video-pll.o
6omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 10omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
7omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o 11omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
8omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 12omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
new file mode 100644
index 000000000000..13e91faaf7a6
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -0,0 +1,140 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/of.h>
4#include <linux/of_graph.h>
5#include <linux/list.h>
6#include "omapdss.h"
7
8static bool dss_initialized;
9static const struct dispc_ops *ops;
10
11static struct list_head omapdss_comp_list;
12
13struct omapdss_comp_node {
14 struct list_head list;
15 struct device_node *node;
16 bool dss_core_component;
17};
18
19void omapdss_set_is_initialized(bool set)
20{
21 dss_initialized = set;
22}
23EXPORT_SYMBOL(omapdss_set_is_initialized);
24
25bool omapdss_is_initialized(void)
26{
27 return dss_initialized;
28}
29EXPORT_SYMBOL(omapdss_is_initialized);
30
31void dispc_set_ops(const struct dispc_ops *o)
32{
33 ops = o;
34}
35EXPORT_SYMBOL(dispc_set_ops);
36
37const struct dispc_ops *dispc_get_ops(void)
38{
39 return ops;
40}
41EXPORT_SYMBOL(dispc_get_ops);
42
43static bool omapdss_list_contains(const struct device_node *node)
44{
45 struct omapdss_comp_node *comp;
46
47 list_for_each_entry(comp, &omapdss_comp_list, list) {
48 if (comp->node == node)
49 return true;
50 }
51
52 return false;
53}
54
55static void omapdss_walk_device(struct device *dev, struct device_node *node,
56 bool dss_core)
57{
58 struct device_node *n;
59 struct omapdss_comp_node *comp = devm_kzalloc(dev, sizeof(*comp),
60 GFP_KERNEL);
61
62 if (comp) {
63 comp->node = node;
64 comp->dss_core_component = dss_core;
65 list_add(&comp->list, &omapdss_comp_list);
66 }
67
68 /*
69 * of_graph_get_remote_port_parent() prints an error if there is no
70 * port/ports node. To avoid that, check first that there's the node.
71 */
72 n = of_get_child_by_name(node, "ports");
73 if (!n)
74 n = of_get_child_by_name(node, "port");
75 if (!n)
76 return;
77
78 of_node_put(n);
79
80 n = NULL;
81 while ((n = of_graph_get_next_endpoint(node, n)) != NULL) {
82 struct device_node *pn = of_graph_get_remote_port_parent(n);
83
84 if (!pn)
85 continue;
86
87 if (!of_device_is_available(pn) || omapdss_list_contains(pn)) {
88 of_node_put(pn);
89 continue;
90 }
91
92 omapdss_walk_device(dev, pn, false);
93 }
94}
95
96void omapdss_gather_components(struct device *dev)
97{
98 struct device_node *child;
99
100 INIT_LIST_HEAD(&omapdss_comp_list);
101
102 omapdss_walk_device(dev, dev->of_node, true);
103
104 for_each_available_child_of_node(dev->of_node, child) {
105 if (!of_find_property(child, "compatible", NULL))
106 continue;
107
108 omapdss_walk_device(dev, child, true);
109 }
110}
111EXPORT_SYMBOL(omapdss_gather_components);
112
113static bool omapdss_component_is_loaded(struct omapdss_comp_node *comp)
114{
115 if (comp->dss_core_component)
116 return true;
117 if (omapdss_component_is_display(comp->node))
118 return true;
119 if (omapdss_component_is_output(comp->node))
120 return true;
121
122 return false;
123}
124
125bool omapdss_stack_is_ready(void)
126{
127 struct omapdss_comp_node *comp;
128
129 list_for_each_entry(comp, &omapdss_comp_list, list) {
130 if (!omapdss_component_is_loaded(comp))
131 return false;
132 }
133
134 return true;
135}
136EXPORT_SYMBOL(omapdss_stack_is_ready);
137
138MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
139MODULE_DESCRIPTION("OMAP Display Subsystem Base");
140MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index d956e6266368..5ac0145fbae6 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -303,8 +303,12 @@ static unsigned long dispc_core_clk_rate(void);
303static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 303static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
304static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 304static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
305 305
306static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); 306static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane);
307static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); 307static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane);
308
309static void dispc_clear_irqstatus(u32 mask);
310static bool dispc_mgr_is_enabled(enum omap_channel channel);
311static void dispc_clear_irqstatus(u32 mask);
308 312
309static inline void dispc_write_reg(const u16 idx, u32 val) 313static inline void dispc_write_reg(const u16 idx, u32 val)
310{ 314{
@@ -581,7 +585,6 @@ int dispc_runtime_get(void)
581 WARN_ON(r < 0); 585 WARN_ON(r < 0);
582 return r < 0 ? r : 0; 586 return r < 0 ? r : 0;
583} 587}
584EXPORT_SYMBOL(dispc_runtime_get);
585 588
586void dispc_runtime_put(void) 589void dispc_runtime_put(void)
587{ 590{
@@ -592,54 +595,48 @@ void dispc_runtime_put(void)
592 r = pm_runtime_put_sync(&dispc.pdev->dev); 595 r = pm_runtime_put_sync(&dispc.pdev->dev);
593 WARN_ON(r < 0 && r != -ENOSYS); 596 WARN_ON(r < 0 && r != -ENOSYS);
594} 597}
595EXPORT_SYMBOL(dispc_runtime_put);
596 598
597u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 599static u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
598{ 600{
599 return mgr_desc[channel].vsync_irq; 601 return mgr_desc[channel].vsync_irq;
600} 602}
601EXPORT_SYMBOL(dispc_mgr_get_vsync_irq);
602 603
603u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) 604static u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
604{ 605{
605 if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv) 606 if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv)
606 return 0; 607 return 0;
607 608
608 return mgr_desc[channel].framedone_irq; 609 return mgr_desc[channel].framedone_irq;
609} 610}
610EXPORT_SYMBOL(dispc_mgr_get_framedone_irq);
611 611
612u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel) 612static u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
613{ 613{
614 return mgr_desc[channel].sync_lost_irq; 614 return mgr_desc[channel].sync_lost_irq;
615} 615}
616EXPORT_SYMBOL(dispc_mgr_get_sync_lost_irq);
617 616
618u32 dispc_wb_get_framedone_irq(void) 617u32 dispc_wb_get_framedone_irq(void)
619{ 618{
620 return DISPC_IRQ_FRAMEDONEWB; 619 return DISPC_IRQ_FRAMEDONEWB;
621} 620}
622 621
623void dispc_mgr_enable(enum omap_channel channel, bool enable) 622static void dispc_mgr_enable(enum omap_channel channel, bool enable)
624{ 623{
625 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); 624 mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
626 /* flush posted write */ 625 /* flush posted write */
627 mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); 626 mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
628} 627}
629EXPORT_SYMBOL(dispc_mgr_enable);
630 628
631static bool dispc_mgr_is_enabled(enum omap_channel channel) 629static bool dispc_mgr_is_enabled(enum omap_channel channel)
632{ 630{
633 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); 631 return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
634} 632}
635 633
636bool dispc_mgr_go_busy(enum omap_channel channel) 634static bool dispc_mgr_go_busy(enum omap_channel channel)
637{ 635{
638 return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; 636 return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
639} 637}
640EXPORT_SYMBOL(dispc_mgr_go_busy);
641 638
642void dispc_mgr_go(enum omap_channel channel) 639static void dispc_mgr_go(enum omap_channel channel)
643{ 640{
644 WARN_ON(!dispc_mgr_is_enabled(channel)); 641 WARN_ON(!dispc_mgr_is_enabled(channel));
645 WARN_ON(dispc_mgr_go_busy(channel)); 642 WARN_ON(dispc_mgr_go_busy(channel));
@@ -648,7 +645,6 @@ void dispc_mgr_go(enum omap_channel channel)
648 645
649 mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); 646 mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
650} 647}
651EXPORT_SYMBOL(dispc_mgr_go);
652 648
653bool dispc_wb_go_busy(void) 649bool dispc_wb_go_busy(void)
654{ 650{
@@ -657,7 +653,7 @@ bool dispc_wb_go_busy(void)
657 653
658void dispc_wb_go(void) 654void dispc_wb_go(void)
659{ 655{
660 enum omap_plane plane = OMAP_DSS_WB; 656 enum omap_plane_id plane = OMAP_DSS_WB;
661 bool enable, go; 657 bool enable, go;
662 658
663 enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1; 659 enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1;
@@ -674,29 +670,33 @@ void dispc_wb_go(void)
674 REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6); 670 REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
675} 671}
676 672
677static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) 673static void dispc_ovl_write_firh_reg(enum omap_plane_id plane, int reg,
674 u32 value)
678{ 675{
679 dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); 676 dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
680} 677}
681 678
682static void dispc_ovl_write_firhv_reg(enum omap_plane plane, int reg, u32 value) 679static void dispc_ovl_write_firhv_reg(enum omap_plane_id plane, int reg,
680 u32 value)
683{ 681{
684 dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value); 682 dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value);
685} 683}
686 684
687static void dispc_ovl_write_firv_reg(enum omap_plane plane, int reg, u32 value) 685static void dispc_ovl_write_firv_reg(enum omap_plane_id plane, int reg,
686 u32 value)
688{ 687{
689 dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value); 688 dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value);
690} 689}
691 690
692static void dispc_ovl_write_firh2_reg(enum omap_plane plane, int reg, u32 value) 691static void dispc_ovl_write_firh2_reg(enum omap_plane_id plane, int reg,
692 u32 value)
693{ 693{
694 BUG_ON(plane == OMAP_DSS_GFX); 694 BUG_ON(plane == OMAP_DSS_GFX);
695 695
696 dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value); 696 dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value);
697} 697}
698 698
699static void dispc_ovl_write_firhv2_reg(enum omap_plane plane, int reg, 699static void dispc_ovl_write_firhv2_reg(enum omap_plane_id plane, int reg,
700 u32 value) 700 u32 value)
701{ 701{
702 BUG_ON(plane == OMAP_DSS_GFX); 702 BUG_ON(plane == OMAP_DSS_GFX);
@@ -704,14 +704,15 @@ static void dispc_ovl_write_firhv2_reg(enum omap_plane plane, int reg,
704 dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value); 704 dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value);
705} 705}
706 706
707static void dispc_ovl_write_firv2_reg(enum omap_plane plane, int reg, u32 value) 707static void dispc_ovl_write_firv2_reg(enum omap_plane_id plane, int reg,
708 u32 value)
708{ 709{
709 BUG_ON(plane == OMAP_DSS_GFX); 710 BUG_ON(plane == OMAP_DSS_GFX);
710 711
711 dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value); 712 dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
712} 713}
713 714
714static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc, 715static void dispc_ovl_set_scale_coef(enum omap_plane_id plane, int fir_hinc,
715 int fir_vinc, int five_taps, 716 int fir_vinc, int five_taps,
716 enum omap_color_component color_comp) 717 enum omap_color_component color_comp)
717{ 718{
@@ -757,7 +758,7 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc,
757} 758}
758 759
759 760
760static void dispc_ovl_write_color_conv_coef(enum omap_plane plane, 761static void dispc_ovl_write_color_conv_coef(enum omap_plane_id plane,
761 const struct color_conv_coef *ct) 762 const struct color_conv_coef *ct)
762{ 763{
763#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) 764#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
@@ -793,27 +794,27 @@ static void dispc_setup_color_conv_coef(void)
793 dispc_ovl_write_color_conv_coef(OMAP_DSS_WB, &ctbl_bt601_5_wb); 794 dispc_ovl_write_color_conv_coef(OMAP_DSS_WB, &ctbl_bt601_5_wb);
794} 795}
795 796
796static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) 797static void dispc_ovl_set_ba0(enum omap_plane_id plane, u32 paddr)
797{ 798{
798 dispc_write_reg(DISPC_OVL_BA0(plane), paddr); 799 dispc_write_reg(DISPC_OVL_BA0(plane), paddr);
799} 800}
800 801
801static void dispc_ovl_set_ba1(enum omap_plane plane, u32 paddr) 802static void dispc_ovl_set_ba1(enum omap_plane_id plane, u32 paddr)
802{ 803{
803 dispc_write_reg(DISPC_OVL_BA1(plane), paddr); 804 dispc_write_reg(DISPC_OVL_BA1(plane), paddr);
804} 805}
805 806
806static void dispc_ovl_set_ba0_uv(enum omap_plane plane, u32 paddr) 807static void dispc_ovl_set_ba0_uv(enum omap_plane_id plane, u32 paddr)
807{ 808{
808 dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr); 809 dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr);
809} 810}
810 811
811static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr) 812static void dispc_ovl_set_ba1_uv(enum omap_plane_id plane, u32 paddr)
812{ 813{
813 dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); 814 dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
814} 815}
815 816
816static void dispc_ovl_set_pos(enum omap_plane plane, 817static void dispc_ovl_set_pos(enum omap_plane_id plane,
817 enum omap_overlay_caps caps, int x, int y) 818 enum omap_overlay_caps caps, int x, int y)
818{ 819{
819 u32 val; 820 u32 val;
@@ -826,7 +827,7 @@ static void dispc_ovl_set_pos(enum omap_plane plane,
826 dispc_write_reg(DISPC_OVL_POSITION(plane), val); 827 dispc_write_reg(DISPC_OVL_POSITION(plane), val);
827} 828}
828 829
829static void dispc_ovl_set_input_size(enum omap_plane plane, int width, 830static void dispc_ovl_set_input_size(enum omap_plane_id plane, int width,
830 int height) 831 int height)
831{ 832{
832 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 833 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
@@ -837,7 +838,7 @@ static void dispc_ovl_set_input_size(enum omap_plane plane, int width,
837 dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); 838 dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
838} 839}
839 840
840static void dispc_ovl_set_output_size(enum omap_plane plane, int width, 841static void dispc_ovl_set_output_size(enum omap_plane_id plane, int width,
841 int height) 842 int height)
842{ 843{
843 u32 val; 844 u32 val;
@@ -852,7 +853,7 @@ static void dispc_ovl_set_output_size(enum omap_plane plane, int width,
852 dispc_write_reg(DISPC_OVL_SIZE(plane), val); 853 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
853} 854}
854 855
855static void dispc_ovl_set_zorder(enum omap_plane plane, 856static void dispc_ovl_set_zorder(enum omap_plane_id plane,
856 enum omap_overlay_caps caps, u8 zorder) 857 enum omap_overlay_caps caps, u8 zorder)
857{ 858{
858 if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) 859 if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
@@ -872,7 +873,7 @@ static void dispc_ovl_enable_zorder_planes(void)
872 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); 873 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
873} 874}
874 875
875static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, 876static void dispc_ovl_set_pre_mult_alpha(enum omap_plane_id plane,
876 enum omap_overlay_caps caps, bool enable) 877 enum omap_overlay_caps caps, bool enable)
877{ 878{
878 if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) 879 if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
@@ -881,7 +882,7 @@ static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane,
881 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); 882 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
882} 883}
883 884
884static void dispc_ovl_setup_global_alpha(enum omap_plane plane, 885static void dispc_ovl_setup_global_alpha(enum omap_plane_id plane,
885 enum omap_overlay_caps caps, u8 global_alpha) 886 enum omap_overlay_caps caps, u8 global_alpha)
886{ 887{
887 static const unsigned shifts[] = { 0, 8, 16, 24, }; 888 static const unsigned shifts[] = { 0, 8, 16, 24, };
@@ -894,17 +895,17 @@ static void dispc_ovl_setup_global_alpha(enum omap_plane plane,
894 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, shift + 7, shift); 895 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, shift + 7, shift);
895} 896}
896 897
897static void dispc_ovl_set_pix_inc(enum omap_plane plane, s32 inc) 898static void dispc_ovl_set_pix_inc(enum omap_plane_id plane, s32 inc)
898{ 899{
899 dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc); 900 dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc);
900} 901}
901 902
902static void dispc_ovl_set_row_inc(enum omap_plane plane, s32 inc) 903static void dispc_ovl_set_row_inc(enum omap_plane_id plane, s32 inc)
903{ 904{
904 dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc); 905 dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc);
905} 906}
906 907
907static void dispc_ovl_set_color_mode(enum omap_plane plane, 908static void dispc_ovl_set_color_mode(enum omap_plane_id plane,
908 enum omap_color_mode color_mode) 909 enum omap_color_mode color_mode)
909{ 910{
910 u32 m = 0; 911 u32 m = 0;
@@ -985,7 +986,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
985 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); 986 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
986} 987}
987 988
988static void dispc_ovl_configure_burst_type(enum omap_plane plane, 989static void dispc_ovl_configure_burst_type(enum omap_plane_id plane,
989 enum omap_dss_rotation_type rotation_type) 990 enum omap_dss_rotation_type rotation_type)
990{ 991{
991 if (dss_has_feature(FEAT_BURST_2D) == 0) 992 if (dss_has_feature(FEAT_BURST_2D) == 0)
@@ -997,7 +998,8 @@ static void dispc_ovl_configure_burst_type(enum omap_plane plane,
997 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29); 998 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0, 29, 29);
998} 999}
999 1000
1000void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel) 1001static void dispc_ovl_set_channel_out(enum omap_plane_id plane,
1002 enum omap_channel channel)
1001{ 1003{
1002 int shift; 1004 int shift;
1003 u32 val; 1005 u32 val;
@@ -1057,9 +1059,8 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
1057 } 1059 }
1058 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 1060 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
1059} 1061}
1060EXPORT_SYMBOL(dispc_ovl_set_channel_out);
1061 1062
1062static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) 1063static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane_id plane)
1063{ 1064{
1064 int shift; 1065 int shift;
1065 u32 val; 1066 u32 val;
@@ -1101,12 +1102,12 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
1101 1102
1102void dispc_wb_set_channel_in(enum dss_writeback_channel channel) 1103void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
1103{ 1104{
1104 enum omap_plane plane = OMAP_DSS_WB; 1105 enum omap_plane_id plane = OMAP_DSS_WB;
1105 1106
1106 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16); 1107 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
1107} 1108}
1108 1109
1109static void dispc_ovl_set_burst_size(enum omap_plane plane, 1110static void dispc_ovl_set_burst_size(enum omap_plane_id plane,
1110 enum omap_burst_size burst_size) 1111 enum omap_burst_size burst_size)
1111{ 1112{
1112 static const unsigned shifts[] = { 6, 14, 14, 14, 14, }; 1113 static const unsigned shifts[] = { 6, 14, 14, 14, 14, };
@@ -1128,13 +1129,23 @@ static void dispc_configure_burst_sizes(void)
1128 dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size); 1129 dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size);
1129} 1130}
1130 1131
1131static u32 dispc_ovl_get_burst_size(enum omap_plane plane) 1132static u32 dispc_ovl_get_burst_size(enum omap_plane_id plane)
1132{ 1133{
1133 unsigned unit = dss_feat_get_burst_size_unit(); 1134 unsigned unit = dss_feat_get_burst_size_unit();
1134 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ 1135 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
1135 return unit * 8; 1136 return unit * 8;
1136} 1137}
1137 1138
1139static enum omap_color_mode dispc_ovl_get_color_modes(enum omap_plane_id plane)
1140{
1141 return dss_feat_get_supported_color_modes(plane);
1142}
1143
1144static int dispc_get_num_ovls(void)
1145{
1146 return dss_feat_get_num_ovls();
1147}
1148
1138static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) 1149static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
1139{ 1150{
1140 if (channel == OMAP_DSS_CHANNEL_DIGIT) 1151 if (channel == OMAP_DSS_CHANNEL_DIGIT)
@@ -1163,7 +1174,8 @@ static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
1163 dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b); 1174 dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b);
1164} 1175}
1165 1176
1166static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) 1177static void dispc_ovl_set_vid_color_conv(enum omap_plane_id plane,
1178 bool enable)
1167{ 1179{
1168 u32 val; 1180 u32 val;
1169 1181
@@ -1174,7 +1186,7 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable)
1174 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 1186 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
1175} 1187}
1176 1188
1177static void dispc_ovl_enable_replication(enum omap_plane plane, 1189static void dispc_ovl_enable_replication(enum omap_plane_id plane,
1178 enum omap_overlay_caps caps, bool enable) 1190 enum omap_overlay_caps caps, bool enable)
1179{ 1191{
1180 static const unsigned shifts[] = { 5, 10, 10, 10 }; 1192 static const unsigned shifts[] = { 5, 10, 10, 10 };
@@ -1271,7 +1283,7 @@ static void dispc_init_fifos(void)
1271 } 1283 }
1272} 1284}
1273 1285
1274static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) 1286static u32 dispc_ovl_get_fifo_size(enum omap_plane_id plane)
1275{ 1287{
1276 int fifo; 1288 int fifo;
1277 u32 size = 0; 1289 u32 size = 0;
@@ -1284,7 +1296,8 @@ static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
1284 return size; 1296 return size;
1285} 1297}
1286 1298
1287void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) 1299void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
1300 u32 high)
1288{ 1301{
1289 u8 hi_start, hi_end, lo_start, lo_end; 1302 u8 hi_start, hi_end, lo_start, lo_end;
1290 u32 unit; 1303 u32 unit;
@@ -1333,7 +1346,7 @@ void dispc_enable_fifomerge(bool enable)
1333 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1346 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
1334} 1347}
1335 1348
1336void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 1349void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
1337 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 1350 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
1338 bool manual_update) 1351 bool manual_update)
1339{ 1352{
@@ -1380,7 +1393,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
1380 } 1393 }
1381} 1394}
1382 1395
1383static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable) 1396static void dispc_ovl_set_mflag(enum omap_plane_id plane, bool enable)
1384{ 1397{
1385 int bit; 1398 int bit;
1386 1399
@@ -1392,7 +1405,7 @@ static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable)
1392 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit); 1405 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
1393} 1406}
1394 1407
1395static void dispc_ovl_set_mflag_threshold(enum omap_plane plane, 1408static void dispc_ovl_set_mflag_threshold(enum omap_plane_id plane,
1396 int low, int high) 1409 int low, int high)
1397{ 1410{
1398 dispc_write_reg(DISPC_OVL_MFLAG_THRESHOLD(plane), 1411 dispc_write_reg(DISPC_OVL_MFLAG_THRESHOLD(plane),
@@ -1456,7 +1469,7 @@ static void dispc_init_mflag(void)
1456 } 1469 }
1457} 1470}
1458 1471
1459static void dispc_ovl_set_fir(enum omap_plane plane, 1472static void dispc_ovl_set_fir(enum omap_plane_id plane,
1460 int hinc, int vinc, 1473 int hinc, int vinc,
1461 enum omap_color_component color_comp) 1474 enum omap_color_component color_comp)
1462{ 1475{
@@ -1479,7 +1492,8 @@ static void dispc_ovl_set_fir(enum omap_plane plane,
1479 } 1492 }
1480} 1493}
1481 1494
1482static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) 1495static void dispc_ovl_set_vid_accu0(enum omap_plane_id plane, int haccu,
1496 int vaccu)
1483{ 1497{
1484 u32 val; 1498 u32 val;
1485 u8 hor_start, hor_end, vert_start, vert_end; 1499 u8 hor_start, hor_end, vert_start, vert_end;
@@ -1493,7 +1507,8 @@ static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1493 dispc_write_reg(DISPC_OVL_ACCU0(plane), val); 1507 dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
1494} 1508}
1495 1509
1496static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) 1510static void dispc_ovl_set_vid_accu1(enum omap_plane_id plane, int haccu,
1511 int vaccu)
1497{ 1512{
1498 u32 val; 1513 u32 val;
1499 u8 hor_start, hor_end, vert_start, vert_end; 1514 u8 hor_start, hor_end, vert_start, vert_end;
@@ -1507,7 +1522,7 @@ static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1507 dispc_write_reg(DISPC_OVL_ACCU1(plane), val); 1522 dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
1508} 1523}
1509 1524
1510static void dispc_ovl_set_vid_accu2_0(enum omap_plane plane, int haccu, 1525static void dispc_ovl_set_vid_accu2_0(enum omap_plane_id plane, int haccu,
1511 int vaccu) 1526 int vaccu)
1512{ 1527{
1513 u32 val; 1528 u32 val;
@@ -1516,7 +1531,7 @@ static void dispc_ovl_set_vid_accu2_0(enum omap_plane plane, int haccu,
1516 dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val); 1531 dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val);
1517} 1532}
1518 1533
1519static void dispc_ovl_set_vid_accu2_1(enum omap_plane plane, int haccu, 1534static void dispc_ovl_set_vid_accu2_1(enum omap_plane_id plane, int haccu,
1520 int vaccu) 1535 int vaccu)
1521{ 1536{
1522 u32 val; 1537 u32 val;
@@ -1525,7 +1540,7 @@ static void dispc_ovl_set_vid_accu2_1(enum omap_plane plane, int haccu,
1525 dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val); 1540 dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val);
1526} 1541}
1527 1542
1528static void dispc_ovl_set_scale_param(enum omap_plane plane, 1543static void dispc_ovl_set_scale_param(enum omap_plane_id plane,
1529 u16 orig_width, u16 orig_height, 1544 u16 orig_width, u16 orig_height,
1530 u16 out_width, u16 out_height, 1545 u16 out_width, u16 out_height,
1531 bool five_taps, u8 rotation, 1546 bool five_taps, u8 rotation,
@@ -1541,7 +1556,7 @@ static void dispc_ovl_set_scale_param(enum omap_plane plane,
1541 dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp); 1556 dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp);
1542} 1557}
1543 1558
1544static void dispc_ovl_set_accu_uv(enum omap_plane plane, 1559static void dispc_ovl_set_accu_uv(enum omap_plane_id plane,
1545 u16 orig_width, u16 orig_height, u16 out_width, u16 out_height, 1560 u16 orig_width, u16 orig_height, u16 out_width, u16 out_height,
1546 bool ilace, enum omap_color_mode color_mode, u8 rotation) 1561 bool ilace, enum omap_color_mode color_mode, u8 rotation)
1547{ 1562{
@@ -1629,7 +1644,7 @@ static void dispc_ovl_set_accu_uv(enum omap_plane plane,
1629 dispc_ovl_set_vid_accu2_1(plane, h_accu2_1, v_accu2_1); 1644 dispc_ovl_set_vid_accu2_1(plane, h_accu2_1, v_accu2_1);
1630} 1645}
1631 1646
1632static void dispc_ovl_set_scaling_common(enum omap_plane plane, 1647static void dispc_ovl_set_scaling_common(enum omap_plane_id plane,
1633 u16 orig_width, u16 orig_height, 1648 u16 orig_width, u16 orig_height,
1634 u16 out_width, u16 out_height, 1649 u16 out_width, u16 out_height,
1635 bool ilace, bool five_taps, 1650 bool ilace, bool five_taps,
@@ -1683,7 +1698,7 @@ static void dispc_ovl_set_scaling_common(enum omap_plane plane,
1683 dispc_ovl_set_vid_accu1(plane, 0, accu1); 1698 dispc_ovl_set_vid_accu1(plane, 0, accu1);
1684} 1699}
1685 1700
1686static void dispc_ovl_set_scaling_uv(enum omap_plane plane, 1701static void dispc_ovl_set_scaling_uv(enum omap_plane_id plane,
1687 u16 orig_width, u16 orig_height, 1702 u16 orig_width, u16 orig_height,
1688 u16 out_width, u16 out_height, 1703 u16 out_width, u16 out_height,
1689 bool ilace, bool five_taps, 1704 bool ilace, bool five_taps,
@@ -1763,7 +1778,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
1763 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6); 1778 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6);
1764} 1779}
1765 1780
1766static void dispc_ovl_set_scaling(enum omap_plane plane, 1781static void dispc_ovl_set_scaling(enum omap_plane_id plane,
1767 u16 orig_width, u16 orig_height, 1782 u16 orig_width, u16 orig_height,
1768 u16 out_width, u16 out_height, 1783 u16 out_width, u16 out_height,
1769 bool ilace, bool five_taps, 1784 bool ilace, bool five_taps,
@@ -1787,7 +1802,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane,
1787 rotation); 1802 rotation);
1788} 1803}
1789 1804
1790static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1805static void dispc_ovl_set_rotation_attrs(enum omap_plane_id plane, u8 rotation,
1791 enum omap_dss_rotation_type rotation_type, 1806 enum omap_dss_rotation_type rotation_type,
1792 bool mirroring, enum omap_color_mode color_mode) 1807 bool mirroring, enum omap_color_mode color_mode)
1793{ 1808{
@@ -2619,7 +2634,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
2619 return 0; 2634 return 0;
2620} 2635}
2621 2636
2622static int dispc_ovl_setup_common(enum omap_plane plane, 2637static int dispc_ovl_setup_common(enum omap_plane_id plane,
2623 enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, 2638 enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
2624 u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, 2639 u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
2625 u16 out_width, u16 out_height, enum omap_color_mode color_mode, 2640 u16 out_width, u16 out_height, enum omap_color_mode color_mode,
@@ -2817,13 +2832,14 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2817 return 0; 2832 return 0;
2818} 2833}
2819 2834
2820int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, 2835static int dispc_ovl_setup(enum omap_plane_id plane,
2821 bool replication, const struct videomode *vm, 2836 const struct omap_overlay_info *oi,
2822 bool mem_to_mem) 2837 const struct videomode *vm, bool mem_to_mem)
2823{ 2838{
2824 int r; 2839 int r;
2825 enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane); 2840 enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
2826 enum omap_channel channel; 2841 enum omap_channel channel;
2842 const bool replication = true;
2827 2843
2828 channel = dispc_ovl_get_channel_out(plane); 2844 channel = dispc_ovl_get_channel_out(plane);
2829 2845
@@ -2841,17 +2857,16 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
2841 2857
2842 return r; 2858 return r;
2843} 2859}
2844EXPORT_SYMBOL(dispc_ovl_setup);
2845 2860
2846int dispc_wb_setup(const struct omap_dss_writeback_info *wi, 2861int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
2847 bool mem_to_mem, const struct videomode *vm) 2862 bool mem_to_mem, const struct videomode *vm)
2848{ 2863{
2849 int r; 2864 int r;
2850 u32 l; 2865 u32 l;
2851 enum omap_plane plane = OMAP_DSS_WB; 2866 enum omap_plane_id plane = OMAP_DSS_WB;
2852 const int pos_x = 0, pos_y = 0; 2867 const int pos_x = 0, pos_y = 0;
2853 const u8 zorder = 0, global_alpha = 0; 2868 const u8 zorder = 0, global_alpha = 0;
2854 const bool replication = false; 2869 const bool replication = true;
2855 bool truncation; 2870 bool truncation;
2856 int in_width = vm->hactive; 2871 int in_width = vm->hactive;
2857 int in_height = vm->vactive; 2872 int in_height = vm->vactive;
@@ -2911,7 +2926,7 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
2911 return r; 2926 return r;
2912} 2927}
2913 2928
2914int dispc_ovl_enable(enum omap_plane plane, bool enable) 2929static int dispc_ovl_enable(enum omap_plane_id plane, bool enable)
2915{ 2930{
2916 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 2931 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
2917 2932
@@ -2919,29 +2934,16 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable)
2919 2934
2920 return 0; 2935 return 0;
2921} 2936}
2922EXPORT_SYMBOL(dispc_ovl_enable);
2923 2937
2924bool dispc_ovl_enabled(enum omap_plane plane) 2938static bool dispc_ovl_enabled(enum omap_plane_id plane)
2925{ 2939{
2926 return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); 2940 return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
2927} 2941}
2928EXPORT_SYMBOL(dispc_ovl_enabled);
2929 2942
2930enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel) 2943static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel)
2931{ 2944{
2932 return dss_feat_get_supported_outputs(channel); 2945 return dss_feat_get_supported_outputs(channel);
2933} 2946}
2934EXPORT_SYMBOL(dispc_mgr_get_supported_outputs);
2935
2936void dispc_wb_enable(bool enable)
2937{
2938 dispc_ovl_enable(OMAP_DSS_WB, enable);
2939}
2940
2941bool dispc_wb_is_enabled(void)
2942{
2943 return dispc_ovl_enabled(OMAP_DSS_WB);
2944}
2945 2947
2946static void dispc_lcd_enable_signal_polarity(bool act_high) 2948static void dispc_lcd_enable_signal_polarity(bool act_high)
2947{ 2949{
@@ -2967,6 +2969,11 @@ void dispc_pck_free_enable(bool enable)
2967 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 2969 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
2968} 2970}
2969 2971
2972static int dispc_get_num_mgrs(void)
2973{
2974 return dss_feat_get_num_mgrs();
2975}
2976
2970static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable) 2977static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
2971{ 2978{
2972 mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable); 2979 mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
@@ -3015,7 +3022,7 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
3015 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 3022 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
3016} 3023}
3017 3024
3018void dispc_mgr_setup(enum omap_channel channel, 3025static void dispc_mgr_setup(enum omap_channel channel,
3019 const struct omap_overlay_manager_info *info) 3026 const struct omap_overlay_manager_info *info)
3020{ 3027{
3021 dispc_mgr_set_default_color(channel, info->default_color); 3028 dispc_mgr_set_default_color(channel, info->default_color);
@@ -3028,7 +3035,6 @@ void dispc_mgr_setup(enum omap_channel channel,
3028 dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs); 3035 dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
3029 } 3036 }
3030} 3037}
3031EXPORT_SYMBOL(dispc_mgr_setup);
3032 3038
3033static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines) 3039static void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
3034{ 3040{
@@ -3089,7 +3095,7 @@ static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
3089 mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); 3095 mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
3090} 3096}
3091 3097
3092void dispc_mgr_set_lcd_config(enum omap_channel channel, 3098static void dispc_mgr_set_lcd_config(enum omap_channel channel,
3093 const struct dss_lcd_mgr_config *config) 3099 const struct dss_lcd_mgr_config *config)
3094{ 3100{
3095 dispc_mgr_set_io_pad_mode(config->io_pad_mode); 3101 dispc_mgr_set_io_pad_mode(config->io_pad_mode);
@@ -3105,7 +3111,6 @@ void dispc_mgr_set_lcd_config(enum omap_channel channel,
3105 3111
3106 dispc_mgr_set_lcd_type_tft(channel); 3112 dispc_mgr_set_lcd_type_tft(channel);
3107} 3113}
3108EXPORT_SYMBOL(dispc_mgr_set_lcd_config);
3109 3114
3110static bool _dispc_mgr_size_ok(u16 width, u16 height) 3115static bool _dispc_mgr_size_ok(u16 width, u16 height)
3111{ 3116{
@@ -3235,8 +3240,18 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel,
3235 } 3240 }
3236} 3241}
3237 3242
3243static int vm_flag_to_int(enum display_flags flags, enum display_flags high,
3244 enum display_flags low)
3245{
3246 if (flags & high)
3247 return 1;
3248 if (flags & low)
3249 return -1;
3250 return 0;
3251}
3252
3238/* change name to mode? */ 3253/* change name to mode? */
3239void dispc_mgr_set_timings(enum omap_channel channel, 3254static void dispc_mgr_set_timings(enum omap_channel channel,
3240 const struct videomode *vm) 3255 const struct videomode *vm)
3241{ 3256{
3242 unsigned xtot, ytot; 3257 unsigned xtot, ytot;
@@ -3264,11 +3279,11 @@ void dispc_mgr_set_timings(enum omap_channel channel,
3264 t.hsync_len, t.hfront_porch, t.hback_porch, 3279 t.hsync_len, t.hfront_porch, t.hback_porch,
3265 t.vsync_len, t.vfront_porch, t.vback_porch); 3280 t.vsync_len, t.vfront_porch, t.vback_porch);
3266 DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n", 3281 DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n",
3267 !!(t.flags & DISPLAY_FLAGS_VSYNC_HIGH), 3282 vm_flag_to_int(t.flags, DISPLAY_FLAGS_VSYNC_HIGH, DISPLAY_FLAGS_VSYNC_LOW),
3268 !!(t.flags & DISPLAY_FLAGS_HSYNC_HIGH), 3283 vm_flag_to_int(t.flags, DISPLAY_FLAGS_HSYNC_HIGH, DISPLAY_FLAGS_HSYNC_LOW),
3269 !!(t.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE), 3284 vm_flag_to_int(t.flags, DISPLAY_FLAGS_PIXDATA_POSEDGE, DISPLAY_FLAGS_PIXDATA_NEGEDGE),
3270 !!(t.flags & DISPLAY_FLAGS_DE_HIGH), 3285 vm_flag_to_int(t.flags, DISPLAY_FLAGS_DE_HIGH, DISPLAY_FLAGS_DE_LOW),
3271 !!(t.flags & DISPLAY_FLAGS_SYNC_POSEDGE)); 3286 vm_flag_to_int(t.flags, DISPLAY_FLAGS_SYNC_POSEDGE, DISPLAY_FLAGS_SYNC_NEGEDGE));
3272 3287
3273 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 3288 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
3274 } else { 3289 } else {
@@ -3283,7 +3298,6 @@ void dispc_mgr_set_timings(enum omap_channel channel,
3283 3298
3284 dispc_mgr_set_size(channel, t.hactive, t.vactive); 3299 dispc_mgr_set_size(channel, t.hactive, t.vactive);
3285} 3300}
3286EXPORT_SYMBOL(dispc_mgr_set_timings);
3287 3301
3288static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, 3302static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
3289 u16 pck_div) 3303 u16 pck_div)
@@ -3389,7 +3403,7 @@ static unsigned long dispc_core_clk_rate(void)
3389 return dispc.core_clk_rate; 3403 return dispc.core_clk_rate;
3390} 3404}
3391 3405
3392static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) 3406static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane)
3393{ 3407{
3394 enum omap_channel channel; 3408 enum omap_channel channel;
3395 3409
@@ -3401,7 +3415,7 @@ static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
3401 return dispc_mgr_pclk_rate(channel); 3415 return dispc_mgr_pclk_rate(channel);
3402} 3416}
3403 3417
3404static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) 3418static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane)
3405{ 3419{
3406 enum omap_channel channel; 3420 enum omap_channel channel;
3407 3421
@@ -3763,25 +3777,22 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
3763 return 0; 3777 return 0;
3764} 3778}
3765 3779
3766u32 dispc_read_irqstatus(void) 3780static u32 dispc_read_irqstatus(void)
3767{ 3781{
3768 return dispc_read_reg(DISPC_IRQSTATUS); 3782 return dispc_read_reg(DISPC_IRQSTATUS);
3769} 3783}
3770EXPORT_SYMBOL(dispc_read_irqstatus);
3771 3784
3772void dispc_clear_irqstatus(u32 mask) 3785static void dispc_clear_irqstatus(u32 mask)
3773{ 3786{
3774 dispc_write_reg(DISPC_IRQSTATUS, mask); 3787 dispc_write_reg(DISPC_IRQSTATUS, mask);
3775} 3788}
3776EXPORT_SYMBOL(dispc_clear_irqstatus);
3777 3789
3778u32 dispc_read_irqenable(void) 3790static u32 dispc_read_irqenable(void)
3779{ 3791{
3780 return dispc_read_reg(DISPC_IRQENABLE); 3792 return dispc_read_reg(DISPC_IRQENABLE);
3781} 3793}
3782EXPORT_SYMBOL(dispc_read_irqenable);
3783 3794
3784void dispc_write_irqenable(u32 mask) 3795static void dispc_write_irqenable(u32 mask)
3785{ 3796{
3786 u32 old_mask = dispc_read_reg(DISPC_IRQENABLE); 3797 u32 old_mask = dispc_read_reg(DISPC_IRQENABLE);
3787 3798
@@ -3790,7 +3801,6 @@ void dispc_write_irqenable(u32 mask)
3790 3801
3791 dispc_write_reg(DISPC_IRQENABLE, mask); 3802 dispc_write_reg(DISPC_IRQENABLE, mask);
3792} 3803}
3793EXPORT_SYMBOL(dispc_write_irqenable);
3794 3804
3795void dispc_enable_sidle(void) 3805void dispc_enable_sidle(void)
3796{ 3806{
@@ -3802,7 +3812,7 @@ void dispc_disable_sidle(void)
3802 REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ 3812 REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */
3803} 3813}
3804 3814
3805u32 dispc_mgr_gamma_size(enum omap_channel channel) 3815static u32 dispc_mgr_gamma_size(enum omap_channel channel)
3806{ 3816{
3807 const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; 3817 const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
3808 3818
@@ -3811,7 +3821,6 @@ u32 dispc_mgr_gamma_size(enum omap_channel channel)
3811 3821
3812 return gdesc->len; 3822 return gdesc->len;
3813} 3823}
3814EXPORT_SYMBOL(dispc_mgr_gamma_size);
3815 3824
3816static void dispc_mgr_write_gamma_table(enum omap_channel channel) 3825static void dispc_mgr_write_gamma_table(enum omap_channel channel)
3817{ 3826{
@@ -3856,7 +3865,7 @@ static const struct drm_color_lut dispc_mgr_gamma_default_lut[] = {
3856 { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, }, 3865 { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, },
3857}; 3866};
3858 3867
3859void dispc_mgr_set_gamma(enum omap_channel channel, 3868static void dispc_mgr_set_gamma(enum omap_channel channel,
3860 const struct drm_color_lut *lut, 3869 const struct drm_color_lut *lut,
3861 unsigned int length) 3870 unsigned int length)
3862{ 3871{
@@ -3902,7 +3911,6 @@ void dispc_mgr_set_gamma(enum omap_channel channel,
3902 if (dispc.is_enabled) 3911 if (dispc.is_enabled)
3903 dispc_mgr_write_gamma_table(channel); 3912 dispc_mgr_write_gamma_table(channel);
3904} 3913}
3905EXPORT_SYMBOL(dispc_mgr_set_gamma);
3906 3914
3907static int dispc_init_gamma_tables(void) 3915static int dispc_init_gamma_tables(void)
3908{ 3916{
@@ -4149,7 +4157,7 @@ static irqreturn_t dispc_irq_handler(int irq, void *arg)
4149 return dispc.user_handler(irq, dispc.user_data); 4157 return dispc.user_handler(irq, dispc.user_data);
4150} 4158}
4151 4159
4152int dispc_request_irq(irq_handler_t handler, void *dev_id) 4160static int dispc_request_irq(irq_handler_t handler, void *dev_id)
4153{ 4161{
4154 int r; 4162 int r;
4155 4163
@@ -4171,16 +4179,14 @@ int dispc_request_irq(irq_handler_t handler, void *dev_id)
4171 4179
4172 return r; 4180 return r;
4173} 4181}
4174EXPORT_SYMBOL(dispc_request_irq);
4175 4182
4176void dispc_free_irq(void *dev_id) 4183static void dispc_free_irq(void *dev_id)
4177{ 4184{
4178 devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc); 4185 devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
4179 4186
4180 dispc.user_handler = NULL; 4187 dispc.user_handler = NULL;
4181 dispc.user_data = NULL; 4188 dispc.user_data = NULL;
4182} 4189}
4183EXPORT_SYMBOL(dispc_free_irq);
4184 4190
4185/* 4191/*
4186 * Workaround for errata i734 in DSS dispc 4192 * Workaround for errata i734 in DSS dispc
@@ -4304,7 +4310,7 @@ static void dispc_errata_i734_wa(void)
4304 4310
4305 /* Setup and enable GFX plane */ 4311 /* Setup and enable GFX plane */
4306 dispc_ovl_set_channel_out(OMAP_DSS_GFX, OMAP_DSS_CHANNEL_LCD); 4312 dispc_ovl_set_channel_out(OMAP_DSS_GFX, OMAP_DSS_CHANNEL_LCD);
4307 dispc_ovl_setup(OMAP_DSS_GFX, &ovli, false, &i734.vm, false); 4313 dispc_ovl_setup(OMAP_DSS_GFX, &ovli, &i734.vm, false);
4308 dispc_ovl_enable(OMAP_DSS_GFX, true); 4314 dispc_ovl_enable(OMAP_DSS_GFX, true);
4309 4315
4310 /* Set up and enable display manager for LCD1 */ 4316 /* Set up and enable display manager for LCD1 */
@@ -4341,6 +4347,42 @@ static void dispc_errata_i734_wa(void)
4341 REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4); 4347 REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4);
4342} 4348}
4343 4349
4350static const struct dispc_ops dispc_ops = {
4351 .read_irqstatus = dispc_read_irqstatus,
4352 .clear_irqstatus = dispc_clear_irqstatus,
4353 .read_irqenable = dispc_read_irqenable,
4354 .write_irqenable = dispc_write_irqenable,
4355
4356 .request_irq = dispc_request_irq,
4357 .free_irq = dispc_free_irq,
4358
4359 .runtime_get = dispc_runtime_get,
4360 .runtime_put = dispc_runtime_put,
4361
4362 .get_num_ovls = dispc_get_num_ovls,
4363 .get_num_mgrs = dispc_get_num_mgrs,
4364
4365 .mgr_enable = dispc_mgr_enable,
4366 .mgr_is_enabled = dispc_mgr_is_enabled,
4367 .mgr_get_vsync_irq = dispc_mgr_get_vsync_irq,
4368 .mgr_get_framedone_irq = dispc_mgr_get_framedone_irq,
4369 .mgr_get_sync_lost_irq = dispc_mgr_get_sync_lost_irq,
4370 .mgr_go_busy = dispc_mgr_go_busy,
4371 .mgr_go = dispc_mgr_go,
4372 .mgr_set_lcd_config = dispc_mgr_set_lcd_config,
4373 .mgr_set_timings = dispc_mgr_set_timings,
4374 .mgr_setup = dispc_mgr_setup,
4375 .mgr_get_supported_outputs = dispc_mgr_get_supported_outputs,
4376 .mgr_gamma_size = dispc_mgr_gamma_size,
4377 .mgr_set_gamma = dispc_mgr_set_gamma,
4378
4379 .ovl_enable = dispc_ovl_enable,
4380 .ovl_enabled = dispc_ovl_enabled,
4381 .ovl_set_channel_out = dispc_ovl_set_channel_out,
4382 .ovl_setup = dispc_ovl_setup,
4383 .ovl_get_color_modes = dispc_ovl_get_color_modes,
4384};
4385
4344/* DISPC HW IP initialisation */ 4386/* DISPC HW IP initialisation */
4345static int dispc_bind(struct device *dev, struct device *master, void *data) 4387static int dispc_bind(struct device *dev, struct device *master, void *data)
4346{ 4388{
@@ -4413,6 +4455,8 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
4413 4455
4414 dispc_runtime_put(); 4456 dispc_runtime_put();
4415 4457
4458 dispc_set_ops(&dispc_ops);
4459
4416 dss_debugfs_create_file("dispc", dispc_dump_regs); 4460 dss_debugfs_create_file("dispc", dispc_dump_regs);
4417 4461
4418 return 0; 4462 return 0;
@@ -4425,6 +4469,8 @@ err_runtime_get:
4425static void dispc_unbind(struct device *dev, struct device *master, 4469static void dispc_unbind(struct device *dev, struct device *master,
4426 void *data) 4470 void *data)
4427{ 4471{
4472 dispc_set_ops(NULL);
4473
4428 pm_runtime_disable(dev); 4474 pm_runtime_disable(dev);
4429 4475
4430 dispc_errata_i734_wa_fini(); 4476 dispc_errata_i734_wa_fini();
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.h b/drivers/gpu/drm/omapdrm/dss/dispc.h
index bc1d8126ee87..003adce532f4 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.h
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.h
@@ -353,7 +353,7 @@ static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel)
353} 353}
354 354
355/* DISPC overlay register base addresses */ 355/* DISPC overlay register base addresses */
356static inline u16 DISPC_OVL_BASE(enum omap_plane plane) 356static inline u16 DISPC_OVL_BASE(enum omap_plane_id plane)
357{ 357{
358 switch (plane) { 358 switch (plane) {
359 case OMAP_DSS_GFX: 359 case OMAP_DSS_GFX:
@@ -373,7 +373,7 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
373} 373}
374 374
375/* DISPC overlay register offsets */ 375/* DISPC overlay register offsets */
376static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) 376static inline u16 DISPC_BA0_OFFSET(enum omap_plane_id plane)
377{ 377{
378 switch (plane) { 378 switch (plane) {
379 case OMAP_DSS_GFX: 379 case OMAP_DSS_GFX:
@@ -389,7 +389,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
389 } 389 }
390} 390}
391 391
392static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) 392static inline u16 DISPC_BA1_OFFSET(enum omap_plane_id plane)
393{ 393{
394 switch (plane) { 394 switch (plane) {
395 case OMAP_DSS_GFX: 395 case OMAP_DSS_GFX:
@@ -405,7 +405,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
405 } 405 }
406} 406}
407 407
408static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) 408static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane_id plane)
409{ 409{
410 switch (plane) { 410 switch (plane) {
411 case OMAP_DSS_GFX: 411 case OMAP_DSS_GFX:
@@ -425,7 +425,7 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
425 } 425 }
426} 426}
427 427
428static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) 428static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane_id plane)
429{ 429{
430 switch (plane) { 430 switch (plane) {
431 case OMAP_DSS_GFX: 431 case OMAP_DSS_GFX:
@@ -445,7 +445,7 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
445 } 445 }
446} 446}
447 447
448static inline u16 DISPC_POS_OFFSET(enum omap_plane plane) 448static inline u16 DISPC_POS_OFFSET(enum omap_plane_id plane)
449{ 449{
450 switch (plane) { 450 switch (plane) {
451 case OMAP_DSS_GFX: 451 case OMAP_DSS_GFX:
@@ -460,7 +460,7 @@ static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
460 } 460 }
461} 461}
462 462
463static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) 463static inline u16 DISPC_SIZE_OFFSET(enum omap_plane_id plane)
464{ 464{
465 switch (plane) { 465 switch (plane) {
466 case OMAP_DSS_GFX: 466 case OMAP_DSS_GFX:
@@ -476,7 +476,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
476 } 476 }
477} 477}
478 478
479static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) 479static inline u16 DISPC_ATTR_OFFSET(enum omap_plane_id plane)
480{ 480{
481 switch (plane) { 481 switch (plane) {
482 case OMAP_DSS_GFX: 482 case OMAP_DSS_GFX:
@@ -493,7 +493,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
493 } 493 }
494} 494}
495 495
496static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) 496static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane_id plane)
497{ 497{
498 switch (plane) { 498 switch (plane) {
499 case OMAP_DSS_GFX: 499 case OMAP_DSS_GFX:
@@ -513,7 +513,7 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
513 } 513 }
514} 514}
515 515
516static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) 516static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane_id plane)
517{ 517{
518 switch (plane) { 518 switch (plane) {
519 case OMAP_DSS_GFX: 519 case OMAP_DSS_GFX:
@@ -530,7 +530,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
530 } 530 }
531} 531}
532 532
533static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane) 533static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane_id plane)
534{ 534{
535 switch (plane) { 535 switch (plane) {
536 case OMAP_DSS_GFX: 536 case OMAP_DSS_GFX:
@@ -547,7 +547,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
547 } 547 }
548} 548}
549 549
550static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) 550static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane_id plane)
551{ 551{
552 switch (plane) { 552 switch (plane) {
553 case OMAP_DSS_GFX: 553 case OMAP_DSS_GFX:
@@ -564,7 +564,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
564 } 564 }
565} 565}
566 566
567static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) 567static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane_id plane)
568{ 568{
569 switch (plane) { 569 switch (plane) {
570 case OMAP_DSS_GFX: 570 case OMAP_DSS_GFX:
@@ -581,7 +581,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
581 } 581 }
582} 582}
583 583
584static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane) 584static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane_id plane)
585{ 585{
586 switch (plane) { 586 switch (plane) {
587 case OMAP_DSS_GFX: 587 case OMAP_DSS_GFX:
@@ -597,7 +597,7 @@ static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
597 } 597 }
598} 598}
599 599
600static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane) 600static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane_id plane)
601{ 601{
602 switch (plane) { 602 switch (plane) {
603 case OMAP_DSS_GFX: 603 case OMAP_DSS_GFX:
@@ -613,7 +613,7 @@ static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
613 } 613 }
614} 614}
615 615
616static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) 616static inline u16 DISPC_FIR_OFFSET(enum omap_plane_id plane)
617{ 617{
618 switch (plane) { 618 switch (plane) {
619 case OMAP_DSS_GFX: 619 case OMAP_DSS_GFX:
@@ -631,7 +631,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
631 } 631 }
632} 632}
633 633
634static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) 634static inline u16 DISPC_FIR2_OFFSET(enum omap_plane_id plane)
635{ 635{
636 switch (plane) { 636 switch (plane) {
637 case OMAP_DSS_GFX: 637 case OMAP_DSS_GFX:
@@ -651,7 +651,7 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
651 } 651 }
652} 652}
653 653
654static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) 654static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane_id plane)
655{ 655{
656 switch (plane) { 656 switch (plane) {
657 case OMAP_DSS_GFX: 657 case OMAP_DSS_GFX:
@@ -670,7 +670,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
670} 670}
671 671
672 672
673static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) 673static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane_id plane)
674{ 674{
675 switch (plane) { 675 switch (plane) {
676 case OMAP_DSS_GFX: 676 case OMAP_DSS_GFX:
@@ -688,7 +688,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
688 } 688 }
689} 689}
690 690
691static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) 691static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane_id plane)
692{ 692{
693 switch (plane) { 693 switch (plane) {
694 case OMAP_DSS_GFX: 694 case OMAP_DSS_GFX:
@@ -708,7 +708,7 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
708 } 708 }
709} 709}
710 710
711static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) 711static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane_id plane)
712{ 712{
713 switch (plane) { 713 switch (plane) {
714 case OMAP_DSS_GFX: 714 case OMAP_DSS_GFX:
@@ -726,7 +726,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
726 } 726 }
727} 727}
728 728
729static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) 729static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane_id plane)
730{ 730{
731 switch (plane) { 731 switch (plane) {
732 case OMAP_DSS_GFX: 732 case OMAP_DSS_GFX:
@@ -747,7 +747,7 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
747} 747}
748 748
749/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ 749/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
750static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) 750static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane_id plane, u16 i)
751{ 751{
752 switch (plane) { 752 switch (plane) {
753 case OMAP_DSS_GFX: 753 case OMAP_DSS_GFX:
@@ -766,7 +766,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
766} 766}
767 767
768/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ 768/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
769static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) 769static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane_id plane, u16 i)
770{ 770{
771 switch (plane) { 771 switch (plane) {
772 case OMAP_DSS_GFX: 772 case OMAP_DSS_GFX:
@@ -787,7 +787,7 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
787} 787}
788 788
789/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ 789/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
790static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) 790static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane_id plane, u16 i)
791{ 791{
792 switch (plane) { 792 switch (plane) {
793 case OMAP_DSS_GFX: 793 case OMAP_DSS_GFX:
@@ -806,7 +806,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
806} 806}
807 807
808/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ 808/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
809static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) 809static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane_id plane, u16 i)
810{ 810{
811 switch (plane) { 811 switch (plane) {
812 case OMAP_DSS_GFX: 812 case OMAP_DSS_GFX:
@@ -827,7 +827,7 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
827} 827}
828 828
829/* coef index i = {0, 1, 2, 3, 4,} */ 829/* coef index i = {0, 1, 2, 3, 4,} */
830static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) 830static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane_id plane, u16 i)
831{ 831{
832 switch (plane) { 832 switch (plane) {
833 case OMAP_DSS_GFX: 833 case OMAP_DSS_GFX:
@@ -845,7 +845,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
845} 845}
846 846
847/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ 847/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
848static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) 848static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane_id plane, u16 i)
849{ 849{
850 switch (plane) { 850 switch (plane) {
851 case OMAP_DSS_GFX: 851 case OMAP_DSS_GFX:
@@ -865,7 +865,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
865} 865}
866 866
867/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ 867/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
868static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) 868static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane_id plane, u16 i)
869{ 869{
870 switch (plane) { 870 switch (plane) {
871 case OMAP_DSS_GFX: 871 case OMAP_DSS_GFX:
@@ -885,7 +885,7 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
885 } 885 }
886} 886}
887 887
888static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane) 888static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane_id plane)
889{ 889{
890 switch (plane) { 890 switch (plane) {
891 case OMAP_DSS_GFX: 891 case OMAP_DSS_GFX:
@@ -902,7 +902,7 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
902 } 902 }
903} 903}
904 904
905static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane plane) 905static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane_id plane)
906{ 906{
907 switch (plane) { 907 switch (plane) {
908 case OMAP_DSS_GFX: 908 case OMAP_DSS_GFX:
diff --git a/drivers/gpu/drm/omapdrm/dss/display.c b/drivers/gpu/drm/omapdrm/dss/display.c
index 425a5a8dff8b..26cb59be045e 100644
--- a/drivers/gpu/drm/omapdrm/dss/display.c
+++ b/drivers/gpu/drm/omapdrm/dss/display.c
@@ -29,8 +29,6 @@
29#include <linux/of.h> 29#include <linux/of.h>
30 30
31#include "omapdss.h" 31#include "omapdss.h"
32#include "dss.h"
33#include "dss_features.h"
34 32
35void omapdss_default_get_resolution(struct omap_dss_device *dssdev, 33void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
36 u16 *xres, u16 *yres) 34 u16 *xres, u16 *yres)
@@ -55,10 +53,10 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
55 else 53 else
56 return 16; 54 return 16;
57 case OMAP_DISPLAY_TYPE_DSI: 55 case OMAP_DISPLAY_TYPE_DSI:
58 if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16) 56 if (dssdev->panel.dsi_pix_fmt == OMAP_DSS_DSI_FMT_RGB565)
59 return 24;
60 else
61 return 16; 57 return 16;
58 else
59 return 24;
62 case OMAP_DISPLAY_TYPE_VENC: 60 case OMAP_DISPLAY_TYPE_VENC:
63 case OMAP_DISPLAY_TYPE_SDI: 61 case OMAP_DISPLAY_TYPE_SDI:
64 case OMAP_DISPLAY_TYPE_HDMI: 62 case OMAP_DISPLAY_TYPE_HDMI:
@@ -85,6 +83,7 @@ static int disp_num_counter;
85int omapdss_register_display(struct omap_dss_device *dssdev) 83int omapdss_register_display(struct omap_dss_device *dssdev)
86{ 84{
87 struct omap_dss_driver *drv = dssdev->driver; 85 struct omap_dss_driver *drv = dssdev->driver;
86 struct list_head *cur;
88 int id; 87 int id;
89 88
90 /* 89 /*
@@ -120,7 +119,14 @@ int omapdss_register_display(struct omap_dss_device *dssdev)
120 drv->get_timings = omapdss_default_get_timings; 119 drv->get_timings = omapdss_default_get_timings;
121 120
122 mutex_lock(&panel_list_mutex); 121 mutex_lock(&panel_list_mutex);
123 list_add_tail(&dssdev->panel_list, &panel_list); 122 list_for_each(cur, &panel_list) {
123 struct omap_dss_device *ldev = list_entry(cur,
124 struct omap_dss_device,
125 panel_list);
126 if (strcmp(ldev->alias, dssdev->alias) > 0)
127 break;
128 }
129 list_add_tail(&dssdev->panel_list, cur);
124 mutex_unlock(&panel_list_mutex); 130 mutex_unlock(&panel_list_mutex);
125 return 0; 131 return 0;
126} 132}
@@ -134,6 +140,24 @@ void omapdss_unregister_display(struct omap_dss_device *dssdev)
134} 140}
135EXPORT_SYMBOL(omapdss_unregister_display); 141EXPORT_SYMBOL(omapdss_unregister_display);
136 142
143bool omapdss_component_is_display(struct device_node *node)
144{
145 struct omap_dss_device *dssdev;
146 bool found = false;
147
148 mutex_lock(&panel_list_mutex);
149 list_for_each_entry(dssdev, &panel_list, panel_list) {
150 if (dssdev->dev->of_node == node) {
151 found = true;
152 goto out;
153 }
154 }
155out:
156 mutex_unlock(&panel_list_mutex);
157 return found;
158}
159EXPORT_SYMBOL(omapdss_component_is_display);
160
137struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev) 161struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
138{ 162{
139 if (!try_module_get(dssdev->owner)) 163 if (!try_module_get(dssdev->owner))
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index e75162d26ac0..51d90a8a61cd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -67,6 +67,45 @@ static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
67 return dev_get_drvdata(&pdev->dev); 67 return dev_get_drvdata(&pdev->dev);
68} 68}
69 69
70static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
71{
72 /*
73 * Possible clock sources:
74 * LCD1: FCK/PLL1_1/HDMI_PLL
75 * LCD2: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_3)
76 * LCD3: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_1)
77 */
78
79 switch (channel) {
80 case OMAP_DSS_CHANNEL_LCD:
81 {
82 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1))
83 return DSS_CLK_SRC_PLL1_1;
84 break;
85 }
86 case OMAP_DSS_CHANNEL_LCD2:
87 {
88 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
89 return DSS_CLK_SRC_PLL1_3;
90 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3))
91 return DSS_CLK_SRC_PLL2_3;
92 break;
93 }
94 case OMAP_DSS_CHANNEL_LCD3:
95 {
96 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1))
97 return DSS_CLK_SRC_PLL2_1;
98 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
99 return DSS_CLK_SRC_PLL1_3;
100 break;
101 }
102 default:
103 break;
104 }
105
106 return DSS_CLK_SRC_FCK;
107}
108
70static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel) 109static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
71{ 110{
72 /* 111 /*
@@ -107,16 +146,7 @@ static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
107 } 146 }
108 147
109 case OMAPDSS_VER_DRA7xx: 148 case OMAPDSS_VER_DRA7xx:
110 switch (channel) { 149 return dpi_get_clk_src_dra7xx(channel);
111 case OMAP_DSS_CHANNEL_LCD:
112 return DSS_CLK_SRC_PLL1_1;
113 case OMAP_DSS_CHANNEL_LCD2:
114 return DSS_CLK_SRC_PLL1_3;
115 case OMAP_DSS_CHANNEL_LCD3:
116 return DSS_CLK_SRC_PLL2_1;
117 default:
118 return DSS_CLK_SRC_FCK;
119 }
120 150
121 default: 151 default:
122 return DSS_CLK_SRC_FCK; 152 return DSS_CLK_SRC_FCK;
@@ -170,14 +200,6 @@ static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
170{ 200{
171 struct dpi_clk_calc_ctx *ctx = data; 201 struct dpi_clk_calc_ctx *ctx = data;
172 202
173 /*
174 * Odd dividers give us uneven duty cycle, causing problem when level
175 * shifted. So skip all odd dividers when the pixel clock is on the
176 * higher side.
177 */
178 if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000)
179 return false;
180
181 ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc; 203 ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
182 ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc; 204 ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
183 205
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 5e51a5649efb..f50d6fc0d92e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -527,7 +527,7 @@ static inline int wait_for_bit_change(struct platform_device *dsidev,
527 return !value; 527 return !value;
528} 528}
529 529
530u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) 530static u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
531{ 531{
532 switch (fmt) { 532 switch (fmt) {
533 case OMAP_DSS_DSI_FMT_RGB888: 533 case OMAP_DSS_DSI_FMT_RGB888:
diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c b/drivers/gpu/drm/omapdrm/dss/dss-of.c
index dfd4e9621e3b..b46606b0f014 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss-of.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss-of.c
@@ -19,7 +19,6 @@
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20 20
21#include "omapdss.h" 21#include "omapdss.h"
22#include "dss.h"
23 22
24struct device_node * 23struct device_node *
25omapdss_of_get_next_port(const struct device_node *parent, 24omapdss_of_get_next_port(const struct device_node *parent,
@@ -110,6 +109,7 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port)
110 109
111 return NULL; 110 return NULL;
112} 111}
112EXPORT_SYMBOL_GPL(dss_of_port_get_parent_device);
113 113
114u32 dss_of_port_get_port_number(struct device_node *port) 114u32 dss_of_port_get_port_number(struct device_node *port)
115{ 115{
@@ -122,6 +122,7 @@ u32 dss_of_port_get_port_number(struct device_node *port)
122 122
123 return reg; 123 return reg;
124} 124}
125EXPORT_SYMBOL_GPL(dss_of_port_get_port_number);
125 126
126static struct device_node *omapdss_of_get_remote_port(const struct device_node *node) 127static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
127{ 128{
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 4e72d2fefb4d..ceb483650f8c 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -117,14 +117,6 @@ static const char * const dss_generic_clk_source_names[] = {
117 [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL", 117 [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL",
118}; 118};
119 119
120static bool dss_initialized;
121
122bool omapdss_is_initialized(void)
123{
124 return dss_initialized;
125}
126EXPORT_SYMBOL(omapdss_is_initialized);
127
128static inline void dss_write_reg(const struct dss_reg idx, u32 val) 120static inline void dss_write_reg(const struct dss_reg idx, u32 val)
129{ 121{
130 __raw_writel(val, dss.base + idx.idx); 122 __raw_writel(val, dss.base + idx.idx);
@@ -1266,7 +1258,8 @@ static int dss_bind(struct device *dev)
1266 1258
1267 pm_set_vt_switch(0); 1259 pm_set_vt_switch(0);
1268 1260
1269 dss_initialized = true; 1261 omapdss_gather_components(dev);
1262 omapdss_set_is_initialized(true);
1270 1263
1271 return 0; 1264 return 0;
1272 1265
@@ -1290,7 +1283,7 @@ static void dss_unbind(struct device *dev)
1290{ 1283{
1291 struct platform_device *pdev = to_platform_device(dev); 1284 struct platform_device *pdev = to_platform_device(dev);
1292 1285
1293 dss_initialized = false; 1286 omapdss_set_is_initialized(false);
1294 1287
1295 component_unbind_all(&pdev->dev, NULL); 1288 component_unbind_all(&pdev->dev, NULL);
1296 1289
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 78f6fc75948b..5dd29c98143a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -253,10 +253,6 @@ struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
253 struct regulator *regulator); 253 struct regulator *regulator);
254void dss_video_pll_uninit(struct dss_pll *pll); 254void dss_video_pll_uninit(struct dss_pll *pll);
255 255
256/* dss-of */
257struct device_node *dss_of_port_get_parent_device(struct device_node *port);
258u32 dss_of_port_get_port_number(struct device_node *port);
259
260#if defined(CONFIG_OMAP2_DSS_DEBUGFS) 256#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
261void dss_debug_dump_clocks(struct seq_file *s); 257void dss_debug_dump_clocks(struct seq_file *s);
262#endif 258#endif
@@ -315,15 +311,7 @@ void dsi_uninit_platform_driver(void);
315void dsi_dump_clocks(struct seq_file *s); 311void dsi_dump_clocks(struct seq_file *s);
316 312
317void dsi_irq_handler(void); 313void dsi_irq_handler(void);
318u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
319 314
320#else
321static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
322{
323 WARN(1, "%s: DSI not compiled in, returning pixel_size as 0\n",
324 __func__);
325 return 0;
326}
327#endif 315#endif
328 316
329/* DPI */ 317/* DPI */
@@ -349,6 +337,9 @@ int dispc_init_platform_driver(void) __init;
349void dispc_uninit_platform_driver(void); 337void dispc_uninit_platform_driver(void);
350void dispc_dump_clocks(struct seq_file *s); 338void dispc_dump_clocks(struct seq_file *s);
351 339
340int dispc_runtime_get(void);
341void dispc_runtime_put(void);
342
352void dispc_enable_sidle(void); 343void dispc_enable_sidle(void);
353void dispc_disable_sidle(void); 344void dispc_disable_sidle(void);
354 345
@@ -368,8 +359,9 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
368 struct dispc_clock_info *cinfo); 359 struct dispc_clock_info *cinfo);
369 360
370 361
371void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); 362void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
372void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 363 u32 high);
364void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
373 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, 365 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
374 bool manual_update); 366 bool manual_update);
375 367
@@ -382,8 +374,6 @@ void dispc_set_tv_pclk(unsigned long pclk);
382u32 dispc_wb_get_framedone_irq(void); 374u32 dispc_wb_get_framedone_irq(void);
383bool dispc_wb_go_busy(void); 375bool dispc_wb_go_busy(void);
384void dispc_wb_go(void); 376void dispc_wb_go(void);
385void dispc_wb_enable(bool enable);
386bool dispc_wb_is_enabled(void);
387void dispc_wb_set_channel_in(enum dss_writeback_channel channel); 377void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
388int dispc_wb_setup(const struct omap_dss_writeback_info *wi, 378int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
389 bool mem_to_mem, const struct videomode *vm); 379 bool mem_to_mem, const struct videomode *vm);
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.c b/drivers/gpu/drm/omapdrm/dss/dss_features.c
index ee5b93ce2763..80c6440a0e08 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss_features.c
@@ -774,13 +774,11 @@ int dss_feat_get_num_mgrs(void)
774{ 774{
775 return omap_current_dss_features->num_mgrs; 775 return omap_current_dss_features->num_mgrs;
776} 776}
777EXPORT_SYMBOL(dss_feat_get_num_mgrs);
778 777
779int dss_feat_get_num_ovls(void) 778int dss_feat_get_num_ovls(void)
780{ 779{
781 return omap_current_dss_features->num_ovls; 780 return omap_current_dss_features->num_ovls;
782} 781}
783EXPORT_SYMBOL(dss_feat_get_num_ovls);
784 782
785unsigned long dss_feat_get_param_min(enum dss_range_param param) 783unsigned long dss_feat_get_param_min(enum dss_range_param param)
786{ 784{
@@ -802,18 +800,17 @@ enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel
802 return omap_current_dss_features->supported_outputs[channel]; 800 return omap_current_dss_features->supported_outputs[channel];
803} 801}
804 802
805enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) 803enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane_id plane)
806{ 804{
807 return omap_current_dss_features->supported_color_modes[plane]; 805 return omap_current_dss_features->supported_color_modes[plane];
808} 806}
809EXPORT_SYMBOL(dss_feat_get_supported_color_modes);
810 807
811enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane) 808enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane)
812{ 809{
813 return omap_current_dss_features->overlay_caps[plane]; 810 return omap_current_dss_features->overlay_caps[plane];
814} 811}
815 812
816bool dss_feat_color_mode_supported(enum omap_plane plane, 813bool dss_feat_color_mode_supported(enum omap_plane_id plane,
817 enum omap_color_mode color_mode) 814 enum omap_color_mode color_mode)
818{ 815{
819 return omap_current_dss_features->supported_color_modes[plane] & 816 return omap_current_dss_features->supported_color_modes[plane] &
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.h b/drivers/gpu/drm/omapdrm/dss/dss_features.h
index bb4b7f0e642b..27fbe64935e8 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss_features.h
@@ -88,8 +88,8 @@ enum dss_range_param {
88/* DSS Feature Functions */ 88/* DSS Feature Functions */
89unsigned long dss_feat_get_param_min(enum dss_range_param param); 89unsigned long dss_feat_get_param_min(enum dss_range_param param);
90unsigned long dss_feat_get_param_max(enum dss_range_param param); 90unsigned long dss_feat_get_param_max(enum dss_range_param param);
91enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); 91enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane);
92bool dss_feat_color_mode_supported(enum omap_plane plane, 92bool dss_feat_color_mode_supported(enum omap_plane_id plane,
93 enum omap_color_mode color_mode); 93 enum omap_color_mode color_mode);
94 94
95u32 dss_feat_get_buffer_size_unit(void); /* in bytes */ 95u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
@@ -104,4 +104,8 @@ void dss_features_init(enum omapdss_version version);
104enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 104enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
105enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel); 105enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
106 106
107int dss_feat_get_num_mgrs(void);
108int dss_feat_get_num_ovls(void);
109enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane_id plane);
110
107#endif 111#endif
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
index b783d5a0750e..597ec9d87d1d 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
@@ -147,15 +147,17 @@ void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
147 struct videomode *vm) 147 struct videomode *vm)
148{ 148{
149 u32 r; 149 u32 r;
150 bool vsync_pol, hsync_pol; 150 bool vsync_inv, hsync_inv;
151 DSSDBG("Enter hdmi_wp_video_config_interface\n"); 151 DSSDBG("Enter hdmi_wp_video_config_interface\n");
152 152
153 vsync_pol = !!(vm->flags & DISPLAY_FLAGS_VSYNC_HIGH); 153 vsync_inv = !!(vm->flags & DISPLAY_FLAGS_VSYNC_LOW);
154 hsync_pol = !!(vm->flags & DISPLAY_FLAGS_HSYNC_HIGH); 154 hsync_inv = !!(vm->flags & DISPLAY_FLAGS_HSYNC_LOW);
155 155
156 r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG); 156 r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG);
157 r = FLD_MOD(r, vsync_pol, 7, 7); 157 r = FLD_MOD(r, 1, 7, 7); /* VSYNC_POL to dispc active high */
158 r = FLD_MOD(r, hsync_pol, 6, 6); 158 r = FLD_MOD(r, 1, 6, 6); /* HSYNC_POL to dispc active high */
159 r = FLD_MOD(r, vsync_inv, 5, 5); /* CORE_VSYNC_INV */
160 r = FLD_MOD(r, hsync_inv, 4, 4); /* CORE_HSYNC_INV */
159 r = FLD_MOD(r, !!(vm->flags & DISPLAY_FLAGS_INTERLACED), 3, 3); 161 r = FLD_MOD(r, !!(vm->flags & DISPLAY_FLAGS_INTERLACED), 3, 3);
160 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ 162 r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */
161 hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r); 163 hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 5b3b961127bd..63c2684f889b 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -76,7 +76,7 @@ enum omap_display_type {
76 OMAP_DISPLAY_TYPE_DVI = 1 << 6, 76 OMAP_DISPLAY_TYPE_DVI = 1 << 6,
77}; 77};
78 78
79enum omap_plane { 79enum omap_plane_id {
80 OMAP_DSS_GFX = 0, 80 OMAP_DSS_GFX = 0,
81 OMAP_DSS_VIDEO1 = 1, 81 OMAP_DSS_VIDEO1 = 1,
82 OMAP_DSS_VIDEO2 = 2, 82 OMAP_DSS_VIDEO2 = 2,
@@ -338,7 +338,7 @@ struct omap_overlay {
338 338
339 /* static fields */ 339 /* static fields */
340 const char *name; 340 const char *name;
341 enum omap_plane id; 341 enum omap_plane_id id;
342 enum omap_color_mode supported_modes; 342 enum omap_color_mode supported_modes;
343 enum omap_overlay_caps caps; 343 enum omap_overlay_caps caps;
344 344
@@ -785,7 +785,7 @@ const char *omapdss_get_default_display_name(void);
785 785
786int dss_feat_get_num_mgrs(void); 786int dss_feat_get_num_mgrs(void);
787int dss_feat_get_num_ovls(void); 787int dss_feat_get_num_ovls(void);
788enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 788enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane_id plane);
789 789
790 790
791 791
@@ -844,42 +844,10 @@ omapdss_of_get_first_endpoint(const struct device_node *parent);
844struct omap_dss_device * 844struct omap_dss_device *
845omapdss_of_find_source_for_first_ep(struct device_node *node); 845omapdss_of_find_source_for_first_ep(struct device_node *node);
846 846
847u32 dispc_read_irqstatus(void); 847void omapdss_set_is_initialized(bool set);
848void dispc_clear_irqstatus(u32 mask);
849u32 dispc_read_irqenable(void);
850void dispc_write_irqenable(u32 mask);
851 848
852int dispc_request_irq(irq_handler_t handler, void *dev_id); 849struct device_node *dss_of_port_get_parent_device(struct device_node *port);
853void dispc_free_irq(void *dev_id); 850u32 dss_of_port_get_port_number(struct device_node *port);
854
855int dispc_runtime_get(void);
856void dispc_runtime_put(void);
857
858void dispc_mgr_enable(enum omap_channel channel, bool enable);
859u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
860u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
861u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel);
862bool dispc_mgr_go_busy(enum omap_channel channel);
863void dispc_mgr_go(enum omap_channel channel);
864void dispc_mgr_set_lcd_config(enum omap_channel channel,
865 const struct dss_lcd_mgr_config *config);
866void dispc_mgr_set_timings(enum omap_channel channel,
867 const struct videomode *vm);
868void dispc_mgr_setup(enum omap_channel channel,
869 const struct omap_overlay_manager_info *info);
870u32 dispc_mgr_gamma_size(enum omap_channel channel);
871void dispc_mgr_set_gamma(enum omap_channel channel,
872 const struct drm_color_lut *lut,
873 unsigned int length);
874
875int dispc_ovl_enable(enum omap_plane plane, bool enable);
876bool dispc_ovl_enabled(enum omap_plane plane);
877void dispc_ovl_set_channel_out(enum omap_plane plane,
878 enum omap_channel channel);
879int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
880 bool replication, const struct videomode *vm, bool mem_to_mem);
881
882enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel);
883 851
884struct dss_mgr_ops { 852struct dss_mgr_ops {
885 int (*connect)(enum omap_channel channel, 853 int (*connect)(enum omap_channel channel,
@@ -919,4 +887,60 @@ int dss_mgr_register_framedone_handler(enum omap_channel channel,
919void dss_mgr_unregister_framedone_handler(enum omap_channel channel, 887void dss_mgr_unregister_framedone_handler(enum omap_channel channel,
920 void (*handler)(void *), void *data); 888 void (*handler)(void *), void *data);
921 889
890/* dispc ops */
891
892struct dispc_ops {
893 u32 (*read_irqstatus)(void);
894 void (*clear_irqstatus)(u32 mask);
895 u32 (*read_irqenable)(void);
896 void (*write_irqenable)(u32 mask);
897
898 int (*request_irq)(irq_handler_t handler, void *dev_id);
899 void (*free_irq)(void *dev_id);
900
901 int (*runtime_get)(void);
902 void (*runtime_put)(void);
903
904 int (*get_num_ovls)(void);
905 int (*get_num_mgrs)(void);
906
907 void (*mgr_enable)(enum omap_channel channel, bool enable);
908 bool (*mgr_is_enabled)(enum omap_channel channel);
909 u32 (*mgr_get_vsync_irq)(enum omap_channel channel);
910 u32 (*mgr_get_framedone_irq)(enum omap_channel channel);
911 u32 (*mgr_get_sync_lost_irq)(enum omap_channel channel);
912 bool (*mgr_go_busy)(enum omap_channel channel);
913 void (*mgr_go)(enum omap_channel channel);
914 void (*mgr_set_lcd_config)(enum omap_channel channel,
915 const struct dss_lcd_mgr_config *config);
916 void (*mgr_set_timings)(enum omap_channel channel,
917 const struct videomode *vm);
918 void (*mgr_setup)(enum omap_channel channel,
919 const struct omap_overlay_manager_info *info);
920 enum omap_dss_output_id (*mgr_get_supported_outputs)(enum omap_channel channel);
921 u32 (*mgr_gamma_size)(enum omap_channel channel);
922 void (*mgr_set_gamma)(enum omap_channel channel,
923 const struct drm_color_lut *lut,
924 unsigned int length);
925
926 int (*ovl_enable)(enum omap_plane_id plane, bool enable);
927 bool (*ovl_enabled)(enum omap_plane_id plane);
928 void (*ovl_set_channel_out)(enum omap_plane_id plane,
929 enum omap_channel channel);
930 int (*ovl_setup)(enum omap_plane_id plane,
931 const struct omap_overlay_info *oi,
932 const struct videomode *vm, bool mem_to_mem);
933
934 enum omap_color_mode (*ovl_get_color_modes)(enum omap_plane_id plane);
935};
936
937void dispc_set_ops(const struct dispc_ops *o);
938const struct dispc_ops *dispc_get_ops(void);
939
940bool omapdss_component_is_display(struct device_node *node);
941bool omapdss_component_is_output(struct device_node *node);
942
943bool omapdss_stack_is_ready(void);
944void omapdss_gather_components(struct device *dev);
945
922#endif /* __OMAP_DRM_DSS_H */ 946#endif /* __OMAP_DRM_DSS_H */
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
index a901af5a9bc3..655c5d73eac9 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -22,7 +22,6 @@
22#include <linux/of.h> 22#include <linux/of.h>
23 23
24#include "omapdss.h" 24#include "omapdss.h"
25#include "dss.h"
26 25
27static LIST_HEAD(output_list); 26static LIST_HEAD(output_list);
28static DEFINE_MUTEX(output_lock); 27static DEFINE_MUTEX(output_lock);
@@ -35,14 +34,15 @@ int omapdss_output_set_device(struct omap_dss_device *out,
35 mutex_lock(&output_lock); 34 mutex_lock(&output_lock);
36 35
37 if (out->dst) { 36 if (out->dst) {
38 DSSERR("output already has device %s connected to it\n", 37 dev_err(out->dev,
38 "output already has device %s connected to it\n",
39 out->dst->name); 39 out->dst->name);
40 r = -EINVAL; 40 r = -EINVAL;
41 goto err; 41 goto err;
42 } 42 }
43 43
44 if (out->output_type != dssdev->type) { 44 if (out->output_type != dssdev->type) {
45 DSSERR("output type and display type don't match\n"); 45 dev_err(out->dev, "output type and display type don't match\n");
46 r = -EINVAL; 46 r = -EINVAL;
47 goto err; 47 goto err;
48 } 48 }
@@ -67,14 +67,16 @@ int omapdss_output_unset_device(struct omap_dss_device *out)
67 mutex_lock(&output_lock); 67 mutex_lock(&output_lock);
68 68
69 if (!out->dst) { 69 if (!out->dst) {
70 DSSERR("output doesn't have a device connected to it\n"); 70 dev_err(out->dev,
71 "output doesn't have a device connected to it\n");
71 r = -EINVAL; 72 r = -EINVAL;
72 goto err; 73 goto err;
73 } 74 }
74 75
75 if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { 76 if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) {
76 DSSERR("device %s is not disabled, cannot unset device\n", 77 dev_err(out->dev,
77 out->dst->name); 78 "device %s is not disabled, cannot unset device\n",
79 out->dst->name);
78 r = -EINVAL; 80 r = -EINVAL;
79 goto err; 81 goto err;
80 } 82 }
@@ -105,6 +107,19 @@ void omapdss_unregister_output(struct omap_dss_device *out)
105} 107}
106EXPORT_SYMBOL(omapdss_unregister_output); 108EXPORT_SYMBOL(omapdss_unregister_output);
107 109
110bool omapdss_component_is_output(struct device_node *node)
111{
112 struct omap_dss_device *out;
113
114 list_for_each_entry(out, &output_list, list) {
115 if (out->dev->of_node == node)
116 return true;
117 }
118
119 return false;
120}
121EXPORT_SYMBOL(omapdss_component_is_output);
122
108struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id) 123struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
109{ 124{
110 struct omap_dss_device *out; 125 struct omap_dss_device *out;
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 0a76c89cdc2e..5e221302768b 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -215,8 +215,8 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
215 dss_pll_calc_func func, void *data) 215 dss_pll_calc_func func, void *data)
216{ 216{
217 const struct dss_pll_hw *hw = pll->hw; 217 const struct dss_pll_hw *hw = pll->hw;
218 int n, n_start, n_stop; 218 int n, n_min, n_max;
219 int m, m_start, m_stop; 219 int m, m_min, m_max;
220 unsigned long fint, clkdco; 220 unsigned long fint, clkdco;
221 unsigned long pll_hw_max; 221 unsigned long pll_hw_max;
222 unsigned long fint_hw_min, fint_hw_max; 222 unsigned long fint_hw_min, fint_hw_max;
@@ -226,21 +226,22 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
226 fint_hw_min = hw->fint_min; 226 fint_hw_min = hw->fint_min;
227 fint_hw_max = hw->fint_max; 227 fint_hw_max = hw->fint_max;
228 228
229 n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); 229 n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
230 n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max); 230 n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max);
231 231
232 pll_max = pll_max ? pll_max : ULONG_MAX; 232 pll_max = pll_max ? pll_max : ULONG_MAX;
233 233
234 for (n = n_start; n <= n_stop; ++n) { 234 /* Try to find high N & M to avoid jitter (DRA7 errata i886) */
235 for (n = n_max; n >= n_min; --n) {
235 fint = clkin / n; 236 fint = clkin / n;
236 237
237 m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2), 238 m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
238 1ul); 239 1ul);
239 m_stop = min3((unsigned)(pll_max / fint / 2), 240 m_max = min3((unsigned)(pll_max / fint / 2),
240 (unsigned)(pll_hw_max / fint / 2), 241 (unsigned)(pll_hw_max / fint / 2),
241 hw->m_max); 242 hw->m_max);
242 243
243 for (m = m_start; m <= m_stop; ++m) { 244 for (m = m_max; m >= m_min; --m) {
244 clkdco = 2 * m * fint; 245 clkdco = 2 * m * fint;
245 246
246 if (func(n, m, fint, clkdco, data)) 247 if (func(n, m, fint, clkdco, data))
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index f90e2d22c5ec..c24b6b783e9a 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -146,8 +146,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
146 int r, ret = MODE_BAD; 146 int r, ret = MODE_BAD;
147 147
148 drm_display_mode_to_videomode(mode, &vm); 148 drm_display_mode_to_videomode(mode, &vm);
149 vm.flags |= DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
150 DISPLAY_FLAGS_SYNC_NEGEDGE;
151 mode->vrefresh = drm_mode_vrefresh(mode); 149 mode->vrefresh = drm_mode_vrefresh(mode);
152 150
153 /* 151 /*
@@ -162,6 +160,12 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
162 160
163 dssdrv->get_timings(dssdev, &t); 161 dssdrv->get_timings(dssdev, &t);
164 162
163 /*
164 * Ignore the flags, as we don't get them from
165 * drm_display_mode_to_videomode.
166 */
167 t.flags = 0;
168
165 if (memcmp(&vm, &t, sizeof(vm))) 169 if (memcmp(&vm, &t, sizeof(vm)))
166 r = -EINVAL; 170 r = -EINVAL;
167 else 171 else
@@ -229,13 +233,11 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
229 connector_type); 233 connector_type);
230 drm_connector_helper_add(connector, &omap_connector_helper_funcs); 234 drm_connector_helper_add(connector, &omap_connector_helper_funcs);
231 235
232#if 0 /* enable when dss2 supports hotplug */ 236 if (dssdev->driver->detect)
233 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_HPD)
234 connector->polled = 0;
235 else
236#endif
237 connector->polled = DRM_CONNECTOR_POLL_CONNECT | 237 connector->polled = DRM_CONNECTOR_POLL_CONNECT |
238 DRM_CONNECTOR_POLL_DISCONNECT; 238 DRM_CONNECTOR_POLL_DISCONNECT;
239 else
240 connector->polled = 0;
239 241
240 connector->interlace_allowed = 1; 242 connector->interlace_allowed = 1;
241 connector->doublescan_allowed = 0; 243 connector->doublescan_allowed = 0;
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 2fe735c269fc..dccd03726796 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -107,10 +107,12 @@ static struct omap_dss_device *omap_crtc_output[8];
107static int omap_crtc_dss_connect(enum omap_channel channel, 107static int omap_crtc_dss_connect(enum omap_channel channel,
108 struct omap_dss_device *dst) 108 struct omap_dss_device *dst)
109{ 109{
110 const struct dispc_ops *dispc_ops = dispc_get_ops();
111
110 if (omap_crtc_output[channel]) 112 if (omap_crtc_output[channel])
111 return -EINVAL; 113 return -EINVAL;
112 114
113 if ((dispc_mgr_get_supported_outputs(channel) & dst->id) == 0) 115 if ((dispc_ops->mgr_get_supported_outputs(channel) & dst->id) == 0)
114 return -EINVAL; 116 return -EINVAL;
115 117
116 omap_crtc_output[channel] = dst; 118 omap_crtc_output[channel] = dst;
@@ -134,6 +136,7 @@ static void omap_crtc_dss_start_update(enum omap_channel channel)
134static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable) 136static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
135{ 137{
136 struct drm_device *dev = crtc->dev; 138 struct drm_device *dev = crtc->dev;
139 struct omap_drm_private *priv = dev->dev_private;
137 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 140 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
138 enum omap_channel channel = omap_crtc->channel; 141 enum omap_channel channel = omap_crtc->channel;
139 struct omap_irq_wait *wait; 142 struct omap_irq_wait *wait;
@@ -144,7 +147,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
144 return; 147 return;
145 148
146 if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) { 149 if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) {
147 dispc_mgr_enable(channel, enable); 150 priv->dispc_ops->mgr_enable(channel, enable);
148 omap_crtc->enabled = enable; 151 omap_crtc->enabled = enable;
149 return; 152 return;
150 } 153 }
@@ -157,8 +160,8 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
157 omap_crtc->ignore_digit_sync_lost = true; 160 omap_crtc->ignore_digit_sync_lost = true;
158 } 161 }
159 162
160 framedone_irq = dispc_mgr_get_framedone_irq(channel); 163 framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel);
161 vsync_irq = dispc_mgr_get_vsync_irq(channel); 164 vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(channel);
162 165
163 if (enable) { 166 if (enable) {
164 wait = omap_irq_wait_init(dev, vsync_irq, 1); 167 wait = omap_irq_wait_init(dev, vsync_irq, 1);
@@ -178,7 +181,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
178 wait = omap_irq_wait_init(dev, vsync_irq, 2); 181 wait = omap_irq_wait_init(dev, vsync_irq, 2);
179 } 182 }
180 183
181 dispc_mgr_enable(channel, enable); 184 priv->dispc_ops->mgr_enable(channel, enable);
182 omap_crtc->enabled = enable; 185 omap_crtc->enabled = enable;
183 186
184 ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); 187 ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
@@ -198,17 +201,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
198static int omap_crtc_dss_enable(enum omap_channel channel) 201static int omap_crtc_dss_enable(enum omap_channel channel)
199{ 202{
200 struct omap_crtc *omap_crtc = omap_crtcs[channel]; 203 struct omap_crtc *omap_crtc = omap_crtcs[channel];
201 struct omap_overlay_manager_info info; 204 struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
202 205
203 memset(&info, 0, sizeof(info)); 206 priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm);
204 info.default_color = 0x00000000;
205 info.trans_key = 0x00000000;
206 info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
207 info.trans_enabled = false;
208
209 dispc_mgr_setup(omap_crtc->channel, &info);
210 dispc_mgr_set_timings(omap_crtc->channel,
211 &omap_crtc->vm);
212 omap_crtc_set_enabled(&omap_crtc->base, true); 207 omap_crtc_set_enabled(&omap_crtc->base, true);
213 208
214 return 0; 209 return 0;
@@ -233,8 +228,10 @@ static void omap_crtc_dss_set_lcd_config(enum omap_channel channel,
233 const struct dss_lcd_mgr_config *config) 228 const struct dss_lcd_mgr_config *config)
234{ 229{
235 struct omap_crtc *omap_crtc = omap_crtcs[channel]; 230 struct omap_crtc *omap_crtc = omap_crtcs[channel];
231 struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
232
236 DBG("%s", omap_crtc->name); 233 DBG("%s", omap_crtc->name);
237 dispc_mgr_set_lcd_config(omap_crtc->channel, config); 234 priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config);
238} 235}
239 236
240static int omap_crtc_dss_register_framedone( 237static int omap_crtc_dss_register_framedone(
@@ -282,6 +279,8 @@ void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus)
282void omap_crtc_vblank_irq(struct drm_crtc *crtc) 279void omap_crtc_vblank_irq(struct drm_crtc *crtc)
283{ 280{
284 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 281 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
282 struct drm_device *dev = omap_crtc->base.dev;
283 struct omap_drm_private *priv = dev->dev_private;
285 bool pending; 284 bool pending;
286 285
287 spin_lock(&crtc->dev->event_lock); 286 spin_lock(&crtc->dev->event_lock);
@@ -289,7 +288,7 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc)
289 * If the dispc is busy we're racing the flush operation. Try again on 288 * If the dispc is busy we're racing the flush operation. Try again on
290 * the next vblank interrupt. 289 * the next vblank interrupt.
291 */ 290 */
292 if (dispc_mgr_go_busy(omap_crtc->channel)) { 291 if (priv->dispc_ops->mgr_go_busy(omap_crtc->channel)) {
293 spin_unlock(&crtc->dev->event_lock); 292 spin_unlock(&crtc->dev->event_lock);
294 return; 293 return;
295 } 294 }
@@ -313,6 +312,22 @@ void omap_crtc_vblank_irq(struct drm_crtc *crtc)
313 DBG("%s: apply done", omap_crtc->name); 312 DBG("%s: apply done", omap_crtc->name);
314} 313}
315 314
315static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc)
316{
317 struct omap_drm_private *priv = crtc->dev->dev_private;
318 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
319 struct omap_overlay_manager_info info;
320
321 memset(&info, 0, sizeof(info));
322
323 info.default_color = 0x000000;
324 info.trans_enabled = false;
325 info.partial_alpha_enabled = false;
326 info.cpr_enable = false;
327
328 priv->dispc_ops->mgr_setup(omap_crtc->channel, &info);
329}
330
316/* ----------------------------------------------------------------------------- 331/* -----------------------------------------------------------------------------
317 * CRTC Functions 332 * CRTC Functions
318 */ 333 */
@@ -358,6 +373,11 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
358{ 373{
359 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 374 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
360 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 375 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
376 struct omap_drm_private *priv = crtc->dev->dev_private;
377 const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW |
378 DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
379 DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE;
380 unsigned int i;
361 381
362 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 382 DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
363 omap_crtc->name, mode->base.id, mode->name, 383 omap_crtc->name, mode->base.id, mode->name,
@@ -367,9 +387,38 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
367 mode->type, mode->flags); 387 mode->type, mode->flags);
368 388
369 drm_display_mode_to_videomode(mode, &omap_crtc->vm); 389 drm_display_mode_to_videomode(mode, &omap_crtc->vm);
370 omap_crtc->vm.flags |= DISPLAY_FLAGS_DE_HIGH | 390
371 DISPLAY_FLAGS_PIXDATA_POSEDGE | 391 /*
372 DISPLAY_FLAGS_SYNC_NEGEDGE; 392 * HACK: This fixes the vm flags.
393 * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags
394 * and they get lost when converting back and forth between
395 * struct drm_display_mode and struct videomode. The hack below
396 * goes and fetches the missing flags from the panel drivers.
397 *
398 * Correct solution would be to use DRM's bus-flags, but that's not
399 * easily possible before the omapdrm's panel/encoder driver model
400 * has been changed to the DRM model.
401 */
402
403 for (i = 0; i < priv->num_encoders; ++i) {
404 struct drm_encoder *encoder = priv->encoders[i];
405
406 if (encoder->crtc == crtc) {
407 struct omap_dss_device *dssdev;
408
409 dssdev = omap_encoder_get_dssdev(encoder);
410
411 if (dssdev) {
412 struct videomode vm = {0};
413
414 dssdev->driver->get_timings(dssdev, &vm);
415
416 omap_crtc->vm.flags |= vm.flags & flags_mask;
417 }
418
419 break;
420 }
421 }
373} 422}
374 423
375static int omap_crtc_atomic_check(struct drm_crtc *crtc, 424static int omap_crtc_atomic_check(struct drm_crtc *crtc,
@@ -394,6 +443,7 @@ static void omap_crtc_atomic_begin(struct drm_crtc *crtc,
394static void omap_crtc_atomic_flush(struct drm_crtc *crtc, 443static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
395 struct drm_crtc_state *old_crtc_state) 444 struct drm_crtc_state *old_crtc_state)
396{ 445{
446 struct omap_drm_private *priv = crtc->dev->dev_private;
397 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 447 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
398 int ret; 448 int ret;
399 449
@@ -407,9 +457,11 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
407 length = crtc->state->gamma_lut->length / 457 length = crtc->state->gamma_lut->length /
408 sizeof(*lut); 458 sizeof(*lut);
409 } 459 }
410 dispc_mgr_set_gamma(omap_crtc->channel, lut, length); 460 priv->dispc_ops->mgr_set_gamma(omap_crtc->channel, lut, length);
411 } 461 }
412 462
463 omap_crtc_write_crtc_properties(crtc);
464
413 /* Only flush the CRTC if it is currently enabled. */ 465 /* Only flush the CRTC if it is currently enabled. */
414 if (!omap_crtc->enabled) 466 if (!omap_crtc->enabled)
415 return; 467 return;
@@ -420,7 +472,7 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
420 WARN_ON(ret != 0); 472 WARN_ON(ret != 0);
421 473
422 spin_lock_irq(&crtc->dev->event_lock); 474 spin_lock_irq(&crtc->dev->event_lock);
423 dispc_mgr_go(omap_crtc->channel); 475 priv->dispc_ops->mgr_go(omap_crtc->channel);
424 476
425 WARN_ON(omap_crtc->pending); 477 WARN_ON(omap_crtc->pending);
426 omap_crtc->pending = true; 478 omap_crtc->pending = true;
@@ -521,6 +573,8 @@ static const char *channel_names[] = {
521 573
522void omap_crtc_pre_init(void) 574void omap_crtc_pre_init(void)
523{ 575{
576 memset(omap_crtcs, 0, sizeof(omap_crtcs));
577
524 dss_install_mgr_ops(&mgr_ops); 578 dss_install_mgr_ops(&mgr_ops);
525} 579}
526 580
@@ -531,17 +585,28 @@ void omap_crtc_pre_uninit(void)
531 585
532/* initialize crtc */ 586/* initialize crtc */
533struct drm_crtc *omap_crtc_init(struct drm_device *dev, 587struct drm_crtc *omap_crtc_init(struct drm_device *dev,
534 struct drm_plane *plane, enum omap_channel channel, int id) 588 struct drm_plane *plane, struct omap_dss_device *dssdev)
535{ 589{
590 struct omap_drm_private *priv = dev->dev_private;
536 struct drm_crtc *crtc = NULL; 591 struct drm_crtc *crtc = NULL;
537 struct omap_crtc *omap_crtc; 592 struct omap_crtc *omap_crtc;
593 enum omap_channel channel;
594 struct omap_dss_device *out;
538 int ret; 595 int ret;
539 596
597 out = omapdss_find_output_from_display(dssdev);
598 channel = out->dispc_channel;
599 omap_dss_put_device(out);
600
540 DBG("%s", channel_names[channel]); 601 DBG("%s", channel_names[channel]);
541 602
603 /* Multiple displays on same channel is not allowed */
604 if (WARN_ON(omap_crtcs[channel] != NULL))
605 return ERR_PTR(-EINVAL);
606
542 omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); 607 omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
543 if (!omap_crtc) 608 if (!omap_crtc)
544 return NULL; 609 return ERR_PTR(-ENOMEM);
545 610
546 crtc = &omap_crtc->base; 611 crtc = &omap_crtc->base;
547 612
@@ -553,8 +618,10 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
553 ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL, 618 ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
554 &omap_crtc_funcs, NULL); 619 &omap_crtc_funcs, NULL);
555 if (ret < 0) { 620 if (ret < 0) {
621 dev_err(dev->dev, "%s(): could not init crtc for: %s\n",
622 __func__, dssdev->name);
556 kfree(omap_crtc); 623 kfree(omap_crtc);
557 return NULL; 624 return ERR_PTR(ret);
558 } 625 }
559 626
560 drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs); 627 drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
@@ -566,7 +633,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
566 * extracted with dispc_mgr_gamma_size(). If it returns 0 633 * extracted with dispc_mgr_gamma_size(). If it returns 0
567 * gamma table is not supprted. 634 * gamma table is not supprted.
568 */ 635 */
569 if (dispc_mgr_gamma_size(channel)) { 636 if (priv->dispc_ops->mgr_gamma_size(channel)) {
570 uint gamma_lut_size = 256; 637 uint gamma_lut_size = 256;
571 638
572 drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size); 639 drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 79a4aad35e0f..e1f47f0b3ccf 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -34,11 +34,6 @@
34#define DRIVER_MINOR 0 34#define DRIVER_MINOR 0
35#define DRIVER_PATCHLEVEL 0 35#define DRIVER_PATCHLEVEL 0
36 36
37static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS;
38
39MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs");
40module_param(num_crtc, int, 0600);
41
42/* 37/*
43 * mode config funcs 38 * mode config funcs
44 */ 39 */
@@ -93,7 +88,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
93 struct drm_atomic_state *old_state = commit->state; 88 struct drm_atomic_state *old_state = commit->state;
94 89
95 /* Apply the atomic update. */ 90 /* Apply the atomic update. */
96 dispc_runtime_get(); 91 priv->dispc_ops->runtime_get();
97 92
98 drm_atomic_helper_commit_modeset_disables(dev, old_state); 93 drm_atomic_helper_commit_modeset_disables(dev, old_state);
99 94
@@ -117,7 +112,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
117 112
118 drm_atomic_helper_cleanup_planes(dev, old_state); 113 drm_atomic_helper_cleanup_planes(dev, old_state);
119 114
120 dispc_runtime_put(); 115 priv->dispc_ops->runtime_put();
121 116
122 drm_atomic_state_put(old_state); 117 drm_atomic_state_put(old_state);
123 118
@@ -224,20 +219,6 @@ static int get_connector_type(struct omap_dss_device *dssdev)
224 } 219 }
225} 220}
226 221
227static bool channel_used(struct drm_device *dev, enum omap_channel channel)
228{
229 struct omap_drm_private *priv = dev->dev_private;
230 int i;
231
232 for (i = 0; i < priv->num_crtcs; i++) {
233 struct drm_crtc *crtc = priv->crtcs[i];
234
235 if (omap_crtc_channel(crtc) == channel)
236 return true;
237 }
238
239 return false;
240}
241static void omap_disconnect_dssdevs(void) 222static void omap_disconnect_dssdevs(void)
242{ 223{
243 struct omap_dss_device *dssdev = NULL; 224 struct omap_dss_device *dssdev = NULL;
@@ -250,7 +231,9 @@ static int omap_connect_dssdevs(void)
250{ 231{
251 int r; 232 int r;
252 struct omap_dss_device *dssdev = NULL; 233 struct omap_dss_device *dssdev = NULL;
253 bool no_displays = true; 234
235 if (!omapdss_stack_is_ready())
236 return -EPROBE_DEFER;
254 237
255 for_each_dss_dev(dssdev) { 238 for_each_dss_dev(dssdev) {
256 r = dssdev->driver->connect(dssdev); 239 r = dssdev->driver->connect(dssdev);
@@ -260,14 +243,9 @@ static int omap_connect_dssdevs(void)
260 } else if (r) { 243 } else if (r) {
261 dev_warn(dssdev->dev, "could not connect display: %s\n", 244 dev_warn(dssdev->dev, "could not connect display: %s\n",
262 dssdev->name); 245 dssdev->name);
263 } else {
264 no_displays = false;
265 } 246 }
266 } 247 }
267 248
268 if (no_displays)
269 return -EPROBE_DEFER;
270
271 return 0; 249 return 0;
272 250
273cleanup: 251cleanup:
@@ -280,31 +258,6 @@ cleanup:
280 return r; 258 return r;
281} 259}
282 260
283static int omap_modeset_create_crtc(struct drm_device *dev, int id,
284 enum omap_channel channel,
285 u32 possible_crtcs)
286{
287 struct omap_drm_private *priv = dev->dev_private;
288 struct drm_plane *plane;
289 struct drm_crtc *crtc;
290
291 plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_PRIMARY,
292 possible_crtcs);
293 if (IS_ERR(plane))
294 return PTR_ERR(plane);
295
296 crtc = omap_crtc_init(dev, plane, channel, id);
297
298 BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
299 priv->crtcs[id] = crtc;
300 priv->num_crtcs++;
301
302 priv->planes[id] = plane;
303 priv->num_planes++;
304
305 return 0;
306}
307
308static int omap_modeset_init_properties(struct drm_device *dev) 261static int omap_modeset_init_properties(struct drm_device *dev)
309{ 262{
310 struct omap_drm_private *priv = dev->dev_private; 263 struct omap_drm_private *priv = dev->dev_private;
@@ -320,12 +273,11 @@ static int omap_modeset_init(struct drm_device *dev)
320{ 273{
321 struct omap_drm_private *priv = dev->dev_private; 274 struct omap_drm_private *priv = dev->dev_private;
322 struct omap_dss_device *dssdev = NULL; 275 struct omap_dss_device *dssdev = NULL;
323 int num_ovls = dss_feat_get_num_ovls(); 276 int num_ovls = priv->dispc_ops->get_num_ovls();
324 int num_mgrs = dss_feat_get_num_mgrs(); 277 int num_mgrs = priv->dispc_ops->get_num_mgrs();
325 int num_crtcs; 278 int num_crtcs, crtc_idx, plane_idx;
326 int i, id = 0;
327 int ret; 279 int ret;
328 u32 possible_crtcs; 280 u32 plane_crtc_mask;
329 281
330 drm_mode_config_init(dev); 282 drm_mode_config_init(dev);
331 283
@@ -334,162 +286,97 @@ static int omap_modeset_init(struct drm_device *dev)
334 return ret; 286 return ret;
335 287
336 /* 288 /*
337 * We usually don't want to create a CRTC for each manager, at least 289 * This function creates exactly one connector, encoder, crtc,
338 * not until we have a way to expose private planes to userspace. 290 * and primary plane per each connected dss-device. Each
339 * Otherwise there would not be enough video pipes left for drm planes. 291 * connector->encoder->crtc chain is expected to be separate
340 * We use the num_crtc argument to limit the number of crtcs we create. 292 * and each crtc is connect to a single dss-channel. If the
293 * configuration does not match the expectations or exceeds
294 * the available resources, the configuration is rejected.
341 */ 295 */
342 num_crtcs = min3(num_crtc, num_mgrs, num_ovls); 296 num_crtcs = 0;
343 possible_crtcs = (1 << num_crtcs) - 1; 297 for_each_dss_dev(dssdev)
298 if (omapdss_device_is_connected(dssdev))
299 num_crtcs++;
300
301 if (num_crtcs > num_mgrs || num_crtcs > num_ovls ||
302 num_crtcs > ARRAY_SIZE(priv->crtcs) ||
303 num_crtcs > ARRAY_SIZE(priv->planes) ||
304 num_crtcs > ARRAY_SIZE(priv->encoders) ||
305 num_crtcs > ARRAY_SIZE(priv->connectors)) {
306 dev_err(dev->dev, "%s(): Too many connected displays\n",
307 __func__);
308 return -EINVAL;
309 }
310
311 /* All planes can be put to any CRTC */
312 plane_crtc_mask = (1 << num_crtcs) - 1;
344 313
345 dssdev = NULL; 314 dssdev = NULL;
346 315
316 crtc_idx = 0;
317 plane_idx = 0;
347 for_each_dss_dev(dssdev) { 318 for_each_dss_dev(dssdev) {
348 struct drm_connector *connector; 319 struct drm_connector *connector;
349 struct drm_encoder *encoder; 320 struct drm_encoder *encoder;
350 enum omap_channel channel; 321 struct drm_plane *plane;
351 struct omap_dss_device *out; 322 struct drm_crtc *crtc;
352 323
353 if (!omapdss_device_is_connected(dssdev)) 324 if (!omapdss_device_is_connected(dssdev))
354 continue; 325 continue;
355 326
356 encoder = omap_encoder_init(dev, dssdev); 327 encoder = omap_encoder_init(dev, dssdev);
357 328 if (!encoder)
358 if (!encoder) {
359 dev_err(dev->dev, "could not create encoder: %s\n",
360 dssdev->name);
361 return -ENOMEM; 329 return -ENOMEM;
362 }
363 330
364 connector = omap_connector_init(dev, 331 connector = omap_connector_init(dev,
365 get_connector_type(dssdev), dssdev, encoder); 332 get_connector_type(dssdev), dssdev, encoder);
366 333 if (!connector)
367 if (!connector) {
368 dev_err(dev->dev, "could not create connector: %s\n",
369 dssdev->name);
370 return -ENOMEM; 334 return -ENOMEM;
371 }
372 335
373 BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); 336 plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_PRIMARY,
374 BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); 337 plane_crtc_mask);
338 if (IS_ERR(plane))
339 return PTR_ERR(plane);
375 340
376 priv->encoders[priv->num_encoders++] = encoder; 341 crtc = omap_crtc_init(dev, plane, dssdev);
377 priv->connectors[priv->num_connectors++] = connector; 342 if (IS_ERR(crtc))
343 return PTR_ERR(crtc);
378 344
379 drm_mode_connector_attach_encoder(connector, encoder); 345 drm_mode_connector_attach_encoder(connector, encoder);
346 encoder->possible_crtcs = (1 << crtc_idx);
380 347
381 /* 348 priv->crtcs[priv->num_crtcs++] = crtc;
382 * if we have reached the limit of the crtcs we are allowed to 349 priv->planes[priv->num_planes++] = plane;
383 * create, let's not try to look for a crtc for this 350 priv->encoders[priv->num_encoders++] = encoder;
384 * panel/encoder and onwards, we will, of course, populate the 351 priv->connectors[priv->num_connectors++] = connector;
385 * the possible_crtcs field for all the encoders with the final
386 * set of crtcs we create
387 */
388 if (id == num_crtcs)
389 continue;
390
391 /*
392 * get the recommended DISPC channel for this encoder. For now,
393 * we only try to get create a crtc out of the recommended, the
394 * other possible channels to which the encoder can connect are
395 * not considered.
396 */
397
398 out = omapdss_find_output_from_display(dssdev);
399 channel = out->dispc_channel;
400 omap_dss_put_device(out);
401
402 /*
403 * if this channel hasn't already been taken by a previously
404 * allocated crtc, we create a new crtc for it
405 */
406 if (!channel_used(dev, channel)) {
407 ret = omap_modeset_create_crtc(dev, id, channel,
408 possible_crtcs);
409 if (ret < 0) {
410 dev_err(dev->dev,
411 "could not create CRTC (channel %u)\n",
412 channel);
413 return ret;
414 }
415
416 id++;
417 }
418 }
419
420 /*
421 * we have allocated crtcs according to the need of the panels/encoders,
422 * adding more crtcs here if needed
423 */
424 for (; id < num_crtcs; id++) {
425
426 /* find a free manager for this crtc */
427 for (i = 0; i < num_mgrs; i++) {
428 if (!channel_used(dev, i))
429 break;
430 }
431
432 if (i == num_mgrs) {
433 /* this shouldn't really happen */
434 dev_err(dev->dev, "no managers left for crtc\n");
435 return -ENOMEM;
436 }
437 352
438 ret = omap_modeset_create_crtc(dev, id, i, 353 plane_idx++;
439 possible_crtcs); 354 crtc_idx++;
440 if (ret < 0) {
441 dev_err(dev->dev,
442 "could not create CRTC (channel %u)\n", i);
443 return ret;
444 }
445 } 355 }
446 356
447 /* 357 /*
448 * Create normal planes for the remaining overlays: 358 * Create normal planes for the remaining overlays:
449 */ 359 */
450 for (; id < num_ovls; id++) { 360 for (; plane_idx < num_ovls; plane_idx++) {
451 struct drm_plane *plane; 361 struct drm_plane *plane;
452 362
453 plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_OVERLAY, 363 if (WARN_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)))
454 possible_crtcs); 364 return -EINVAL;
365
366 plane = omap_plane_init(dev, plane_idx, DRM_PLANE_TYPE_OVERLAY,
367 plane_crtc_mask);
455 if (IS_ERR(plane)) 368 if (IS_ERR(plane))
456 return PTR_ERR(plane); 369 return PTR_ERR(plane);
457 370
458 BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
459 priv->planes[priv->num_planes++] = plane; 371 priv->planes[priv->num_planes++] = plane;
460 } 372 }
461 373
462 for (i = 0; i < priv->num_encoders; i++) {
463 struct drm_encoder *encoder = priv->encoders[i];
464 struct omap_dss_device *dssdev =
465 omap_encoder_get_dssdev(encoder);
466 struct omap_dss_device *output;
467
468 output = omapdss_find_output_from_display(dssdev);
469
470 /* figure out which crtc's we can connect the encoder to: */
471 encoder->possible_crtcs = 0;
472 for (id = 0; id < priv->num_crtcs; id++) {
473 struct drm_crtc *crtc = priv->crtcs[id];
474 enum omap_channel crtc_channel;
475
476 crtc_channel = omap_crtc_channel(crtc);
477
478 if (output->dispc_channel == crtc_channel) {
479 encoder->possible_crtcs |= (1 << id);
480 break;
481 }
482 }
483
484 omap_dss_put_device(output);
485 }
486
487 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", 374 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
488 priv->num_planes, priv->num_crtcs, priv->num_encoders, 375 priv->num_planes, priv->num_crtcs, priv->num_encoders,
489 priv->num_connectors); 376 priv->num_connectors);
490 377
491 dev->mode_config.min_width = 32; 378 dev->mode_config.min_width = 8;
492 dev->mode_config.min_height = 32; 379 dev->mode_config.min_height = 2;
493 380
494 /* note: eventually will need some cpu_is_omapXYZ() type stuff here 381 /* note: eventually will need some cpu_is_omapXYZ() type stuff here
495 * to fill in these limits properly on different OMAP generations.. 382 * to fill in these limits properly on different OMAP generations..
@@ -629,12 +516,18 @@ static int ioctl_gem_info(struct drm_device *dev, void *data,
629} 516}
630 517
631static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { 518static const struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
632 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_AUTH), 519 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param,
633 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 520 DRM_AUTH | DRM_RENDER_ALLOW),
634 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_AUTH), 521 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param,
635 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, DRM_AUTH), 522 DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
636 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, DRM_AUTH), 523 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new,
637 DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info, DRM_AUTH), 524 DRM_AUTH | DRM_RENDER_ALLOW),
525 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep,
526 DRM_AUTH | DRM_RENDER_ALLOW),
527 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini,
528 DRM_AUTH | DRM_RENDER_ALLOW),
529 DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info,
530 DRM_AUTH | DRM_RENDER_ALLOW),
638}; 531};
639 532
640/* 533/*
@@ -724,7 +617,7 @@ static const struct file_operations omapdriver_fops = {
724 617
725static struct drm_driver omap_drm_driver = { 618static struct drm_driver omap_drm_driver = {
726 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | 619 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
727 DRIVER_ATOMIC, 620 DRIVER_ATOMIC | DRIVER_RENDER,
728 .open = dev_open, 621 .open = dev_open,
729 .lastclose = dev_lastclose, 622 .lastclose = dev_lastclose,
730#ifdef CONFIG_DEBUG_FS 623#ifdef CONFIG_DEBUG_FS
@@ -776,6 +669,8 @@ static int pdev_probe(struct platform_device *pdev)
776 goto err_disconnect_dssdevs; 669 goto err_disconnect_dssdevs;
777 } 670 }
778 671
672 priv->dispc_ops = dispc_get_ops();
673
779 priv->omaprev = pdata->omaprev; 674 priv->omaprev = pdata->omaprev;
780 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 675 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
781 676
@@ -860,6 +755,8 @@ static int pdev_remove(struct platform_device *pdev)
860 if (priv->fbdev) 755 if (priv->fbdev)
861 omap_fbdev_free(ddev); 756 omap_fbdev_free(ddev);
862 757
758 drm_atomic_helper_shutdown(ddev);
759
863 drm_mode_config_cleanup(ddev); 760 drm_mode_config_cleanup(ddev);
864 761
865 omap_drm_irq_uninstall(ddev); 762 omap_drm_irq_uninstall(ddev);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 9098ea138269..7a4c57eb6536 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -59,6 +59,8 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
59struct omap_drm_private { 59struct omap_drm_private {
60 uint32_t omaprev; 60 uint32_t omaprev;
61 61
62 const struct dispc_ops *dispc_ops;
63
62 unsigned int num_crtcs; 64 unsigned int num_crtcs;
63 struct drm_crtc *crtcs[8]; 65 struct drm_crtc *crtcs[8];
64 66
@@ -135,13 +137,13 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
135void omap_crtc_pre_init(void); 137void omap_crtc_pre_init(void);
136void omap_crtc_pre_uninit(void); 138void omap_crtc_pre_uninit(void);
137struct drm_crtc *omap_crtc_init(struct drm_device *dev, 139struct drm_crtc *omap_crtc_init(struct drm_device *dev,
138 struct drm_plane *plane, enum omap_channel channel, int id); 140 struct drm_plane *plane, struct omap_dss_device *dssdev);
139int omap_crtc_wait_pending(struct drm_crtc *crtc); 141int omap_crtc_wait_pending(struct drm_crtc *crtc);
140void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus); 142void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus);
141void omap_crtc_vblank_irq(struct drm_crtc *crtc); 143void omap_crtc_vblank_irq(struct drm_crtc *crtc);
142 144
143struct drm_plane *omap_plane_init(struct drm_device *dev, 145struct drm_plane *omap_plane_init(struct drm_device *dev,
144 int id, enum drm_plane_type type, 146 int idx, enum drm_plane_type type,
145 u32 possible_crtcs); 147 u32 possible_crtcs);
146void omap_plane_install_properties(struct drm_plane *plane, 148void omap_plane_install_properties(struct drm_plane *plane,
147 struct drm_mode_object *obj); 149 struct drm_mode_object *obj);
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index 59f21add6f19..115104cdcc59 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -40,8 +40,8 @@ static void omap_irq_update(struct drm_device *dev)
40 40
41 DBG("irqmask=%08x", irqmask); 41 DBG("irqmask=%08x", irqmask);
42 42
43 dispc_write_irqenable(irqmask); 43 priv->dispc_ops->write_irqenable(irqmask);
44 dispc_read_irqenable(); /* flush posted write */ 44 priv->dispc_ops->read_irqenable(); /* flush posted write */
45} 45}
46 46
47static void omap_irq_wait_handler(struct omap_irq_wait *wait) 47static void omap_irq_wait_handler(struct omap_irq_wait *wait)
@@ -111,7 +111,7 @@ int omap_irq_enable_vblank(struct drm_crtc *crtc)
111 DBG("dev=%p, crtc=%u", dev, channel); 111 DBG("dev=%p, crtc=%u", dev, channel);
112 112
113 spin_lock_irqsave(&priv->wait_lock, flags); 113 spin_lock_irqsave(&priv->wait_lock, flags);
114 priv->irq_mask |= dispc_mgr_get_vsync_irq(channel); 114 priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(channel);
115 omap_irq_update(dev); 115 omap_irq_update(dev);
116 spin_unlock_irqrestore(&priv->wait_lock, flags); 116 spin_unlock_irqrestore(&priv->wait_lock, flags);
117 117
@@ -137,7 +137,7 @@ void omap_irq_disable_vblank(struct drm_crtc *crtc)
137 DBG("dev=%p, crtc=%u", dev, channel); 137 DBG("dev=%p, crtc=%u", dev, channel);
138 138
139 spin_lock_irqsave(&priv->wait_lock, flags); 139 spin_lock_irqsave(&priv->wait_lock, flags);
140 priv->irq_mask &= ~dispc_mgr_get_vsync_irq(channel); 140 priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(channel);
141 omap_irq_update(dev); 141 omap_irq_update(dev);
142 spin_unlock_irqrestore(&priv->wait_lock, flags); 142 spin_unlock_irqrestore(&priv->wait_lock, flags);
143} 143}
@@ -200,9 +200,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
200 unsigned int id; 200 unsigned int id;
201 u32 irqstatus; 201 u32 irqstatus;
202 202
203 irqstatus = dispc_read_irqstatus(); 203 irqstatus = priv->dispc_ops->read_irqstatus();
204 dispc_clear_irqstatus(irqstatus); 204 priv->dispc_ops->clear_irqstatus(irqstatus);
205 dispc_read_irqstatus(); /* flush posted write */ 205 priv->dispc_ops->read_irqstatus(); /* flush posted write */
206 206
207 VERB("irqs: %08x", irqstatus); 207 VERB("irqs: %08x", irqstatus);
208 208
@@ -210,12 +210,12 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
210 struct drm_crtc *crtc = priv->crtcs[id]; 210 struct drm_crtc *crtc = priv->crtcs[id];
211 enum omap_channel channel = omap_crtc_channel(crtc); 211 enum omap_channel channel = omap_crtc_channel(crtc);
212 212
213 if (irqstatus & dispc_mgr_get_vsync_irq(channel)) { 213 if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(channel)) {
214 drm_handle_vblank(dev, id); 214 drm_handle_vblank(dev, id);
215 omap_crtc_vblank_irq(crtc); 215 omap_crtc_vblank_irq(crtc);
216 } 216 }
217 217
218 if (irqstatus & dispc_mgr_get_sync_lost_irq(channel)) 218 if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel))
219 omap_crtc_error_irq(crtc, irqstatus); 219 omap_crtc_error_irq(crtc, irqstatus);
220 } 220 }
221 221
@@ -249,7 +249,7 @@ static const u32 omap_underflow_irqs[] = {
249int omap_drm_irq_install(struct drm_device *dev) 249int omap_drm_irq_install(struct drm_device *dev)
250{ 250{
251 struct omap_drm_private *priv = dev->dev_private; 251 struct omap_drm_private *priv = dev->dev_private;
252 unsigned int num_mgrs = dss_feat_get_num_mgrs(); 252 unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs();
253 unsigned int max_planes; 253 unsigned int max_planes;
254 unsigned int i; 254 unsigned int i;
255 int ret; 255 int ret;
@@ -267,13 +267,13 @@ int omap_drm_irq_install(struct drm_device *dev)
267 } 267 }
268 268
269 for (i = 0; i < num_mgrs; ++i) 269 for (i = 0; i < num_mgrs; ++i)
270 priv->irq_mask |= dispc_mgr_get_sync_lost_irq(i); 270 priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(i);
271 271
272 dispc_runtime_get(); 272 priv->dispc_ops->runtime_get();
273 dispc_clear_irqstatus(0xffffffff); 273 priv->dispc_ops->clear_irqstatus(0xffffffff);
274 dispc_runtime_put(); 274 priv->dispc_ops->runtime_put();
275 275
276 ret = dispc_request_irq(omap_irq_handler, dev); 276 ret = priv->dispc_ops->request_irq(omap_irq_handler, dev);
277 if (ret < 0) 277 if (ret < 0)
278 return ret; 278 return ret;
279 279
@@ -284,25 +284,12 @@ int omap_drm_irq_install(struct drm_device *dev)
284 284
285void omap_drm_irq_uninstall(struct drm_device *dev) 285void omap_drm_irq_uninstall(struct drm_device *dev)
286{ 286{
287 unsigned long irqflags; 287 struct omap_drm_private *priv = dev->dev_private;
288 int i;
289 288
290 if (!dev->irq_enabled) 289 if (!dev->irq_enabled)
291 return; 290 return;
292 291
293 dev->irq_enabled = false; 292 dev->irq_enabled = false;
294 293
295 /* Wake up any waiters so they don't hang. */ 294 priv->dispc_ops->free_irq(dev);
296 if (dev->num_crtcs) {
297 spin_lock_irqsave(&dev->vbl_lock, irqflags);
298 for (i = 0; i < dev->num_crtcs; i++) {
299 wake_up(&dev->vblank[i].queue);
300 dev->vblank[i].enabled = false;
301 dev->vblank[i].last =
302 dev->driver->get_vblank_counter(dev, i);
303 }
304 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
305 }
306
307 dispc_free_irq(dev);
308} 295}
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 386d90af70f7..9168154d749e 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -24,12 +24,6 @@
24#include "omap_dmm_tiler.h" 24#include "omap_dmm_tiler.h"
25#include "omap_drv.h" 25#include "omap_drv.h"
26 26
27/* some hackery because omapdss has an 'enum omap_plane' (which would be
28 * better named omap_plane_id).. and compiler seems unhappy about having
29 * both a 'struct omap_plane' and 'enum omap_plane'
30 */
31#define omap_plane _omap_plane
32
33/* 27/*
34 * plane funcs 28 * plane funcs
35 */ 29 */
@@ -38,7 +32,7 @@
38 32
39struct omap_plane { 33struct omap_plane {
40 struct drm_plane base; 34 struct drm_plane base;
41 int id; /* TODO rename omap_plane -> omap_plane_id in omapdss so I can use the enum */ 35 enum omap_plane_id id;
42 const char *name; 36 const char *name;
43 37
44 uint32_t nformats; 38 uint32_t nformats;
@@ -76,6 +70,7 @@ static void omap_plane_cleanup_fb(struct drm_plane *plane,
76static void omap_plane_atomic_update(struct drm_plane *plane, 70static void omap_plane_atomic_update(struct drm_plane *plane,
77 struct drm_plane_state *old_state) 71 struct drm_plane_state *old_state)
78{ 72{
73 struct omap_drm_private *priv = plane->dev->dev_private;
79 struct omap_plane *omap_plane = to_omap_plane(plane); 74 struct omap_plane *omap_plane = to_omap_plane(plane);
80 struct drm_plane_state *state = plane->state; 75 struct drm_plane_state *state = plane->state;
81 struct omap_plane_state *omap_state = to_omap_plane_state(state); 76 struct omap_plane_state *omap_state = to_omap_plane_state(state);
@@ -123,25 +118,26 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
123 DBG("%d,%d %pad %pad", info.pos_x, info.pos_y, 118 DBG("%d,%d %pad %pad", info.pos_x, info.pos_y,
124 &info.paddr, &info.p_uv_addr); 119 &info.paddr, &info.p_uv_addr);
125 120
126 dispc_ovl_set_channel_out(omap_plane->id, 121 priv->dispc_ops->ovl_set_channel_out(omap_plane->id,
127 omap_crtc_channel(state->crtc)); 122 omap_crtc_channel(state->crtc));
128 123
129 /* and finally, update omapdss: */ 124 /* and finally, update omapdss: */
130 ret = dispc_ovl_setup(omap_plane->id, &info, false, 125 ret = priv->dispc_ops->ovl_setup(omap_plane->id, &info,
131 omap_crtc_timings(state->crtc), false); 126 omap_crtc_timings(state->crtc), false);
132 if (ret) { 127 if (ret) {
133 dev_err(plane->dev->dev, "Failed to setup plane %s\n", 128 dev_err(plane->dev->dev, "Failed to setup plane %s\n",
134 omap_plane->name); 129 omap_plane->name);
135 dispc_ovl_enable(omap_plane->id, false); 130 priv->dispc_ops->ovl_enable(omap_plane->id, false);
136 return; 131 return;
137 } 132 }
138 133
139 dispc_ovl_enable(omap_plane->id, true); 134 priv->dispc_ops->ovl_enable(omap_plane->id, true);
140} 135}
141 136
142static void omap_plane_atomic_disable(struct drm_plane *plane, 137static void omap_plane_atomic_disable(struct drm_plane *plane,
143 struct drm_plane_state *old_state) 138 struct drm_plane_state *old_state)
144{ 139{
140 struct omap_drm_private *priv = plane->dev->dev_private;
145 struct omap_plane_state *omap_state = to_omap_plane_state(plane->state); 141 struct omap_plane_state *omap_state = to_omap_plane_state(plane->state);
146 struct omap_plane *omap_plane = to_omap_plane(plane); 142 struct omap_plane *omap_plane = to_omap_plane(plane);
147 143
@@ -149,7 +145,7 @@ static void omap_plane_atomic_disable(struct drm_plane *plane,
149 omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY 145 omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY
150 ? 0 : omap_plane->id; 146 ? 0 : omap_plane->id;
151 147
152 dispc_ovl_enable(omap_plane->id, false); 148 priv->dispc_ops->ovl_enable(omap_plane->id, false);
153} 149}
154 150
155static int omap_plane_atomic_check(struct drm_plane *plane, 151static int omap_plane_atomic_check(struct drm_plane *plane,
@@ -328,23 +324,37 @@ static const struct drm_plane_funcs omap_plane_funcs = {
328 .atomic_get_property = omap_plane_atomic_get_property, 324 .atomic_get_property = omap_plane_atomic_get_property,
329}; 325};
330 326
331static const char *plane_names[] = { 327static const char *plane_id_to_name[] = {
332 [OMAP_DSS_GFX] = "gfx", 328 [OMAP_DSS_GFX] = "gfx",
333 [OMAP_DSS_VIDEO1] = "vid1", 329 [OMAP_DSS_VIDEO1] = "vid1",
334 [OMAP_DSS_VIDEO2] = "vid2", 330 [OMAP_DSS_VIDEO2] = "vid2",
335 [OMAP_DSS_VIDEO3] = "vid3", 331 [OMAP_DSS_VIDEO3] = "vid3",
336}; 332};
337 333
334static const enum omap_plane_id plane_idx_to_id[] = {
335 OMAP_DSS_GFX,
336 OMAP_DSS_VIDEO1,
337 OMAP_DSS_VIDEO2,
338 OMAP_DSS_VIDEO3,
339};
340
338/* initialize plane */ 341/* initialize plane */
339struct drm_plane *omap_plane_init(struct drm_device *dev, 342struct drm_plane *omap_plane_init(struct drm_device *dev,
340 int id, enum drm_plane_type type, 343 int idx, enum drm_plane_type type,
341 u32 possible_crtcs) 344 u32 possible_crtcs)
342{ 345{
346 struct omap_drm_private *priv = dev->dev_private;
343 struct drm_plane *plane; 347 struct drm_plane *plane;
344 struct omap_plane *omap_plane; 348 struct omap_plane *omap_plane;
349 enum omap_plane_id id;
345 int ret; 350 int ret;
346 351
347 DBG("%s: type=%d", plane_names[id], type); 352 if (WARN_ON(idx >= ARRAY_SIZE(plane_idx_to_id)))
353 return ERR_PTR(-EINVAL);
354
355 id = plane_idx_to_id[idx];
356
357 DBG("%s: type=%d", plane_id_to_name[id], type);
348 358
349 omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); 359 omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
350 if (!omap_plane) 360 if (!omap_plane)
@@ -352,9 +362,9 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
352 362
353 omap_plane->nformats = omap_framebuffer_get_formats( 363 omap_plane->nformats = omap_framebuffer_get_formats(
354 omap_plane->formats, ARRAY_SIZE(omap_plane->formats), 364 omap_plane->formats, ARRAY_SIZE(omap_plane->formats),
355 dss_feat_get_supported_color_modes(id)); 365 priv->dispc_ops->ovl_get_color_modes(id));
356 omap_plane->id = id; 366 omap_plane->id = id;
357 omap_plane->name = plane_names[id]; 367 omap_plane->name = plane_id_to_name[id];
358 368
359 plane = &omap_plane->base; 369 plane = &omap_plane->base;
360 370
@@ -371,6 +381,9 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
371 return plane; 381 return plane;
372 382
373error: 383error:
384 dev_err(dev->dev, "%s(): could not create plane: %s\n",
385 __func__, plane_id_to_name[id]);
386
374 kfree(omap_plane); 387 kfree(omap_plane);
375 return NULL; 388 return NULL;
376} 389}