aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-09-15 09:08:05 -0400
committerJiri Kosina <jkosina@suse.cz>2011-09-15 09:08:18 -0400
commite060c38434b2caa78efe7cedaff4191040b65a15 (patch)
tree407361230bf6733f63d8e788e4b5e6566ee04818 /drivers/video
parent10e4ac572eeffe5317019bd7330b6058a400dfc2 (diff)
parentcc39c6a9bbdebfcf1a7dee64d83bf302bc38d941 (diff)
Merge branch 'master' into for-next
Fast-forward merge with Linus to be able to merge patches based on more recent version of the tree.
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/backlight/Kconfig7
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/aat2870_bl.c246
-rw-r--r--drivers/video/backlight/adp8870_bl.c2
-rw-r--r--drivers/video/backlight/backlight.c2
-rw-r--r--drivers/video/backlight/ep93xx_bl.c2
-rw-r--r--drivers/video/backlight/pwm_bl.c9
-rw-r--r--drivers/video/omap2/displays/panel-taal.c55
-rw-r--r--drivers/video/omap2/dss/Kconfig12
-rw-r--r--drivers/video/omap2/dss/core.c21
-rw-r--r--drivers/video/omap2/dss/dispc.c562
-rw-r--r--drivers/video/omap2/dss/display.c57
-rw-r--r--drivers/video/omap2/dss/dpi.c73
-rw-r--r--drivers/video/omap2/dss/dsi.c296
-rw-r--r--drivers/video/omap2/dss/dss.c583
-rw-r--r--drivers/video/omap2/dss/dss.h54
-rw-r--r--drivers/video/omap2/dss/dss_features.c36
-rw-r--r--drivers/video/omap2/dss/dss_features.h7
-rw-r--r--drivers/video/omap2/dss/hdmi.c162
-rw-r--r--drivers/video/omap2/dss/manager.c351
-rw-r--r--drivers/video/omap2/dss/overlay.c27
-rw-r--r--drivers/video/omap2/dss/rfbi.c114
-rw-r--r--drivers/video/omap2/dss/sdi.c40
-rw-r--r--drivers/video/omap2/dss/venc.c183
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c72
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c166
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c34
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h37
-rw-r--r--drivers/video/savage/savagefb.h2
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c2
-rw-r--r--drivers/video/vermilion/vermilion.h2
31 files changed, 1895 insertions, 1322 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 1e54b8b7f698..278aeaa92505 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -335,6 +335,13 @@ config BACKLIGHT_PCF50633
335 If you have a backlight driven by a NXP PCF50633 MFD, say Y here to 335 If you have a backlight driven by a NXP PCF50633 MFD, say Y here to
336 enable its driver. 336 enable its driver.
337 337
338config BACKLIGHT_AAT2870
339 tristate "AnalogicTech AAT2870 Backlight"
340 depends on BACKLIGHT_CLASS_DEVICE && MFD_AAT2870_CORE
341 help
342 If you have a AnalogicTech AAT2870 say Y to enable the
343 backlight driver.
344
338endif # BACKLIGHT_CLASS_DEVICE 345endif # BACKLIGHT_CLASS_DEVICE
339 346
340endif # BACKLIGHT_LCD_SUPPORT 347endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bf1dd92b7527..fdd1fc4b2770 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -38,4 +38,5 @@ obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
38obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o 38obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
39obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o 39obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
40obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o 40obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
41obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
41 42
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
new file mode 100644
index 000000000000..331f1ef1dad5
--- /dev/null
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -0,0 +1,246 @@
1/*
2 * linux/drivers/video/backlight/aat2870_bl.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 * Author: Jin Park <jinyoungp@nvidia.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/platform_device.h>
26#include <linux/mutex.h>
27#include <linux/delay.h>
28#include <linux/fb.h>
29#include <linux/backlight.h>
30#include <linux/mfd/aat2870.h>
31
32struct aat2870_bl_driver_data {
33 struct platform_device *pdev;
34 struct backlight_device *bd;
35
36 int channels;
37 int max_current;
38 int brightness; /* current brightness */
39};
40
41static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl,
42 int brightness)
43{
44 struct backlight_device *bd = aat2870_bl->bd;
45 int val;
46
47 val = brightness * (aat2870_bl->max_current - 1);
48 val /= bd->props.max_brightness;
49
50 return val;
51}
52
53static inline int aat2870_bl_enable(struct aat2870_bl_driver_data *aat2870_bl)
54{
55 struct aat2870_data *aat2870
56 = dev_get_drvdata(aat2870_bl->pdev->dev.parent);
57
58 return aat2870->write(aat2870, AAT2870_BL_CH_EN,
59 (u8)aat2870_bl->channels);
60}
61
62static inline int aat2870_bl_disable(struct aat2870_bl_driver_data *aat2870_bl)
63{
64 struct aat2870_data *aat2870
65 = dev_get_drvdata(aat2870_bl->pdev->dev.parent);
66
67 return aat2870->write(aat2870, AAT2870_BL_CH_EN, 0x0);
68}
69
70static int aat2870_bl_get_brightness(struct backlight_device *bd)
71{
72 return bd->props.brightness;
73}
74
75static int aat2870_bl_update_status(struct backlight_device *bd)
76{
77 struct aat2870_bl_driver_data *aat2870_bl = dev_get_drvdata(&bd->dev);
78 struct aat2870_data *aat2870 =
79 dev_get_drvdata(aat2870_bl->pdev->dev.parent);
80 int brightness = bd->props.brightness;
81 int ret;
82
83 if ((brightness < 0) || (bd->props.max_brightness < brightness)) {
84 dev_err(&bd->dev, "invalid brightness, %d\n", brightness);
85 return -EINVAL;
86 }
87
88 dev_dbg(&bd->dev, "brightness=%d, power=%d, state=%d\n",
89 bd->props.brightness, bd->props.power, bd->props.state);
90
91 if ((bd->props.power != FB_BLANK_UNBLANK) ||
92 (bd->props.state & BL_CORE_FBBLANK) ||
93 (bd->props.state & BL_CORE_SUSPENDED))
94 brightness = 0;
95
96 ret = aat2870->write(aat2870, AAT2870_BLM,
97 (u8)aat2870_brightness(aat2870_bl, brightness));
98 if (ret < 0)
99 return ret;
100
101 if (brightness == 0) {
102 ret = aat2870_bl_disable(aat2870_bl);
103 if (ret < 0)
104 return ret;
105 } else if (aat2870_bl->brightness == 0) {
106 ret = aat2870_bl_enable(aat2870_bl);
107 if (ret < 0)
108 return ret;
109 }
110
111 aat2870_bl->brightness = brightness;
112
113 return 0;
114}
115
116static int aat2870_bl_check_fb(struct backlight_device *bd, struct fb_info *fi)
117{
118 return 1;
119}
120
121static const struct backlight_ops aat2870_bl_ops = {
122 .options = BL_CORE_SUSPENDRESUME,
123 .get_brightness = aat2870_bl_get_brightness,
124 .update_status = aat2870_bl_update_status,
125 .check_fb = aat2870_bl_check_fb,
126};
127
128static int aat2870_bl_probe(struct platform_device *pdev)
129{
130 struct aat2870_bl_platform_data *pdata = pdev->dev.platform_data;
131 struct aat2870_bl_driver_data *aat2870_bl;
132 struct backlight_device *bd;
133 struct backlight_properties props;
134 int ret = 0;
135
136 if (!pdata) {
137 dev_err(&pdev->dev, "No platform data\n");
138 ret = -ENXIO;
139 goto out;
140 }
141
142 if (pdev->id != AAT2870_ID_BL) {
143 dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
144 ret = -EINVAL;
145 goto out;
146 }
147
148 aat2870_bl = kzalloc(sizeof(struct aat2870_bl_driver_data), GFP_KERNEL);
149 if (!aat2870_bl) {
150 dev_err(&pdev->dev,
151 "Failed to allocate memory for aat2870 backlight\n");
152 ret = -ENOMEM;
153 goto out;
154 }
155
156 memset(&props, 0, sizeof(struct backlight_properties));
157
158 props.type = BACKLIGHT_RAW;
159 bd = backlight_device_register("aat2870-backlight", &pdev->dev,
160 aat2870_bl, &aat2870_bl_ops, &props);
161 if (IS_ERR(bd)) {
162 dev_err(&pdev->dev,
163 "Failed allocate memory for backlight device\n");
164 ret = PTR_ERR(bd);
165 goto out_kfree;
166 }
167
168 aat2870_bl->pdev = pdev;
169 platform_set_drvdata(pdev, aat2870_bl);
170
171 aat2870_bl->bd = bd;
172
173 if (pdata->channels > 0)
174 aat2870_bl->channels = pdata->channels;
175 else
176 aat2870_bl->channels = AAT2870_BL_CH_ALL;
177
178 if (pdata->max_current > 0)
179 aat2870_bl->max_current = pdata->max_current;
180 else
181 aat2870_bl->max_current = AAT2870_CURRENT_27_9;
182
183 if (pdata->max_brightness > 0)
184 bd->props.max_brightness = pdata->max_brightness;
185 else
186 bd->props.max_brightness = 255;
187
188 aat2870_bl->brightness = 0;
189 bd->props.power = FB_BLANK_UNBLANK;
190 bd->props.brightness = bd->props.max_brightness;
191
192 ret = aat2870_bl_update_status(bd);
193 if (ret < 0) {
194 dev_err(&pdev->dev, "Failed to initialize\n");
195 goto out_bl_dev_unregister;
196 }
197
198 return 0;
199
200out_bl_dev_unregister:
201 backlight_device_unregister(bd);
202out_kfree:
203 kfree(aat2870_bl);
204out:
205 return ret;
206}
207
208static int aat2870_bl_remove(struct platform_device *pdev)
209{
210 struct aat2870_bl_driver_data *aat2870_bl = platform_get_drvdata(pdev);
211 struct backlight_device *bd = aat2870_bl->bd;
212
213 bd->props.power = FB_BLANK_POWERDOWN;
214 bd->props.brightness = 0;
215 backlight_update_status(bd);
216
217 backlight_device_unregister(bd);
218 kfree(aat2870_bl);
219
220 return 0;
221}
222
223static struct platform_driver aat2870_bl_driver = {
224 .driver = {
225 .name = "aat2870-backlight",
226 .owner = THIS_MODULE,
227 },
228 .probe = aat2870_bl_probe,
229 .remove = aat2870_bl_remove,
230};
231
232static int __init aat2870_bl_init(void)
233{
234 return platform_driver_register(&aat2870_bl_driver);
235}
236subsys_initcall(aat2870_bl_init);
237
238static void __exit aat2870_bl_exit(void)
239{
240 platform_driver_unregister(&aat2870_bl_driver);
241}
242module_exit(aat2870_bl_exit);
243
244MODULE_DESCRIPTION("AnalogicTech AAT2870 Backlight");
245MODULE_LICENSE("GPL");
246MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 05a8832bb3eb..d06886a2bfb5 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -1009,4 +1009,4 @@ module_exit(adp8870_exit);
1009MODULE_LICENSE("GPL v2"); 1009MODULE_LICENSE("GPL v2");
1010MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 1010MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
1011MODULE_DESCRIPTION("ADP8870 Backlight driver"); 1011MODULE_DESCRIPTION("ADP8870 Backlight driver");
1012MODULE_ALIAS("platform:adp8870-backlight"); 1012MODULE_ALIAS("i2c:adp8870-backlight");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 80d292fb92d8..7363c1b169e8 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -19,7 +19,7 @@
19#include <asm/backlight.h> 19#include <asm/backlight.h>
20#endif 20#endif
21 21
22static const char const *backlight_types[] = { 22static const char *const backlight_types[] = {
23 [BACKLIGHT_RAW] = "raw", 23 [BACKLIGHT_RAW] = "raw",
24 [BACKLIGHT_PLATFORM] = "platform", 24 [BACKLIGHT_PLATFORM] = "platform",
25 [BACKLIGHT_FIRMWARE] = "firmware", 25 [BACKLIGHT_FIRMWARE] = "firmware",
diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c
index 9f1e389d51d2..b0582917f0c8 100644
--- a/drivers/video/backlight/ep93xx_bl.c
+++ b/drivers/video/backlight/ep93xx_bl.c
@@ -11,7 +11,7 @@
11 * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors. 11 * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors.
12 */ 12 */
13 13
14 14#include <linux/module.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/fb.h> 17#include <linux/fb.h>
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index b8f38ec6eb18..8b5b2a4124c7 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -28,6 +28,8 @@ struct pwm_bl_data {
28 unsigned int lth_brightness; 28 unsigned int lth_brightness;
29 int (*notify)(struct device *, 29 int (*notify)(struct device *,
30 int brightness); 30 int brightness);
31 void (*notify_after)(struct device *,
32 int brightness);
31 int (*check_fb)(struct device *, struct fb_info *); 33 int (*check_fb)(struct device *, struct fb_info *);
32}; 34};
33 35
@@ -55,6 +57,10 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
55 pwm_config(pb->pwm, brightness, pb->period); 57 pwm_config(pb->pwm, brightness, pb->period);
56 pwm_enable(pb->pwm); 58 pwm_enable(pb->pwm);
57 } 59 }
60
61 if (pb->notify_after)
62 pb->notify_after(pb->dev, brightness);
63
58 return 0; 64 return 0;
59} 65}
60 66
@@ -105,6 +111,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
105 111
106 pb->period = data->pwm_period_ns; 112 pb->period = data->pwm_period_ns;
107 pb->notify = data->notify; 113 pb->notify = data->notify;
114 pb->notify_after = data->notify_after;
108 pb->check_fb = data->check_fb; 115 pb->check_fb = data->check_fb;
109 pb->lth_brightness = data->lth_brightness * 116 pb->lth_brightness = data->lth_brightness *
110 (data->pwm_period_ns / data->max_brightness); 117 (data->pwm_period_ns / data->max_brightness);
@@ -172,6 +179,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev,
172 pb->notify(pb->dev, 0); 179 pb->notify(pb->dev, 0);
173 pwm_config(pb->pwm, 0, pb->period); 180 pwm_config(pb->pwm, 0, pb->period);
174 pwm_disable(pb->pwm); 181 pwm_disable(pb->pwm);
182 if (pb->notify_after)
183 pb->notify_after(pb->dev, 0);
175 return 0; 184 return 0;
176} 185}
177 186
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index fdd5d4ae437d..4e888ac09b3f 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -504,14 +504,18 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
504 return 0; 504 return 0;
505 505
506 r = omapdss_dsi_display_enable(dssdev); 506 r = omapdss_dsi_display_enable(dssdev);
507 if (r) 507 if (r) {
508 goto err; 508 dev_err(&dssdev->dev, "failed to enable DSI\n");
509 goto err1;
510 }
509 511
510 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true); 512 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
511 513
512 r = _taal_enable_te(dssdev, true); 514 r = _taal_enable_te(dssdev, true);
513 if (r) 515 if (r) {
514 goto err; 516 dev_err(&dssdev->dev, "failed to re-enable TE");
517 goto err2;
518 }
515 519
516 enable_irq(gpio_to_irq(panel_data->ext_te_gpio)); 520 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
517 521
@@ -521,13 +525,15 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
521 525
522 return 0; 526 return 0;
523 527
524err: 528err2:
525 dev_err(&dssdev->dev, "exit ULPS failed"); 529 dev_err(&dssdev->dev, "failed to exit ULPS");
526 r = taal_panel_reset(dssdev);
527
528 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
529 td->ulps_enabled = false;
530 530
531 r = taal_panel_reset(dssdev);
532 if (!r) {
533 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
534 td->ulps_enabled = false;
535 }
536err1:
531 taal_queue_ulps_work(dssdev); 537 taal_queue_ulps_work(dssdev);
532 538
533 return r; 539 return r;
@@ -1241,11 +1247,8 @@ static void taal_power_off(struct omap_dss_device *dssdev)
1241 int r; 1247 int r;
1242 1248
1243 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF); 1249 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
1244 if (!r) { 1250 if (!r)
1245 r = taal_sleep_in(td); 1251 r = taal_sleep_in(td);
1246 /* HACK: wait a bit so that the message goes through */
1247 msleep(10);
1248 }
1249 1252
1250 if (r) { 1253 if (r) {
1251 dev_err(&dssdev->dev, 1254 dev_err(&dssdev->dev,
@@ -1317,8 +1320,11 @@ static void taal_disable(struct omap_dss_device *dssdev)
1317 dsi_bus_lock(dssdev); 1320 dsi_bus_lock(dssdev);
1318 1321
1319 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 1322 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
1320 taal_wake_up(dssdev); 1323 int r;
1321 taal_power_off(dssdev); 1324
1325 r = taal_wake_up(dssdev);
1326 if (!r)
1327 taal_power_off(dssdev);
1322 } 1328 }
1323 1329
1324 dsi_bus_unlock(dssdev); 1330 dsi_bus_unlock(dssdev);
@@ -1897,20 +1903,6 @@ err:
1897 mutex_unlock(&td->lock); 1903 mutex_unlock(&td->lock);
1898} 1904}
1899 1905
1900static int taal_set_update_mode(struct omap_dss_device *dssdev,
1901 enum omap_dss_update_mode mode)
1902{
1903 if (mode != OMAP_DSS_UPDATE_MANUAL)
1904 return -EINVAL;
1905 return 0;
1906}
1907
1908static enum omap_dss_update_mode taal_get_update_mode(
1909 struct omap_dss_device *dssdev)
1910{
1911 return OMAP_DSS_UPDATE_MANUAL;
1912}
1913
1914static struct omap_dss_driver taal_driver = { 1906static struct omap_dss_driver taal_driver = {
1915 .probe = taal_probe, 1907 .probe = taal_probe,
1916 .remove = __exit_p(taal_remove), 1908 .remove = __exit_p(taal_remove),
@@ -1920,9 +1912,6 @@ static struct omap_dss_driver taal_driver = {
1920 .suspend = taal_suspend, 1912 .suspend = taal_suspend,
1921 .resume = taal_resume, 1913 .resume = taal_resume,
1922 1914
1923 .set_update_mode = taal_set_update_mode,
1924 .get_update_mode = taal_get_update_mode,
1925
1926 .update = taal_update, 1915 .update = taal_update,
1927 .sync = taal_sync, 1916 .sync = taal_sync,
1928 1917
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 6b3e2da11419..0d12524db14b 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -117,18 +117,6 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
117 Max FCK is 173MHz, so this doesn't work if your PCK 117 Max FCK is 173MHz, so this doesn't work if your PCK
118 is very high. 118 is very high.
119 119
120config OMAP2_DSS_SLEEP_BEFORE_RESET
121 bool "Sleep 50ms before DSS reset"
122 default y
123 help
124 For some unknown reason we may get SYNC_LOST errors from the display
125 subsystem at initialization time if we don't sleep before resetting
126 the DSS. See the source (dss.c) for more comments.
127
128 However, 50ms is quite long time to sleep, and with some
129 configurations the SYNC_LOST may never happen, so the sleep can
130 be disabled here.
131
132config OMAP2_DSS_SLEEP_AFTER_VENC_RESET 120config OMAP2_DSS_SLEEP_AFTER_VENC_RESET
133 bool "Sleep 20ms after VENC reset" 121 bool "Sleep 20ms after VENC reset"
134 default y 122 default y
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 3da426719dd6..76821fefce9a 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -183,8 +183,11 @@ static int omap_dss_probe(struct platform_device *pdev)
183 goto err_dss; 183 goto err_dss;
184 } 184 }
185 185
186 /* keep clocks enabled to prevent context saves/restores during init */ 186 r = dispc_init_platform_driver();
187 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 187 if (r) {
188 DSSERR("Failed to initialize dispc platform driver\n");
189 goto err_dispc;
190 }
188 191
189 r = rfbi_init_platform_driver(); 192 r = rfbi_init_platform_driver();
190 if (r) { 193 if (r) {
@@ -192,12 +195,6 @@ static int omap_dss_probe(struct platform_device *pdev)
192 goto err_rfbi; 195 goto err_rfbi;
193 } 196 }
194 197
195 r = dispc_init_platform_driver();
196 if (r) {
197 DSSERR("Failed to initialize dispc platform driver\n");
198 goto err_dispc;
199 }
200
201 r = venc_init_platform_driver(); 198 r = venc_init_platform_driver();
202 if (r) { 199 if (r) {
203 DSSERR("Failed to initialize venc platform driver\n"); 200 DSSERR("Failed to initialize venc platform driver\n");
@@ -238,8 +235,6 @@ static int omap_dss_probe(struct platform_device *pdev)
238 pdata->default_device = dssdev; 235 pdata->default_device = dssdev;
239 } 236 }
240 237
241 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
242
243 return 0; 238 return 0;
244 239
245err_register: 240err_register:
@@ -268,11 +263,11 @@ static int omap_dss_remove(struct platform_device *pdev)
268 263
269 dss_uninitialize_debugfs(); 264 dss_uninitialize_debugfs();
270 265
266 hdmi_uninit_platform_driver();
267 dsi_uninit_platform_driver();
271 venc_uninit_platform_driver(); 268 venc_uninit_platform_driver();
272 dispc_uninit_platform_driver();
273 rfbi_uninit_platform_driver(); 269 rfbi_uninit_platform_driver();
274 dsi_uninit_platform_driver(); 270 dispc_uninit_platform_driver();
275 hdmi_uninit_platform_driver();
276 dss_uninit_platform_driver(); 271 dss_uninit_platform_driver();
277 272
278 dss_uninit_overlays(pdev); 273 dss_uninit_overlays(pdev);
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 7a9a2e7d9685..0f3961a1ce26 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -33,6 +33,8 @@
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h> 34#include <linux/hardirq.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/platform_device.h>
37#include <linux/pm_runtime.h>
36 38
37#include <plat/sram.h> 39#include <plat/sram.h>
38#include <plat/clock.h> 40#include <plat/clock.h>
@@ -77,6 +79,12 @@ struct dispc_v_coef {
77 s8 vc00; 79 s8 vc00;
78}; 80};
79 81
82enum omap_burst_size {
83 BURST_SIZE_X2 = 0,
84 BURST_SIZE_X4 = 1,
85 BURST_SIZE_X8 = 2,
86};
87
80#define REG_GET(idx, start, end) \ 88#define REG_GET(idx, start, end) \
81 FLD_GET(dispc_read_reg(idx), start, end) 89 FLD_GET(dispc_read_reg(idx), start, end)
82 90
@@ -92,7 +100,11 @@ struct dispc_irq_stats {
92static struct { 100static struct {
93 struct platform_device *pdev; 101 struct platform_device *pdev;
94 void __iomem *base; 102 void __iomem *base;
103
104 int ctx_loss_cnt;
105
95 int irq; 106 int irq;
107 struct clk *dss_clk;
96 108
97 u32 fifo_size[3]; 109 u32 fifo_size[3];
98 110
@@ -102,6 +114,7 @@ static struct {
102 u32 error_irqs; 114 u32 error_irqs;
103 struct work_struct error_work; 115 struct work_struct error_work;
104 116
117 bool ctx_valid;
105 u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; 118 u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
106 119
107#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 120#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -134,18 +147,34 @@ static inline u32 dispc_read_reg(const u16 idx)
134 return __raw_readl(dispc.base + idx); 147 return __raw_readl(dispc.base + idx);
135} 148}
136 149
150static int dispc_get_ctx_loss_count(void)
151{
152 struct device *dev = &dispc.pdev->dev;
153 struct omap_display_platform_data *pdata = dev->platform_data;
154 struct omap_dss_board_info *board_data = pdata->board_data;
155 int cnt;
156
157 if (!board_data->get_context_loss_count)
158 return -ENOENT;
159
160 cnt = board_data->get_context_loss_count(dev);
161
162 WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt);
163
164 return cnt;
165}
166
137#define SR(reg) \ 167#define SR(reg) \
138 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 168 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
139#define RR(reg) \ 169#define RR(reg) \
140 dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)]) 170 dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)])
141 171
142void dispc_save_context(void) 172static void dispc_save_context(void)
143{ 173{
144 int i; 174 int i;
145 if (cpu_is_omap24xx())
146 return;
147 175
148 SR(SYSCONFIG); 176 DSSDBG("dispc_save_context\n");
177
149 SR(IRQENABLE); 178 SR(IRQENABLE);
150 SR(CONTROL); 179 SR(CONTROL);
151 SR(CONFIG); 180 SR(CONFIG);
@@ -158,7 +187,8 @@ void dispc_save_context(void)
158 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD)); 187 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
159 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD)); 188 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
160 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD)); 189 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
161 SR(GLOBAL_ALPHA); 190 if (dss_has_feature(FEAT_GLOBAL_ALPHA))
191 SR(GLOBAL_ALPHA);
162 SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 192 SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
163 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD)); 193 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
164 if (dss_has_feature(FEAT_MGR_LCD2)) { 194 if (dss_has_feature(FEAT_MGR_LCD2)) {
@@ -188,20 +218,25 @@ void dispc_save_context(void)
188 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 218 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
189 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 219 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
190 220
191 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 221 if (dss_has_feature(FEAT_CPR)) {
192 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 222 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
193 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 223 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
224 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
225 }
194 if (dss_has_feature(FEAT_MGR_LCD2)) { 226 if (dss_has_feature(FEAT_MGR_LCD2)) {
195 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 227 if (dss_has_feature(FEAT_CPR)) {
196 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 228 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
197 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 229 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
230 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
231 }
198 232
199 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 233 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
200 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 234 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
201 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 235 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
202 } 236 }
203 237
204 SR(OVL_PRELOAD(OMAP_DSS_GFX)); 238 if (dss_has_feature(FEAT_PRELOAD))
239 SR(OVL_PRELOAD(OMAP_DSS_GFX));
205 240
206 /* VID1 */ 241 /* VID1 */
207 SR(OVL_BA0(OMAP_DSS_VIDEO1)); 242 SR(OVL_BA0(OMAP_DSS_VIDEO1));
@@ -226,8 +261,10 @@ void dispc_save_context(void)
226 for (i = 0; i < 5; i++) 261 for (i = 0; i < 5; i++)
227 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i)); 262 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
228 263
229 for (i = 0; i < 8; i++) 264 if (dss_has_feature(FEAT_FIR_COEF_V)) {
230 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i)); 265 for (i = 0; i < 8; i++)
266 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
267 }
231 268
232 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 269 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
233 SR(OVL_BA0_UV(OMAP_DSS_VIDEO1)); 270 SR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
@@ -248,7 +285,8 @@ void dispc_save_context(void)
248 if (dss_has_feature(FEAT_ATTR2)) 285 if (dss_has_feature(FEAT_ATTR2))
249 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1)); 286 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
250 287
251 SR(OVL_PRELOAD(OMAP_DSS_VIDEO1)); 288 if (dss_has_feature(FEAT_PRELOAD))
289 SR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
252 290
253 /* VID2 */ 291 /* VID2 */
254 SR(OVL_BA0(OMAP_DSS_VIDEO2)); 292 SR(OVL_BA0(OMAP_DSS_VIDEO2));
@@ -273,8 +311,10 @@ void dispc_save_context(void)
273 for (i = 0; i < 5; i++) 311 for (i = 0; i < 5; i++)
274 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i)); 312 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
275 313
276 for (i = 0; i < 8; i++) 314 if (dss_has_feature(FEAT_FIR_COEF_V)) {
277 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 315 for (i = 0; i < 8; i++)
316 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
317 }
278 318
279 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 319 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
280 SR(OVL_BA0_UV(OMAP_DSS_VIDEO2)); 320 SR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
@@ -295,16 +335,35 @@ void dispc_save_context(void)
295 if (dss_has_feature(FEAT_ATTR2)) 335 if (dss_has_feature(FEAT_ATTR2))
296 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2)); 336 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
297 337
298 SR(OVL_PRELOAD(OMAP_DSS_VIDEO2)); 338 if (dss_has_feature(FEAT_PRELOAD))
339 SR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
299 340
300 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 341 if (dss_has_feature(FEAT_CORE_CLK_DIV))
301 SR(DIVISOR); 342 SR(DIVISOR);
343
344 dispc.ctx_loss_cnt = dispc_get_ctx_loss_count();
345 dispc.ctx_valid = true;
346
347 DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt);
302} 348}
303 349
304void dispc_restore_context(void) 350static void dispc_restore_context(void)
305{ 351{
306 int i; 352 int i, ctx;
307 RR(SYSCONFIG); 353
354 DSSDBG("dispc_restore_context\n");
355
356 if (!dispc.ctx_valid)
357 return;
358
359 ctx = dispc_get_ctx_loss_count();
360
361 if (ctx >= 0 && ctx == dispc.ctx_loss_cnt)
362 return;
363
364 DSSDBG("ctx_loss_count: saved %d, current %d\n",
365 dispc.ctx_loss_cnt, ctx);
366
308 /*RR(IRQENABLE);*/ 367 /*RR(IRQENABLE);*/
309 /*RR(CONTROL);*/ 368 /*RR(CONTROL);*/
310 RR(CONFIG); 369 RR(CONFIG);
@@ -317,7 +376,8 @@ void dispc_restore_context(void)
317 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD)); 376 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
318 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD)); 377 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
319 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD)); 378 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
320 RR(GLOBAL_ALPHA); 379 if (dss_has_feature(FEAT_GLOBAL_ALPHA))
380 RR(GLOBAL_ALPHA);
321 RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 381 RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
322 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD)); 382 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
323 if (dss_has_feature(FEAT_MGR_LCD2)) { 383 if (dss_has_feature(FEAT_MGR_LCD2)) {
@@ -347,20 +407,25 @@ void dispc_restore_context(void)
347 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 407 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
348 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 408 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
349 409
350 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 410 if (dss_has_feature(FEAT_CPR)) {
351 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 411 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
352 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 412 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
413 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
414 }
353 if (dss_has_feature(FEAT_MGR_LCD2)) { 415 if (dss_has_feature(FEAT_MGR_LCD2)) {
354 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 416 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
355 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 417 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
356 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 418 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
357 419
358 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 420 if (dss_has_feature(FEAT_CPR)) {
359 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 421 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
360 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 422 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
423 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
424 }
361 } 425 }
362 426
363 RR(OVL_PRELOAD(OMAP_DSS_GFX)); 427 if (dss_has_feature(FEAT_PRELOAD))
428 RR(OVL_PRELOAD(OMAP_DSS_GFX));
364 429
365 /* VID1 */ 430 /* VID1 */
366 RR(OVL_BA0(OMAP_DSS_VIDEO1)); 431 RR(OVL_BA0(OMAP_DSS_VIDEO1));
@@ -385,8 +450,10 @@ void dispc_restore_context(void)
385 for (i = 0; i < 5; i++) 450 for (i = 0; i < 5; i++)
386 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i)); 451 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
387 452
388 for (i = 0; i < 8; i++) 453 if (dss_has_feature(FEAT_FIR_COEF_V)) {
389 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i)); 454 for (i = 0; i < 8; i++)
455 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
456 }
390 457
391 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 458 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
392 RR(OVL_BA0_UV(OMAP_DSS_VIDEO1)); 459 RR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
@@ -407,7 +474,8 @@ void dispc_restore_context(void)
407 if (dss_has_feature(FEAT_ATTR2)) 474 if (dss_has_feature(FEAT_ATTR2))
408 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1)); 475 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
409 476
410 RR(OVL_PRELOAD(OMAP_DSS_VIDEO1)); 477 if (dss_has_feature(FEAT_PRELOAD))
478 RR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
411 479
412 /* VID2 */ 480 /* VID2 */
413 RR(OVL_BA0(OMAP_DSS_VIDEO2)); 481 RR(OVL_BA0(OMAP_DSS_VIDEO2));
@@ -432,8 +500,10 @@ void dispc_restore_context(void)
432 for (i = 0; i < 5; i++) 500 for (i = 0; i < 5; i++)
433 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i)); 501 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
434 502
435 for (i = 0; i < 8; i++) 503 if (dss_has_feature(FEAT_FIR_COEF_V)) {
436 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 504 for (i = 0; i < 8; i++)
505 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
506 }
437 507
438 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 508 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
439 RR(OVL_BA0_UV(OMAP_DSS_VIDEO2)); 509 RR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
@@ -454,7 +524,8 @@ void dispc_restore_context(void)
454 if (dss_has_feature(FEAT_ATTR2)) 524 if (dss_has_feature(FEAT_ATTR2))
455 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2)); 525 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
456 526
457 RR(OVL_PRELOAD(OMAP_DSS_VIDEO2)); 527 if (dss_has_feature(FEAT_PRELOAD))
528 RR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
458 529
459 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 530 if (dss_has_feature(FEAT_CORE_CLK_DIV))
460 RR(DIVISOR); 531 RR(DIVISOR);
@@ -471,19 +542,35 @@ void dispc_restore_context(void)
471 * the context is fully restored 542 * the context is fully restored
472 */ 543 */
473 RR(IRQENABLE); 544 RR(IRQENABLE);
545
546 DSSDBG("context restored\n");
474} 547}
475 548
476#undef SR 549#undef SR
477#undef RR 550#undef RR
478 551
479static inline void enable_clocks(bool enable) 552int dispc_runtime_get(void)
480{ 553{
481 if (enable) 554 int r;
482 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 555
483 else 556 DSSDBG("dispc_runtime_get\n");
484 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 557
558 r = pm_runtime_get_sync(&dispc.pdev->dev);
559 WARN_ON(r < 0);
560 return r < 0 ? r : 0;
485} 561}
486 562
563void dispc_runtime_put(void)
564{
565 int r;
566
567 DSSDBG("dispc_runtime_put\n");
568
569 r = pm_runtime_put(&dispc.pdev->dev);
570 WARN_ON(r < 0);
571}
572
573
487bool dispc_go_busy(enum omap_channel channel) 574bool dispc_go_busy(enum omap_channel channel)
488{ 575{
489 int bit; 576 int bit;
@@ -505,8 +592,6 @@ void dispc_go(enum omap_channel channel)
505 int bit; 592 int bit;
506 bool enable_bit, go_bit; 593 bool enable_bit, go_bit;
507 594
508 enable_clocks(1);
509
510 if (channel == OMAP_DSS_CHANNEL_LCD || 595 if (channel == OMAP_DSS_CHANNEL_LCD ||
511 channel == OMAP_DSS_CHANNEL_LCD2) 596 channel == OMAP_DSS_CHANNEL_LCD2)
512 bit = 0; /* LCDENABLE */ 597 bit = 0; /* LCDENABLE */
@@ -520,7 +605,7 @@ void dispc_go(enum omap_channel channel)
520 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1; 605 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
521 606
522 if (!enable_bit) 607 if (!enable_bit)
523 goto end; 608 return;
524 609
525 if (channel == OMAP_DSS_CHANNEL_LCD || 610 if (channel == OMAP_DSS_CHANNEL_LCD ||
526 channel == OMAP_DSS_CHANNEL_LCD2) 611 channel == OMAP_DSS_CHANNEL_LCD2)
@@ -535,7 +620,7 @@ void dispc_go(enum omap_channel channel)
535 620
536 if (go_bit) { 621 if (go_bit) {
537 DSSERR("GO bit not down for channel %d\n", channel); 622 DSSERR("GO bit not down for channel %d\n", channel);
538 goto end; 623 return;
539 } 624 }
540 625
541 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : 626 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" :
@@ -545,8 +630,6 @@ void dispc_go(enum omap_channel channel)
545 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit); 630 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
546 else 631 else
547 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); 632 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
548end:
549 enable_clocks(0);
550} 633}
551 634
552static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) 635static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
@@ -920,7 +1003,7 @@ static void _dispc_set_color_mode(enum omap_plane plane,
920 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); 1003 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
921} 1004}
922 1005
923static void _dispc_set_channel_out(enum omap_plane plane, 1006void dispc_set_channel_out(enum omap_plane plane,
924 enum omap_channel channel) 1007 enum omap_channel channel)
925{ 1008{
926 int shift; 1009 int shift;
@@ -967,13 +1050,10 @@ static void _dispc_set_channel_out(enum omap_plane plane,
967 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 1050 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
968} 1051}
969 1052
970void dispc_set_burst_size(enum omap_plane plane, 1053static void dispc_set_burst_size(enum omap_plane plane,
971 enum omap_burst_size burst_size) 1054 enum omap_burst_size burst_size)
972{ 1055{
973 int shift; 1056 int shift;
974 u32 val;
975
976 enable_clocks(1);
977 1057
978 switch (plane) { 1058 switch (plane) {
979 case OMAP_DSS_GFX: 1059 case OMAP_DSS_GFX:
@@ -988,11 +1068,24 @@ void dispc_set_burst_size(enum omap_plane plane,
988 return; 1068 return;
989 } 1069 }
990 1070
991 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); 1071 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift);
992 val = FLD_MOD(val, burst_size, shift+1, shift); 1072}
993 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
994 1073
995 enable_clocks(0); 1074static void dispc_configure_burst_sizes(void)
1075{
1076 int i;
1077 const int burst_size = BURST_SIZE_X8;
1078
1079 /* Configure burst size always to maximum size */
1080 for (i = 0; i < omap_dss_get_num_overlays(); ++i)
1081 dispc_set_burst_size(i, burst_size);
1082}
1083
1084u32 dispc_get_burst_size(enum omap_plane plane)
1085{
1086 unsigned unit = dss_feat_get_burst_size_unit();
1087 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
1088 return unit * 8;
996} 1089}
997 1090
998void dispc_enable_gamma_table(bool enable) 1091void dispc_enable_gamma_table(bool enable)
@@ -1009,6 +1102,40 @@ void dispc_enable_gamma_table(bool enable)
1009 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); 1102 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1010} 1103}
1011 1104
1105void dispc_enable_cpr(enum omap_channel channel, bool enable)
1106{
1107 u16 reg;
1108
1109 if (channel == OMAP_DSS_CHANNEL_LCD)
1110 reg = DISPC_CONFIG;
1111 else if (channel == OMAP_DSS_CHANNEL_LCD2)
1112 reg = DISPC_CONFIG2;
1113 else
1114 return;
1115
1116 REG_FLD_MOD(reg, enable, 15, 15);
1117}
1118
1119void dispc_set_cpr_coef(enum omap_channel channel,
1120 struct omap_dss_cpr_coefs *coefs)
1121{
1122 u32 coef_r, coef_g, coef_b;
1123
1124 if (channel != OMAP_DSS_CHANNEL_LCD && channel != OMAP_DSS_CHANNEL_LCD2)
1125 return;
1126
1127 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
1128 FLD_VAL(coefs->rb, 9, 0);
1129 coef_g = FLD_VAL(coefs->gr, 31, 22) | FLD_VAL(coefs->gg, 20, 11) |
1130 FLD_VAL(coefs->gb, 9, 0);
1131 coef_b = FLD_VAL(coefs->br, 31, 22) | FLD_VAL(coefs->bg, 20, 11) |
1132 FLD_VAL(coefs->bb, 9, 0);
1133
1134 dispc_write_reg(DISPC_CPR_COEF_R(channel), coef_r);
1135 dispc_write_reg(DISPC_CPR_COEF_G(channel), coef_g);
1136 dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b);
1137}
1138
1012static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1139static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1013{ 1140{
1014 u32 val; 1141 u32 val;
@@ -1029,9 +1156,7 @@ void dispc_enable_replication(enum omap_plane plane, bool enable)
1029 else 1156 else
1030 bit = 10; 1157 bit = 10;
1031 1158
1032 enable_clocks(1);
1033 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit); 1159 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
1034 enable_clocks(0);
1035} 1160}
1036 1161
1037void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height) 1162void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
@@ -1039,9 +1164,7 @@ void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
1039 u32 val; 1164 u32 val;
1040 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1165 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
1041 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1166 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
1042 enable_clocks(1);
1043 dispc_write_reg(DISPC_SIZE_MGR(channel), val); 1167 dispc_write_reg(DISPC_SIZE_MGR(channel), val);
1044 enable_clocks(0);
1045} 1168}
1046 1169
1047void dispc_set_digit_size(u16 width, u16 height) 1170void dispc_set_digit_size(u16 width, u16 height)
@@ -1049,9 +1172,7 @@ void dispc_set_digit_size(u16 width, u16 height)
1049 u32 val; 1172 u32 val;
1050 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1173 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
1051 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1174 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
1052 enable_clocks(1);
1053 dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val); 1175 dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val);
1054 enable_clocks(0);
1055} 1176}
1056 1177
1057static void dispc_read_plane_fifo_sizes(void) 1178static void dispc_read_plane_fifo_sizes(void)
@@ -1059,18 +1180,17 @@ static void dispc_read_plane_fifo_sizes(void)
1059 u32 size; 1180 u32 size;
1060 int plane; 1181 int plane;
1061 u8 start, end; 1182 u8 start, end;
1183 u32 unit;
1062 1184
1063 enable_clocks(1); 1185 unit = dss_feat_get_buffer_size_unit();
1064 1186
1065 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); 1187 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
1066 1188
1067 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) { 1189 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) {
1068 size = FLD_GET(dispc_read_reg(DISPC_OVL_FIFO_SIZE_STATUS(plane)), 1190 size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
1069 start, end); 1191 size *= unit;
1070 dispc.fifo_size[plane] = size; 1192 dispc.fifo_size[plane] = size;
1071 } 1193 }
1072
1073 enable_clocks(0);
1074} 1194}
1075 1195
1076u32 dispc_get_plane_fifo_size(enum omap_plane plane) 1196u32 dispc_get_plane_fifo_size(enum omap_plane plane)
@@ -1078,15 +1198,22 @@ u32 dispc_get_plane_fifo_size(enum omap_plane plane)
1078 return dispc.fifo_size[plane]; 1198 return dispc.fifo_size[plane];
1079} 1199}
1080 1200
1081void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high) 1201void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
1082{ 1202{
1083 u8 hi_start, hi_end, lo_start, lo_end; 1203 u8 hi_start, hi_end, lo_start, lo_end;
1204 u32 unit;
1205
1206 unit = dss_feat_get_buffer_size_unit();
1207
1208 WARN_ON(low % unit != 0);
1209 WARN_ON(high % unit != 0);
1210
1211 low /= unit;
1212 high /= unit;
1084 1213
1085 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); 1214 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
1086 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); 1215 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
1087 1216
1088 enable_clocks(1);
1089
1090 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", 1217 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
1091 plane, 1218 plane,
1092 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), 1219 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
@@ -1098,18 +1225,12 @@ void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high)
1098 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), 1225 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
1099 FLD_VAL(high, hi_start, hi_end) | 1226 FLD_VAL(high, hi_start, hi_end) |
1100 FLD_VAL(low, lo_start, lo_end)); 1227 FLD_VAL(low, lo_start, lo_end));
1101
1102 enable_clocks(0);
1103} 1228}
1104 1229
1105void dispc_enable_fifomerge(bool enable) 1230void dispc_enable_fifomerge(bool enable)
1106{ 1231{
1107 enable_clocks(1);
1108
1109 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); 1232 DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
1110 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1233 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
1111
1112 enable_clocks(0);
1113} 1234}
1114 1235
1115static void _dispc_set_fir(enum omap_plane plane, 1236static void _dispc_set_fir(enum omap_plane plane,
@@ -1729,14 +1850,7 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1729 return dispc_pclk_rate(channel) * vf * hf; 1850 return dispc_pclk_rate(channel) * vf * hf;
1730} 1851}
1731 1852
1732void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) 1853int dispc_setup_plane(enum omap_plane plane,
1733{
1734 enable_clocks(1);
1735 _dispc_set_channel_out(plane, channel_out);
1736 enable_clocks(0);
1737}
1738
1739static int _dispc_setup_plane(enum omap_plane plane,
1740 u32 paddr, u16 screen_width, 1854 u32 paddr, u16 screen_width,
1741 u16 pos_x, u16 pos_y, 1855 u16 pos_x, u16 pos_y,
1742 u16 width, u16 height, 1856 u16 width, u16 height,
@@ -1744,7 +1858,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
1744 enum omap_color_mode color_mode, 1858 enum omap_color_mode color_mode,
1745 bool ilace, 1859 bool ilace,
1746 enum omap_dss_rotation_type rotation_type, 1860 enum omap_dss_rotation_type rotation_type,
1747 u8 rotation, int mirror, 1861 u8 rotation, bool mirror,
1748 u8 global_alpha, u8 pre_mult_alpha, 1862 u8 global_alpha, u8 pre_mult_alpha,
1749 enum omap_channel channel, u32 puv_addr) 1863 enum omap_channel channel, u32 puv_addr)
1750{ 1864{
@@ -1758,6 +1872,14 @@ static int _dispc_setup_plane(enum omap_plane plane,
1758 u16 frame_height = height; 1872 u16 frame_height = height;
1759 unsigned int field_offset = 0; 1873 unsigned int field_offset = 0;
1760 1874
1875 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
1876 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
1877 plane, paddr, screen_width, pos_x, pos_y,
1878 width, height,
1879 out_width, out_height,
1880 ilace, color_mode,
1881 rotation, mirror, channel);
1882
1761 if (paddr == 0) 1883 if (paddr == 0)
1762 return -EINVAL; 1884 return -EINVAL;
1763 1885
@@ -1903,9 +2025,13 @@ static int _dispc_setup_plane(enum omap_plane plane,
1903 return 0; 2025 return 0;
1904} 2026}
1905 2027
1906static void _dispc_enable_plane(enum omap_plane plane, bool enable) 2028int dispc_enable_plane(enum omap_plane plane, bool enable)
1907{ 2029{
2030 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
2031
1908 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); 2032 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
2033
2034 return 0;
1909} 2035}
1910 2036
1911static void dispc_disable_isr(void *data, u32 mask) 2037static void dispc_disable_isr(void *data, u32 mask)
@@ -1929,8 +2055,6 @@ static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
1929 int r; 2055 int r;
1930 u32 irq; 2056 u32 irq;
1931 2057
1932 enable_clocks(1);
1933
1934 /* When we disable LCD output, we need to wait until frame is done. 2058 /* When we disable LCD output, we need to wait until frame is done.
1935 * Otherwise the DSS is still working, and turning off the clocks 2059 * Otherwise the DSS is still working, and turning off the clocks
1936 * prevents DSS from going to OFF mode */ 2060 * prevents DSS from going to OFF mode */
@@ -1964,8 +2088,6 @@ static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
1964 if (r) 2088 if (r)
1965 DSSERR("failed to unregister FRAMEDONE isr\n"); 2089 DSSERR("failed to unregister FRAMEDONE isr\n");
1966 } 2090 }
1967
1968 enable_clocks(0);
1969} 2091}
1970 2092
1971static void _enable_digit_out(bool enable) 2093static void _enable_digit_out(bool enable)
@@ -1978,12 +2100,8 @@ static void dispc_enable_digit_out(bool enable)
1978 struct completion frame_done_completion; 2100 struct completion frame_done_completion;
1979 int r; 2101 int r;
1980 2102
1981 enable_clocks(1); 2103 if (REG_GET(DISPC_CONTROL, 1, 1) == enable)
1982
1983 if (REG_GET(DISPC_CONTROL, 1, 1) == enable) {
1984 enable_clocks(0);
1985 return; 2104 return;
1986 }
1987 2105
1988 if (enable) { 2106 if (enable) {
1989 unsigned long flags; 2107 unsigned long flags;
@@ -2035,8 +2153,6 @@ static void dispc_enable_digit_out(bool enable)
2035 _omap_dispc_set_irqs(); 2153 _omap_dispc_set_irqs();
2036 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2154 spin_unlock_irqrestore(&dispc.irq_lock, flags);
2037 } 2155 }
2038
2039 enable_clocks(0);
2040} 2156}
2041 2157
2042bool dispc_is_channel_enabled(enum omap_channel channel) 2158bool dispc_is_channel_enabled(enum omap_channel channel)
@@ -2067,9 +2183,7 @@ void dispc_lcd_enable_signal_polarity(bool act_high)
2067 if (!dss_has_feature(FEAT_LCDENABLEPOL)) 2183 if (!dss_has_feature(FEAT_LCDENABLEPOL))
2068 return; 2184 return;
2069 2185
2070 enable_clocks(1);
2071 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29); 2186 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
2072 enable_clocks(0);
2073} 2187}
2074 2188
2075void dispc_lcd_enable_signal(bool enable) 2189void dispc_lcd_enable_signal(bool enable)
@@ -2077,9 +2191,7 @@ void dispc_lcd_enable_signal(bool enable)
2077 if (!dss_has_feature(FEAT_LCDENABLESIGNAL)) 2191 if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
2078 return; 2192 return;
2079 2193
2080 enable_clocks(1);
2081 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28); 2194 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
2082 enable_clocks(0);
2083} 2195}
2084 2196
2085void dispc_pck_free_enable(bool enable) 2197void dispc_pck_free_enable(bool enable)
@@ -2087,19 +2199,15 @@ void dispc_pck_free_enable(bool enable)
2087 if (!dss_has_feature(FEAT_PCKFREEENABLE)) 2199 if (!dss_has_feature(FEAT_PCKFREEENABLE))
2088 return; 2200 return;
2089 2201
2090 enable_clocks(1);
2091 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 2202 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
2092 enable_clocks(0);
2093} 2203}
2094 2204
2095void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) 2205void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
2096{ 2206{
2097 enable_clocks(1);
2098 if (channel == OMAP_DSS_CHANNEL_LCD2) 2207 if (channel == OMAP_DSS_CHANNEL_LCD2)
2099 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16); 2208 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
2100 else 2209 else
2101 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); 2210 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
2102 enable_clocks(0);
2103} 2211}
2104 2212
2105 2213
@@ -2122,27 +2230,21 @@ void dispc_set_lcd_display_type(enum omap_channel channel,
2122 return; 2230 return;
2123 } 2231 }
2124 2232
2125 enable_clocks(1);
2126 if (channel == OMAP_DSS_CHANNEL_LCD2) 2233 if (channel == OMAP_DSS_CHANNEL_LCD2)
2127 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3); 2234 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
2128 else 2235 else
2129 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); 2236 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
2130 enable_clocks(0);
2131} 2237}
2132 2238
2133void dispc_set_loadmode(enum omap_dss_load_mode mode) 2239void dispc_set_loadmode(enum omap_dss_load_mode mode)
2134{ 2240{
2135 enable_clocks(1);
2136 REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1); 2241 REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1);
2137 enable_clocks(0);
2138} 2242}
2139 2243
2140 2244
2141void dispc_set_default_color(enum omap_channel channel, u32 color) 2245void dispc_set_default_color(enum omap_channel channel, u32 color)
2142{ 2246{
2143 enable_clocks(1);
2144 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color); 2247 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
2145 enable_clocks(0);
2146} 2248}
2147 2249
2148u32 dispc_get_default_color(enum omap_channel channel) 2250u32 dispc_get_default_color(enum omap_channel channel)
@@ -2153,9 +2255,7 @@ u32 dispc_get_default_color(enum omap_channel channel)
2153 channel != OMAP_DSS_CHANNEL_LCD && 2255 channel != OMAP_DSS_CHANNEL_LCD &&
2154 channel != OMAP_DSS_CHANNEL_LCD2); 2256 channel != OMAP_DSS_CHANNEL_LCD2);
2155 2257
2156 enable_clocks(1);
2157 l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel)); 2258 l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
2158 enable_clocks(0);
2159 2259
2160 return l; 2260 return l;
2161} 2261}
@@ -2164,7 +2264,6 @@ void dispc_set_trans_key(enum omap_channel ch,
2164 enum omap_dss_trans_key_type type, 2264 enum omap_dss_trans_key_type type,
2165 u32 trans_key) 2265 u32 trans_key)
2166{ 2266{
2167 enable_clocks(1);
2168 if (ch == OMAP_DSS_CHANNEL_LCD) 2267 if (ch == OMAP_DSS_CHANNEL_LCD)
2169 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); 2268 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
2170 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2269 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
@@ -2173,14 +2272,12 @@ void dispc_set_trans_key(enum omap_channel ch,
2173 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11); 2272 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
2174 2273
2175 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); 2274 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
2176 enable_clocks(0);
2177} 2275}
2178 2276
2179void dispc_get_trans_key(enum omap_channel ch, 2277void dispc_get_trans_key(enum omap_channel ch,
2180 enum omap_dss_trans_key_type *type, 2278 enum omap_dss_trans_key_type *type,
2181 u32 *trans_key) 2279 u32 *trans_key)
2182{ 2280{
2183 enable_clocks(1);
2184 if (type) { 2281 if (type) {
2185 if (ch == OMAP_DSS_CHANNEL_LCD) 2282 if (ch == OMAP_DSS_CHANNEL_LCD)
2186 *type = REG_GET(DISPC_CONFIG, 11, 11); 2283 *type = REG_GET(DISPC_CONFIG, 11, 11);
@@ -2194,33 +2291,28 @@ void dispc_get_trans_key(enum omap_channel ch,
2194 2291
2195 if (trans_key) 2292 if (trans_key)
2196 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch)); 2293 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
2197 enable_clocks(0);
2198} 2294}
2199 2295
2200void dispc_enable_trans_key(enum omap_channel ch, bool enable) 2296void dispc_enable_trans_key(enum omap_channel ch, bool enable)
2201{ 2297{
2202 enable_clocks(1);
2203 if (ch == OMAP_DSS_CHANNEL_LCD) 2298 if (ch == OMAP_DSS_CHANNEL_LCD)
2204 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); 2299 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
2205 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2300 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2206 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); 2301 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
2207 else /* OMAP_DSS_CHANNEL_LCD2 */ 2302 else /* OMAP_DSS_CHANNEL_LCD2 */
2208 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10); 2303 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
2209 enable_clocks(0);
2210} 2304}
2211void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2305void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
2212{ 2306{
2213 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 2307 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
2214 return; 2308 return;
2215 2309
2216 enable_clocks(1);
2217 if (ch == OMAP_DSS_CHANNEL_LCD) 2310 if (ch == OMAP_DSS_CHANNEL_LCD)
2218 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); 2311 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
2219 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2312 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2220 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 2313 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
2221 else /* OMAP_DSS_CHANNEL_LCD2 */ 2314 else /* OMAP_DSS_CHANNEL_LCD2 */
2222 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18); 2315 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
2223 enable_clocks(0);
2224} 2316}
2225bool dispc_alpha_blending_enabled(enum omap_channel ch) 2317bool dispc_alpha_blending_enabled(enum omap_channel ch)
2226{ 2318{
@@ -2229,7 +2321,6 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch)
2229 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 2321 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
2230 return false; 2322 return false;
2231 2323
2232 enable_clocks(1);
2233 if (ch == OMAP_DSS_CHANNEL_LCD) 2324 if (ch == OMAP_DSS_CHANNEL_LCD)
2234 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2325 enabled = REG_GET(DISPC_CONFIG, 18, 18);
2235 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2326 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
@@ -2238,7 +2329,6 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch)
2238 enabled = REG_GET(DISPC_CONFIG2, 18, 18); 2329 enabled = REG_GET(DISPC_CONFIG2, 18, 18);
2239 else 2330 else
2240 BUG(); 2331 BUG();
2241 enable_clocks(0);
2242 2332
2243 return enabled; 2333 return enabled;
2244} 2334}
@@ -2248,7 +2338,6 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2248{ 2338{
2249 bool enabled; 2339 bool enabled;
2250 2340
2251 enable_clocks(1);
2252 if (ch == OMAP_DSS_CHANNEL_LCD) 2341 if (ch == OMAP_DSS_CHANNEL_LCD)
2253 enabled = REG_GET(DISPC_CONFIG, 10, 10); 2342 enabled = REG_GET(DISPC_CONFIG, 10, 10);
2254 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2343 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
@@ -2257,7 +2346,6 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2257 enabled = REG_GET(DISPC_CONFIG2, 10, 10); 2346 enabled = REG_GET(DISPC_CONFIG2, 10, 10);
2258 else 2347 else
2259 BUG(); 2348 BUG();
2260 enable_clocks(0);
2261 2349
2262 return enabled; 2350 return enabled;
2263} 2351}
@@ -2285,12 +2373,10 @@ void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2285 return; 2373 return;
2286 } 2374 }
2287 2375
2288 enable_clocks(1);
2289 if (channel == OMAP_DSS_CHANNEL_LCD2) 2376 if (channel == OMAP_DSS_CHANNEL_LCD2)
2290 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8); 2377 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
2291 else 2378 else
2292 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); 2379 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2293 enable_clocks(0);
2294} 2380}
2295 2381
2296void dispc_set_parallel_interface_mode(enum omap_channel channel, 2382void dispc_set_parallel_interface_mode(enum omap_channel channel,
@@ -2322,8 +2408,6 @@ void dispc_set_parallel_interface_mode(enum omap_channel channel,
2322 return; 2408 return;
2323 } 2409 }
2324 2410
2325 enable_clocks(1);
2326
2327 if (channel == OMAP_DSS_CHANNEL_LCD2) { 2411 if (channel == OMAP_DSS_CHANNEL_LCD2) {
2328 l = dispc_read_reg(DISPC_CONTROL2); 2412 l = dispc_read_reg(DISPC_CONTROL2);
2329 l = FLD_MOD(l, stallmode, 11, 11); 2413 l = FLD_MOD(l, stallmode, 11, 11);
@@ -2335,8 +2419,6 @@ void dispc_set_parallel_interface_mode(enum omap_channel channel,
2335 l = FLD_MOD(l, gpout1, 16, 16); 2419 l = FLD_MOD(l, gpout1, 16, 16);
2336 dispc_write_reg(DISPC_CONTROL, l); 2420 dispc_write_reg(DISPC_CONTROL, l);
2337 } 2421 }
2338
2339 enable_clocks(0);
2340} 2422}
2341 2423
2342static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, 2424static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -2389,10 +2471,8 @@ static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
2389 FLD_VAL(vbp, 31, 20); 2471 FLD_VAL(vbp, 31, 20);
2390 } 2472 }
2391 2473
2392 enable_clocks(1);
2393 dispc_write_reg(DISPC_TIMING_H(channel), timing_h); 2474 dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
2394 dispc_write_reg(DISPC_TIMING_V(channel), timing_v); 2475 dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
2395 enable_clocks(0);
2396} 2476}
2397 2477
2398/* change name to mode? */ 2478/* change name to mode? */
@@ -2435,10 +2515,8 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2435 BUG_ON(lck_div < 1); 2515 BUG_ON(lck_div < 1);
2436 BUG_ON(pck_div < 2); 2516 BUG_ON(pck_div < 2);
2437 2517
2438 enable_clocks(1);
2439 dispc_write_reg(DISPC_DIVISORo(channel), 2518 dispc_write_reg(DISPC_DIVISORo(channel),
2440 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2519 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2441 enable_clocks(0);
2442} 2520}
2443 2521
2444static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div, 2522static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
@@ -2457,7 +2535,7 @@ unsigned long dispc_fclk_rate(void)
2457 2535
2458 switch (dss_get_dispc_clk_source()) { 2536 switch (dss_get_dispc_clk_source()) {
2459 case OMAP_DSS_CLK_SRC_FCK: 2537 case OMAP_DSS_CLK_SRC_FCK:
2460 r = dss_clk_get_rate(DSS_CLK_FCK); 2538 r = clk_get_rate(dispc.dss_clk);
2461 break; 2539 break;
2462 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2540 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2463 dsidev = dsi_get_dsidev_from_id(0); 2541 dsidev = dsi_get_dsidev_from_id(0);
@@ -2487,7 +2565,7 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2487 2565
2488 switch (dss_get_lcd_clk_source(channel)) { 2566 switch (dss_get_lcd_clk_source(channel)) {
2489 case OMAP_DSS_CLK_SRC_FCK: 2567 case OMAP_DSS_CLK_SRC_FCK:
2490 r = dss_clk_get_rate(DSS_CLK_FCK); 2568 r = clk_get_rate(dispc.dss_clk);
2491 break; 2569 break;
2492 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2570 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2493 dsidev = dsi_get_dsidev_from_id(0); 2571 dsidev = dsi_get_dsidev_from_id(0);
@@ -2526,7 +2604,8 @@ void dispc_dump_clocks(struct seq_file *s)
2526 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 2604 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2527 enum omap_dss_clk_source lcd_clk_src; 2605 enum omap_dss_clk_source lcd_clk_src;
2528 2606
2529 enable_clocks(1); 2607 if (dispc_runtime_get())
2608 return;
2530 2609
2531 seq_printf(s, "- DISPC -\n"); 2610 seq_printf(s, "- DISPC -\n");
2532 2611
@@ -2574,7 +2653,8 @@ void dispc_dump_clocks(struct seq_file *s)
2574 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", 2653 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2575 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd); 2654 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2576 } 2655 }
2577 enable_clocks(0); 2656
2657 dispc_runtime_put();
2578} 2658}
2579 2659
2580#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 2660#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -2629,7 +2709,8 @@ void dispc_dump_regs(struct seq_file *s)
2629{ 2709{
2630#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) 2710#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
2631 2711
2632 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 2712 if (dispc_runtime_get())
2713 return;
2633 2714
2634 DUMPREG(DISPC_REVISION); 2715 DUMPREG(DISPC_REVISION);
2635 DUMPREG(DISPC_SYSCONFIG); 2716 DUMPREG(DISPC_SYSCONFIG);
@@ -2649,7 +2730,8 @@ void dispc_dump_regs(struct seq_file *s)
2649 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD)); 2730 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD));
2650 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD)); 2731 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD));
2651 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD)); 2732 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD));
2652 DUMPREG(DISPC_GLOBAL_ALPHA); 2733 if (dss_has_feature(FEAT_GLOBAL_ALPHA))
2734 DUMPREG(DISPC_GLOBAL_ALPHA);
2653 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 2735 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
2654 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD)); 2736 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
2655 if (dss_has_feature(FEAT_MGR_LCD2)) { 2737 if (dss_has_feature(FEAT_MGR_LCD2)) {
@@ -2680,20 +2762,25 @@ void dispc_dump_regs(struct seq_file *s)
2680 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 2762 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
2681 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 2763 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
2682 2764
2683 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 2765 if (dss_has_feature(FEAT_CPR)) {
2684 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 2766 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
2685 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD)); 2767 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
2768 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
2769 }
2686 if (dss_has_feature(FEAT_MGR_LCD2)) { 2770 if (dss_has_feature(FEAT_MGR_LCD2)) {
2687 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 2771 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
2688 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 2772 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
2689 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 2773 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
2690 2774
2691 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 2775 if (dss_has_feature(FEAT_CPR)) {
2692 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 2776 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
2693 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 2777 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
2778 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
2779 }
2694 } 2780 }
2695 2781
2696 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX)); 2782 if (dss_has_feature(FEAT_PRELOAD))
2783 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX));
2697 2784
2698 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1)); 2785 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1));
2699 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1)); 2786 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1));
@@ -2744,14 +2831,16 @@ void dispc_dump_regs(struct seq_file *s)
2744 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2)); 2831 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2));
2745 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3)); 2832 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3));
2746 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4)); 2833 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4));
2747 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0)); 2834 if (dss_has_feature(FEAT_FIR_COEF_V)) {
2748 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1)); 2835 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0));
2749 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2)); 2836 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1));
2750 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3)); 2837 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2));
2751 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4)); 2838 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3));
2752 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5)); 2839 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4));
2753 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6)); 2840 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5));
2754 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7)); 2841 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6));
2842 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7));
2843 }
2755 2844
2756 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 2845 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2757 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1)); 2846 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1));
@@ -2812,14 +2901,17 @@ void dispc_dump_regs(struct seq_file *s)
2812 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2)); 2901 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2));
2813 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3)); 2902 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3));
2814 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4)); 2903 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4));
2815 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0)); 2904
2816 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1)); 2905 if (dss_has_feature(FEAT_FIR_COEF_V)) {
2817 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2)); 2906 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0));
2818 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3)); 2907 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1));
2819 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4)); 2908 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2));
2820 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5)); 2909 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3));
2821 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6)); 2910 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4));
2822 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7)); 2911 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5));
2912 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6));
2913 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7));
2914 }
2823 2915
2824 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 2916 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2825 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2)); 2917 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2));
@@ -2858,10 +2950,12 @@ void dispc_dump_regs(struct seq_file *s)
2858 if (dss_has_feature(FEAT_ATTR2)) 2950 if (dss_has_feature(FEAT_ATTR2))
2859 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2)); 2951 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
2860 2952
2861 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1)); 2953 if (dss_has_feature(FEAT_PRELOAD)) {
2862 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2)); 2954 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1));
2955 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
2956 }
2863 2957
2864 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 2958 dispc_runtime_put();
2865#undef DUMPREG 2959#undef DUMPREG
2866} 2960}
2867 2961
@@ -2882,9 +2976,7 @@ static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
2882 l |= FLD_VAL(acbi, 11, 8); 2976 l |= FLD_VAL(acbi, 11, 8);
2883 l |= FLD_VAL(acb, 7, 0); 2977 l |= FLD_VAL(acb, 7, 0);
2884 2978
2885 enable_clocks(1);
2886 dispc_write_reg(DISPC_POL_FREQ(channel), l); 2979 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2887 enable_clocks(0);
2888} 2980}
2889 2981
2890void dispc_set_pol_freq(enum omap_channel channel, 2982void dispc_set_pol_freq(enum omap_channel channel,
@@ -3005,15 +3097,11 @@ static void _omap_dispc_set_irqs(void)
3005 mask |= isr_data->mask; 3097 mask |= isr_data->mask;
3006 } 3098 }
3007 3099
3008 enable_clocks(1);
3009
3010 old_mask = dispc_read_reg(DISPC_IRQENABLE); 3100 old_mask = dispc_read_reg(DISPC_IRQENABLE);
3011 /* clear the irqstatus for newly enabled irqs */ 3101 /* clear the irqstatus for newly enabled irqs */
3012 dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask); 3102 dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask);
3013 3103
3014 dispc_write_reg(DISPC_IRQENABLE, mask); 3104 dispc_write_reg(DISPC_IRQENABLE, mask);
3015
3016 enable_clocks(0);
3017} 3105}
3018 3106
3019int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask) 3107int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
@@ -3522,13 +3610,6 @@ static void _omap_dispc_initial_config(void)
3522{ 3610{
3523 u32 l; 3611 u32 l;
3524 3612
3525 l = dispc_read_reg(DISPC_SYSCONFIG);
3526 l = FLD_MOD(l, 2, 13, 12); /* MIDLEMODE: smart standby */
3527 l = FLD_MOD(l, 2, 4, 3); /* SIDLEMODE: smart idle */
3528 l = FLD_MOD(l, 1, 2, 2); /* ENWAKEUP */
3529 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
3530 dispc_write_reg(DISPC_SYSCONFIG, l);
3531
3532 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */ 3613 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
3533 if (dss_has_feature(FEAT_CORE_CLK_DIV)) { 3614 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
3534 l = dispc_read_reg(DISPC_DIVISOR); 3615 l = dispc_read_reg(DISPC_DIVISOR);
@@ -3552,58 +3633,8 @@ static void _omap_dispc_initial_config(void)
3552 dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); 3633 dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
3553 3634
3554 dispc_read_plane_fifo_sizes(); 3635 dispc_read_plane_fifo_sizes();
3555}
3556 3636
3557int dispc_enable_plane(enum omap_plane plane, bool enable) 3637 dispc_configure_burst_sizes();
3558{
3559 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
3560
3561 enable_clocks(1);
3562 _dispc_enable_plane(plane, enable);
3563 enable_clocks(0);
3564
3565 return 0;
3566}
3567
3568int dispc_setup_plane(enum omap_plane plane,
3569 u32 paddr, u16 screen_width,
3570 u16 pos_x, u16 pos_y,
3571 u16 width, u16 height,
3572 u16 out_width, u16 out_height,
3573 enum omap_color_mode color_mode,
3574 bool ilace,
3575 enum omap_dss_rotation_type rotation_type,
3576 u8 rotation, bool mirror, u8 global_alpha,
3577 u8 pre_mult_alpha, enum omap_channel channel,
3578 u32 puv_addr)
3579{
3580 int r = 0;
3581
3582 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d, %d, %dx%d -> "
3583 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
3584 plane, paddr, screen_width, pos_x, pos_y,
3585 width, height,
3586 out_width, out_height,
3587 ilace, color_mode,
3588 rotation, mirror, channel);
3589
3590 enable_clocks(1);
3591
3592 r = _dispc_setup_plane(plane,
3593 paddr, screen_width,
3594 pos_x, pos_y,
3595 width, height,
3596 out_width, out_height,
3597 color_mode, ilace,
3598 rotation_type,
3599 rotation, mirror,
3600 global_alpha,
3601 pre_mult_alpha,
3602 channel, puv_addr);
3603
3604 enable_clocks(0);
3605
3606 return r;
3607} 3638}
3608 3639
3609/* DISPC HW IP initialisation */ 3640/* DISPC HW IP initialisation */
@@ -3612,9 +3643,19 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3612 u32 rev; 3643 u32 rev;
3613 int r = 0; 3644 int r = 0;
3614 struct resource *dispc_mem; 3645 struct resource *dispc_mem;
3646 struct clk *clk;
3615 3647
3616 dispc.pdev = pdev; 3648 dispc.pdev = pdev;
3617 3649
3650 clk = clk_get(&pdev->dev, "fck");
3651 if (IS_ERR(clk)) {
3652 DSSERR("can't get fck\n");
3653 r = PTR_ERR(clk);
3654 goto err_get_clk;
3655 }
3656
3657 dispc.dss_clk = clk;
3658
3618 spin_lock_init(&dispc.irq_lock); 3659 spin_lock_init(&dispc.irq_lock);
3619 3660
3620#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 3661#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
@@ -3628,62 +3669,103 @@ static int omap_dispchw_probe(struct platform_device *pdev)
3628 if (!dispc_mem) { 3669 if (!dispc_mem) {
3629 DSSERR("can't get IORESOURCE_MEM DISPC\n"); 3670 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3630 r = -EINVAL; 3671 r = -EINVAL;
3631 goto fail0; 3672 goto err_ioremap;
3632 } 3673 }
3633 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); 3674 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3634 if (!dispc.base) { 3675 if (!dispc.base) {
3635 DSSERR("can't ioremap DISPC\n"); 3676 DSSERR("can't ioremap DISPC\n");
3636 r = -ENOMEM; 3677 r = -ENOMEM;
3637 goto fail0; 3678 goto err_ioremap;
3638 } 3679 }
3639 dispc.irq = platform_get_irq(dispc.pdev, 0); 3680 dispc.irq = platform_get_irq(dispc.pdev, 0);
3640 if (dispc.irq < 0) { 3681 if (dispc.irq < 0) {
3641 DSSERR("platform_get_irq failed\n"); 3682 DSSERR("platform_get_irq failed\n");
3642 r = -ENODEV; 3683 r = -ENODEV;
3643 goto fail1; 3684 goto err_irq;
3644 } 3685 }
3645 3686
3646 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, 3687 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3647 "OMAP DISPC", dispc.pdev); 3688 "OMAP DISPC", dispc.pdev);
3648 if (r < 0) { 3689 if (r < 0) {
3649 DSSERR("request_irq failed\n"); 3690 DSSERR("request_irq failed\n");
3650 goto fail1; 3691 goto err_irq;
3651 } 3692 }
3652 3693
3653 enable_clocks(1); 3694 pm_runtime_enable(&pdev->dev);
3695
3696 r = dispc_runtime_get();
3697 if (r)
3698 goto err_runtime_get;
3654 3699
3655 _omap_dispc_initial_config(); 3700 _omap_dispc_initial_config();
3656 3701
3657 _omap_dispc_initialize_irq(); 3702 _omap_dispc_initialize_irq();
3658 3703
3659 dispc_save_context();
3660
3661 rev = dispc_read_reg(DISPC_REVISION); 3704 rev = dispc_read_reg(DISPC_REVISION);
3662 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", 3705 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
3663 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 3706 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3664 3707
3665 enable_clocks(0); 3708 dispc_runtime_put();
3666 3709
3667 return 0; 3710 return 0;
3668fail1: 3711
3712err_runtime_get:
3713 pm_runtime_disable(&pdev->dev);
3714 free_irq(dispc.irq, dispc.pdev);
3715err_irq:
3669 iounmap(dispc.base); 3716 iounmap(dispc.base);
3670fail0: 3717err_ioremap:
3718 clk_put(dispc.dss_clk);
3719err_get_clk:
3671 return r; 3720 return r;
3672} 3721}
3673 3722
3674static int omap_dispchw_remove(struct platform_device *pdev) 3723static int omap_dispchw_remove(struct platform_device *pdev)
3675{ 3724{
3725 pm_runtime_disable(&pdev->dev);
3726
3727 clk_put(dispc.dss_clk);
3728
3676 free_irq(dispc.irq, dispc.pdev); 3729 free_irq(dispc.irq, dispc.pdev);
3677 iounmap(dispc.base); 3730 iounmap(dispc.base);
3678 return 0; 3731 return 0;
3679} 3732}
3680 3733
3734static int dispc_runtime_suspend(struct device *dev)
3735{
3736 dispc_save_context();
3737 clk_disable(dispc.dss_clk);
3738 dss_runtime_put();
3739
3740 return 0;
3741}
3742
3743static int dispc_runtime_resume(struct device *dev)
3744{
3745 int r;
3746
3747 r = dss_runtime_get();
3748 if (r < 0)
3749 return r;
3750
3751 clk_enable(dispc.dss_clk);
3752 dispc_restore_context();
3753
3754 return 0;
3755}
3756
3757static const struct dev_pm_ops dispc_pm_ops = {
3758 .runtime_suspend = dispc_runtime_suspend,
3759 .runtime_resume = dispc_runtime_resume,
3760};
3761
3681static struct platform_driver omap_dispchw_driver = { 3762static struct platform_driver omap_dispchw_driver = {
3682 .probe = omap_dispchw_probe, 3763 .probe = omap_dispchw_probe,
3683 .remove = omap_dispchw_remove, 3764 .remove = omap_dispchw_remove,
3684 .driver = { 3765 .driver = {
3685 .name = "omapdss_dispc", 3766 .name = "omapdss_dispc",
3686 .owner = THIS_MODULE, 3767 .owner = THIS_MODULE,
3768 .pm = &dispc_pm_ops,
3687 }, 3769 },
3688}; 3770};
3689 3771
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index c2dfc8c50057..94495e45ec5a 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -29,6 +29,7 @@
29 29
30#include <video/omapdss.h> 30#include <video/omapdss.h>
31#include "dss.h" 31#include "dss.h"
32#include "dss_features.h"
32 33
33static ssize_t display_enabled_show(struct device *dev, 34static ssize_t display_enabled_show(struct device *dev,
34 struct device_attribute *attr, char *buf) 35 struct device_attribute *attr, char *buf)
@@ -65,48 +66,6 @@ static ssize_t display_enabled_store(struct device *dev,
65 return size; 66 return size;
66} 67}
67 68
68static ssize_t display_upd_mode_show(struct device *dev,
69 struct device_attribute *attr, char *buf)
70{
71 struct omap_dss_device *dssdev = to_dss_device(dev);
72 enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
73 if (dssdev->driver->get_update_mode)
74 mode = dssdev->driver->get_update_mode(dssdev);
75 return snprintf(buf, PAGE_SIZE, "%d\n", mode);
76}
77
78static ssize_t display_upd_mode_store(struct device *dev,
79 struct device_attribute *attr,
80 const char *buf, size_t size)
81{
82 struct omap_dss_device *dssdev = to_dss_device(dev);
83 int val, r;
84 enum omap_dss_update_mode mode;
85
86 if (!dssdev->driver->set_update_mode)
87 return -EINVAL;
88
89 r = kstrtoint(buf, 0, &val);
90 if (r)
91 return r;
92
93 switch (val) {
94 case OMAP_DSS_UPDATE_DISABLED:
95 case OMAP_DSS_UPDATE_AUTO:
96 case OMAP_DSS_UPDATE_MANUAL:
97 mode = (enum omap_dss_update_mode)val;
98 break;
99 default:
100 return -EINVAL;
101 }
102
103 r = dssdev->driver->set_update_mode(dssdev, mode);
104 if (r)
105 return r;
106
107 return size;
108}
109
110static ssize_t display_tear_show(struct device *dev, 69static ssize_t display_tear_show(struct device *dev,
111 struct device_attribute *attr, char *buf) 70 struct device_attribute *attr, char *buf)
112{ 71{
@@ -294,8 +253,6 @@ static ssize_t display_wss_store(struct device *dev,
294 253
295static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, 254static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
296 display_enabled_show, display_enabled_store); 255 display_enabled_show, display_enabled_store);
297static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR,
298 display_upd_mode_show, display_upd_mode_store);
299static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, 256static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
300 display_tear_show, display_tear_store); 257 display_tear_show, display_tear_store);
301static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR, 258static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
@@ -309,7 +266,6 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
309 266
310static struct device_attribute *display_sysfs_attrs[] = { 267static struct device_attribute *display_sysfs_attrs[] = {
311 &dev_attr_enabled, 268 &dev_attr_enabled,
312 &dev_attr_update_mode,
313 &dev_attr_tear_elim, 269 &dev_attr_tear_elim,
314 &dev_attr_timings, 270 &dev_attr_timings,
315 &dev_attr_rotate, 271 &dev_attr_rotate,
@@ -327,16 +283,13 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
327EXPORT_SYMBOL(omapdss_default_get_resolution); 283EXPORT_SYMBOL(omapdss_default_get_resolution);
328 284
329void default_get_overlay_fifo_thresholds(enum omap_plane plane, 285void default_get_overlay_fifo_thresholds(enum omap_plane plane,
330 u32 fifo_size, enum omap_burst_size *burst_size, 286 u32 fifo_size, u32 burst_size,
331 u32 *fifo_low, u32 *fifo_high) 287 u32 *fifo_low, u32 *fifo_high)
332{ 288{
333 unsigned burst_size_bytes; 289 unsigned buf_unit = dss_feat_get_buffer_size_unit();
334
335 *burst_size = OMAP_DSS_BURST_16x32;
336 burst_size_bytes = 16 * 32 / 8;
337 290
338 *fifo_high = fifo_size - 1; 291 *fifo_high = fifo_size - buf_unit;
339 *fifo_low = fifo_size - burst_size_bytes; 292 *fifo_low = fifo_size - burst_size;
340} 293}
341 294
342int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) 295int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index ff6bd30132df..f053b180ecd7 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -23,7 +23,6 @@
23#define DSS_SUBSYS_NAME "DPI" 23#define DSS_SUBSYS_NAME "DPI"
24 24
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/clk.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <linux/err.h> 27#include <linux/err.h>
29#include <linux/errno.h> 28#include <linux/errno.h>
@@ -130,8 +129,6 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
130 bool is_tft; 129 bool is_tft;
131 int r = 0; 130 int r = 0;
132 131
133 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
134
135 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 132 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
136 dssdev->panel.acbi, dssdev->panel.acb); 133 dssdev->panel.acbi, dssdev->panel.acb);
137 134
@@ -144,7 +141,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, 141 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
145 &fck, &lck_div, &pck_div); 142 &fck, &lck_div, &pck_div);
146 if (r) 143 if (r)
147 goto err0; 144 return r;
148 145
149 pck = fck / lck_div / pck_div / 1000; 146 pck = fck / lck_div / pck_div / 1000;
150 147
@@ -158,12 +155,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
158 155
159 dispc_set_lcd_timings(dssdev->manager->id, t); 156 dispc_set_lcd_timings(dssdev->manager->id, t);
160 157
161err0: 158 return 0;
162 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
163 return r;
164} 159}
165 160
166static int dpi_basic_init(struct omap_dss_device *dssdev) 161static void dpi_basic_init(struct omap_dss_device *dssdev)
167{ 162{
168 bool is_tft; 163 bool is_tft;
169 164
@@ -175,8 +170,6 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
175 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN); 170 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
176 dispc_set_tft_data_lines(dssdev->manager->id, 171 dispc_set_tft_data_lines(dssdev->manager->id,
177 dssdev->phy.dpi.data_lines); 172 dssdev->phy.dpi.data_lines);
178
179 return 0;
180} 173}
181 174
182int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 175int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
@@ -186,31 +179,38 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
186 r = omap_dss_start_device(dssdev); 179 r = omap_dss_start_device(dssdev);
187 if (r) { 180 if (r) {
188 DSSERR("failed to start device\n"); 181 DSSERR("failed to start device\n");
189 goto err0; 182 goto err_start_dev;
190 } 183 }
191 184
192 if (cpu_is_omap34xx()) { 185 if (cpu_is_omap34xx()) {
193 r = regulator_enable(dpi.vdds_dsi_reg); 186 r = regulator_enable(dpi.vdds_dsi_reg);
194 if (r) 187 if (r)
195 goto err1; 188 goto err_reg_enable;
196 } 189 }
197 190
198 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 191 r = dss_runtime_get();
192 if (r)
193 goto err_get_dss;
199 194
200 r = dpi_basic_init(dssdev); 195 r = dispc_runtime_get();
201 if (r) 196 if (r)
202 goto err2; 197 goto err_get_dispc;
198
199 dpi_basic_init(dssdev);
203 200
204 if (dpi_use_dsi_pll(dssdev)) { 201 if (dpi_use_dsi_pll(dssdev)) {
205 dss_clk_enable(DSS_CLK_SYSCK); 202 r = dsi_runtime_get(dpi.dsidev);
203 if (r)
204 goto err_get_dsi;
205
206 r = dsi_pll_init(dpi.dsidev, 0, 1); 206 r = dsi_pll_init(dpi.dsidev, 0, 1);
207 if (r) 207 if (r)
208 goto err3; 208 goto err_dsi_pll_init;
209 } 209 }
210 210
211 r = dpi_set_mode(dssdev); 211 r = dpi_set_mode(dssdev);
212 if (r) 212 if (r)
213 goto err4; 213 goto err_set_mode;
214 214
215 mdelay(2); 215 mdelay(2);
216 216
@@ -218,19 +218,22 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
218 218
219 return 0; 219 return 0;
220 220
221err4: 221err_set_mode:
222 if (dpi_use_dsi_pll(dssdev)) 222 if (dpi_use_dsi_pll(dssdev))
223 dsi_pll_uninit(dpi.dsidev, true); 223 dsi_pll_uninit(dpi.dsidev, true);
224err3: 224err_dsi_pll_init:
225 if (dpi_use_dsi_pll(dssdev)) 225 if (dpi_use_dsi_pll(dssdev))
226 dss_clk_disable(DSS_CLK_SYSCK); 226 dsi_runtime_put(dpi.dsidev);
227err2: 227err_get_dsi:
228 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 228 dispc_runtime_put();
229err_get_dispc:
230 dss_runtime_put();
231err_get_dss:
229 if (cpu_is_omap34xx()) 232 if (cpu_is_omap34xx())
230 regulator_disable(dpi.vdds_dsi_reg); 233 regulator_disable(dpi.vdds_dsi_reg);
231err1: 234err_reg_enable:
232 omap_dss_stop_device(dssdev); 235 omap_dss_stop_device(dssdev);
233err0: 236err_start_dev:
234 return r; 237 return r;
235} 238}
236EXPORT_SYMBOL(omapdss_dpi_display_enable); 239EXPORT_SYMBOL(omapdss_dpi_display_enable);
@@ -242,10 +245,11 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
242 if (dpi_use_dsi_pll(dssdev)) { 245 if (dpi_use_dsi_pll(dssdev)) {
243 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 246 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
244 dsi_pll_uninit(dpi.dsidev, true); 247 dsi_pll_uninit(dpi.dsidev, true);
245 dss_clk_disable(DSS_CLK_SYSCK); 248 dsi_runtime_put(dpi.dsidev);
246 } 249 }
247 250
248 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 251 dispc_runtime_put();
252 dss_runtime_put();
249 253
250 if (cpu_is_omap34xx()) 254 if (cpu_is_omap34xx())
251 regulator_disable(dpi.vdds_dsi_reg); 255 regulator_disable(dpi.vdds_dsi_reg);
@@ -257,11 +261,26 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
257void dpi_set_timings(struct omap_dss_device *dssdev, 261void dpi_set_timings(struct omap_dss_device *dssdev,
258 struct omap_video_timings *timings) 262 struct omap_video_timings *timings)
259{ 263{
264 int r;
265
260 DSSDBG("dpi_set_timings\n"); 266 DSSDBG("dpi_set_timings\n");
261 dssdev->panel.timings = *timings; 267 dssdev->panel.timings = *timings;
262 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 268 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
269 r = dss_runtime_get();
270 if (r)
271 return;
272
273 r = dispc_runtime_get();
274 if (r) {
275 dss_runtime_put();
276 return;
277 }
278
263 dpi_set_mode(dssdev); 279 dpi_set_mode(dssdev);
264 dispc_go(dssdev->manager->id); 280 dispc_go(dssdev->manager->id);
281
282 dispc_runtime_put();
283 dss_runtime_put();
265 } 284 }
266} 285}
267EXPORT_SYMBOL(dpi_set_timings); 286EXPORT_SYMBOL(dpi_set_timings);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 345757cfcbee..7adbbeb84334 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -36,6 +36,7 @@
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/pm_runtime.h>
39 40
40#include <video/omapdss.h> 41#include <video/omapdss.h>
41#include <plat/clock.h> 42#include <plat/clock.h>
@@ -267,8 +268,12 @@ struct dsi_isr_tables {
267struct dsi_data { 268struct dsi_data {
268 struct platform_device *pdev; 269 struct platform_device *pdev;
269 void __iomem *base; 270 void __iomem *base;
271
270 int irq; 272 int irq;
271 273
274 struct clk *dss_clk;
275 struct clk *sys_clk;
276
272 void (*dsi_mux_pads)(bool enable); 277 void (*dsi_mux_pads)(bool enable);
273 278
274 struct dsi_clock_info current_cinfo; 279 struct dsi_clock_info current_cinfo;
@@ -389,15 +394,6 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev,
389 return __raw_readl(dsi->base + idx.idx); 394 return __raw_readl(dsi->base + idx.idx);
390} 395}
391 396
392
393void dsi_save_context(void)
394{
395}
396
397void dsi_restore_context(void)
398{
399}
400
401void dsi_bus_lock(struct omap_dss_device *dssdev) 397void dsi_bus_lock(struct omap_dss_device *dssdev)
402{ 398{
403 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 399 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -493,9 +489,18 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
493 total_bytes * 1000 / total_us); 489 total_bytes * 1000 / total_us);
494} 490}
495#else 491#else
496#define dsi_perf_mark_setup(x) 492static inline void dsi_perf_mark_setup(struct platform_device *dsidev)
497#define dsi_perf_mark_start(x) 493{
498#define dsi_perf_show(x, y) 494}
495
496static inline void dsi_perf_mark_start(struct platform_device *dsidev)
497{
498}
499
500static inline void dsi_perf_show(struct platform_device *dsidev,
501 const char *name)
502{
503}
499#endif 504#endif
500 505
501static void print_irq_status(u32 status) 506static void print_irq_status(u32 status)
@@ -1039,13 +1044,27 @@ static u32 dsi_get_errors(struct platform_device *dsidev)
1039 return e; 1044 return e;
1040} 1045}
1041 1046
1042/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */ 1047int dsi_runtime_get(struct platform_device *dsidev)
1043static inline void enable_clocks(bool enable)
1044{ 1048{
1045 if (enable) 1049 int r;
1046 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1050 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1047 else 1051
1048 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1052 DSSDBG("dsi_runtime_get\n");
1053
1054 r = pm_runtime_get_sync(&dsi->pdev->dev);
1055 WARN_ON(r < 0);
1056 return r < 0 ? r : 0;
1057}
1058
1059void dsi_runtime_put(struct platform_device *dsidev)
1060{
1061 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1062 int r;
1063
1064 DSSDBG("dsi_runtime_put\n");
1065
1066 r = pm_runtime_put(&dsi->pdev->dev);
1067 WARN_ON(r < 0);
1049} 1068}
1050 1069
1051/* source clock for DSI PLL. this could also be PCLKFREE */ 1070/* source clock for DSI PLL. this could also be PCLKFREE */
@@ -1055,9 +1074,9 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1055 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1074 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1056 1075
1057 if (enable) 1076 if (enable)
1058 dss_clk_enable(DSS_CLK_SYSCK); 1077 clk_enable(dsi->sys_clk);
1059 else 1078 else
1060 dss_clk_disable(DSS_CLK_SYSCK); 1079 clk_disable(dsi->sys_clk);
1061 1080
1062 if (enable && dsi->pll_locked) { 1081 if (enable && dsi->pll_locked) {
1063 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) 1082 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
@@ -1150,10 +1169,11 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
1150{ 1169{
1151 unsigned long r; 1170 unsigned long r;
1152 int dsi_module = dsi_get_dsidev_id(dsidev); 1171 int dsi_module = dsi_get_dsidev_id(dsidev);
1172 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1153 1173
1154 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) { 1174 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) {
1155 /* DSI FCLK source is DSS_CLK_FCK */ 1175 /* DSI FCLK source is DSS_CLK_FCK */
1156 r = dss_clk_get_rate(DSS_CLK_FCK); 1176 r = clk_get_rate(dsi->dss_clk);
1157 } else { 1177 } else {
1158 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ 1178 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
1159 r = dsi_get_pll_hsdiv_dsi_rate(dsidev); 1179 r = dsi_get_pll_hsdiv_dsi_rate(dsidev);
@@ -1262,7 +1282,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1262 return -EINVAL; 1282 return -EINVAL;
1263 1283
1264 if (cinfo->use_sys_clk) { 1284 if (cinfo->use_sys_clk) {
1265 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK); 1285 cinfo->clkin = clk_get_rate(dsi->sys_clk);
1266 /* XXX it is unclear if highfreq should be used 1286 /* XXX it is unclear if highfreq should be used
1267 * with DSS_SYS_CLK source also */ 1287 * with DSS_SYS_CLK source also */
1268 cinfo->highfreq = 0; 1288 cinfo->highfreq = 0;
@@ -1311,7 +1331,7 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
1311 int match = 0; 1331 int match = 0;
1312 unsigned long dss_sys_clk, max_dss_fck; 1332 unsigned long dss_sys_clk, max_dss_fck;
1313 1333
1314 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK); 1334 dss_sys_clk = clk_get_rate(dsi->sys_clk);
1315 1335
1316 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1336 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1317 1337
@@ -1601,7 +1621,6 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1601 dsi->vdds_dsi_reg = vdds_dsi; 1621 dsi->vdds_dsi_reg = vdds_dsi;
1602 } 1622 }
1603 1623
1604 enable_clocks(1);
1605 dsi_enable_pll_clock(dsidev, 1); 1624 dsi_enable_pll_clock(dsidev, 1);
1606 /* 1625 /*
1607 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. 1626 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
@@ -1653,7 +1672,6 @@ err1:
1653 } 1672 }
1654err0: 1673err0:
1655 dsi_disable_scp_clk(dsidev); 1674 dsi_disable_scp_clk(dsidev);
1656 enable_clocks(0);
1657 dsi_enable_pll_clock(dsidev, 0); 1675 dsi_enable_pll_clock(dsidev, 0);
1658 return r; 1676 return r;
1659} 1677}
@@ -1671,7 +1689,6 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
1671 } 1689 }
1672 1690
1673 dsi_disable_scp_clk(dsidev); 1691 dsi_disable_scp_clk(dsidev);
1674 enable_clocks(0);
1675 dsi_enable_pll_clock(dsidev, 0); 1692 dsi_enable_pll_clock(dsidev, 0);
1676 1693
1677 DSSDBG("PLL uninit done\n"); 1694 DSSDBG("PLL uninit done\n");
@@ -1688,7 +1705,8 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1688 dispc_clk_src = dss_get_dispc_clk_source(); 1705 dispc_clk_src = dss_get_dispc_clk_source();
1689 dsi_clk_src = dss_get_dsi_clk_source(dsi_module); 1706 dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
1690 1707
1691 enable_clocks(1); 1708 if (dsi_runtime_get(dsidev))
1709 return;
1692 1710
1693 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); 1711 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
1694 1712
@@ -1731,7 +1749,7 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1731 1749
1732 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); 1750 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk);
1733 1751
1734 enable_clocks(0); 1752 dsi_runtime_put(dsidev);
1735} 1753}
1736 1754
1737void dsi_dump_clocks(struct seq_file *s) 1755void dsi_dump_clocks(struct seq_file *s)
@@ -1873,7 +1891,8 @@ static void dsi_dump_dsidev_regs(struct platform_device *dsidev,
1873{ 1891{
1874#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r)) 1892#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r))
1875 1893
1876 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1894 if (dsi_runtime_get(dsidev))
1895 return;
1877 dsi_enable_scp_clk(dsidev); 1896 dsi_enable_scp_clk(dsidev);
1878 1897
1879 DUMPREG(DSI_REVISION); 1898 DUMPREG(DSI_REVISION);
@@ -1947,7 +1966,7 @@ static void dsi_dump_dsidev_regs(struct platform_device *dsidev,
1947 DUMPREG(DSI_PLL_CONFIGURATION2); 1966 DUMPREG(DSI_PLL_CONFIGURATION2);
1948 1967
1949 dsi_disable_scp_clk(dsidev); 1968 dsi_disable_scp_clk(dsidev);
1950 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1969 dsi_runtime_put(dsidev);
1951#undef DUMPREG 1970#undef DUMPREG
1952} 1971}
1953 1972
@@ -2463,28 +2482,6 @@ static void dsi_cio_uninit(struct platform_device *dsidev)
2463 dsi->dsi_mux_pads(false); 2482 dsi->dsi_mux_pads(false);
2464} 2483}
2465 2484
2466static int _dsi_wait_reset(struct platform_device *dsidev)
2467{
2468 int t = 0;
2469
2470 while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
2471 if (++t > 5) {
2472 DSSERR("soft reset failed\n");
2473 return -ENODEV;
2474 }
2475 udelay(1);
2476 }
2477
2478 return 0;
2479}
2480
2481static int _dsi_reset(struct platform_device *dsidev)
2482{
2483 /* Soft reset */
2484 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
2485 return _dsi_wait_reset(dsidev);
2486}
2487
2488static void dsi_config_tx_fifo(struct platform_device *dsidev, 2485static void dsi_config_tx_fifo(struct platform_device *dsidev,
2489 enum fifo_size size1, enum fifo_size size2, 2486 enum fifo_size size1, enum fifo_size size2,
2490 enum fifo_size size3, enum fifo_size size4) 2487 enum fifo_size size3, enum fifo_size size4)
@@ -3386,6 +3383,10 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
3386 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion, 3383 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
3387 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); 3384 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3388 3385
3386 /* Reset LANEx_ULPS_SIG2 */
3387 REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2),
3388 7, 5);
3389
3389 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS); 3390 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
3390 3391
3391 dsi_if_enable(dsidev, false); 3392 dsi_if_enable(dsidev, false);
@@ -4198,22 +4199,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4198 dsi_pll_uninit(dsidev, disconnect_lanes); 4199 dsi_pll_uninit(dsidev, disconnect_lanes);
4199} 4200}
4200 4201
4201static int dsi_core_init(struct platform_device *dsidev)
4202{
4203 /* Autoidle */
4204 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0);
4205
4206 /* ENWAKEUP */
4207 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2);
4208
4209 /* SIDLEMODE smart-idle */
4210 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3);
4211
4212 _dsi_initialize_irq(dsidev);
4213
4214 return 0;
4215}
4216
4217int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) 4202int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4218{ 4203{
4219 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4204 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4229,37 +4214,37 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4229 r = omap_dss_start_device(dssdev); 4214 r = omap_dss_start_device(dssdev);
4230 if (r) { 4215 if (r) {
4231 DSSERR("failed to start device\n"); 4216 DSSERR("failed to start device\n");
4232 goto err0; 4217 goto err_start_dev;
4233 } 4218 }
4234 4219
4235 enable_clocks(1); 4220 r = dsi_runtime_get(dsidev);
4236 dsi_enable_pll_clock(dsidev, 1);
4237
4238 r = _dsi_reset(dsidev);
4239 if (r) 4221 if (r)
4240 goto err1; 4222 goto err_get_dsi;
4241 4223
4242 dsi_core_init(dsidev); 4224 dsi_enable_pll_clock(dsidev, 1);
4225
4226 _dsi_initialize_irq(dsidev);
4243 4227
4244 r = dsi_display_init_dispc(dssdev); 4228 r = dsi_display_init_dispc(dssdev);
4245 if (r) 4229 if (r)
4246 goto err1; 4230 goto err_init_dispc;
4247 4231
4248 r = dsi_display_init_dsi(dssdev); 4232 r = dsi_display_init_dsi(dssdev);
4249 if (r) 4233 if (r)
4250 goto err2; 4234 goto err_init_dsi;
4251 4235
4252 mutex_unlock(&dsi->lock); 4236 mutex_unlock(&dsi->lock);
4253 4237
4254 return 0; 4238 return 0;
4255 4239
4256err2: 4240err_init_dsi:
4257 dsi_display_uninit_dispc(dssdev); 4241 dsi_display_uninit_dispc(dssdev);
4258err1: 4242err_init_dispc:
4259 enable_clocks(0);
4260 dsi_enable_pll_clock(dsidev, 0); 4243 dsi_enable_pll_clock(dsidev, 0);
4244 dsi_runtime_put(dsidev);
4245err_get_dsi:
4261 omap_dss_stop_device(dssdev); 4246 omap_dss_stop_device(dssdev);
4262err0: 4247err_start_dev:
4263 mutex_unlock(&dsi->lock); 4248 mutex_unlock(&dsi->lock);
4264 DSSDBG("dsi_display_enable FAILED\n"); 4249 DSSDBG("dsi_display_enable FAILED\n");
4265 return r; 4250 return r;
@@ -4278,11 +4263,16 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
4278 4263
4279 mutex_lock(&dsi->lock); 4264 mutex_lock(&dsi->lock);
4280 4265
4266 dsi_sync_vc(dsidev, 0);
4267 dsi_sync_vc(dsidev, 1);
4268 dsi_sync_vc(dsidev, 2);
4269 dsi_sync_vc(dsidev, 3);
4270
4281 dsi_display_uninit_dispc(dssdev); 4271 dsi_display_uninit_dispc(dssdev);
4282 4272
4283 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps); 4273 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
4284 4274
4285 enable_clocks(0); 4275 dsi_runtime_put(dsidev);
4286 dsi_enable_pll_clock(dsidev, 0); 4276 dsi_enable_pll_clock(dsidev, 0);
4287 4277
4288 omap_dss_stop_device(dssdev); 4278 omap_dss_stop_device(dssdev);
@@ -4302,16 +4292,11 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
4302EXPORT_SYMBOL(omapdss_dsi_enable_te); 4292EXPORT_SYMBOL(omapdss_dsi_enable_te);
4303 4293
4304void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 4294void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
4305 u32 fifo_size, enum omap_burst_size *burst_size, 4295 u32 fifo_size, u32 burst_size,
4306 u32 *fifo_low, u32 *fifo_high) 4296 u32 *fifo_low, u32 *fifo_high)
4307{ 4297{
4308 unsigned burst_size_bytes; 4298 *fifo_high = fifo_size - burst_size;
4309 4299 *fifo_low = fifo_size - burst_size * 2;
4310 *burst_size = OMAP_DSS_BURST_16x32;
4311 burst_size_bytes = 16 * 32 / 8;
4312
4313 *fifo_high = fifo_size - burst_size_bytes;
4314 *fifo_low = fifo_size - burst_size_bytes * 2;
4315} 4300}
4316 4301
4317int dsi_init_display(struct omap_dss_device *dssdev) 4302int dsi_init_display(struct omap_dss_device *dssdev)
@@ -4437,7 +4422,47 @@ static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
4437 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); 4422 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
4438} 4423}
4439 4424
4440static int dsi_init(struct platform_device *dsidev) 4425static int dsi_get_clocks(struct platform_device *dsidev)
4426{
4427 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4428 struct clk *clk;
4429
4430 clk = clk_get(&dsidev->dev, "fck");
4431 if (IS_ERR(clk)) {
4432 DSSERR("can't get fck\n");
4433 return PTR_ERR(clk);
4434 }
4435
4436 dsi->dss_clk = clk;
4437
4438 if (cpu_is_omap34xx() || cpu_is_omap3630())
4439 clk = clk_get(&dsidev->dev, "dss2_alwon_fck");
4440 else
4441 clk = clk_get(&dsidev->dev, "sys_clk");
4442 if (IS_ERR(clk)) {
4443 DSSERR("can't get sys_clk\n");
4444 clk_put(dsi->dss_clk);
4445 dsi->dss_clk = NULL;
4446 return PTR_ERR(clk);
4447 }
4448
4449 dsi->sys_clk = clk;
4450
4451 return 0;
4452}
4453
4454static void dsi_put_clocks(struct platform_device *dsidev)
4455{
4456 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4457
4458 if (dsi->dss_clk)
4459 clk_put(dsi->dss_clk);
4460 if (dsi->sys_clk)
4461 clk_put(dsi->sys_clk);
4462}
4463
4464/* DSI1 HW IP initialisation */
4465static int omap_dsi1hw_probe(struct platform_device *dsidev)
4441{ 4466{
4442 struct omap_display_platform_data *dss_plat_data; 4467 struct omap_display_platform_data *dss_plat_data;
4443 struct omap_dss_board_info *board_info; 4468 struct omap_dss_board_info *board_info;
@@ -4449,7 +4474,7 @@ static int dsi_init(struct platform_device *dsidev)
4449 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 4474 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
4450 if (!dsi) { 4475 if (!dsi) {
4451 r = -ENOMEM; 4476 r = -ENOMEM;
4452 goto err0; 4477 goto err_alloc;
4453 } 4478 }
4454 4479
4455 dsi->pdev = dsidev; 4480 dsi->pdev = dsidev;
@@ -4472,6 +4497,12 @@ static int dsi_init(struct platform_device *dsidev)
4472 mutex_init(&dsi->lock); 4497 mutex_init(&dsi->lock);
4473 sema_init(&dsi->bus_lock, 1); 4498 sema_init(&dsi->bus_lock, 1);
4474 4499
4500 r = dsi_get_clocks(dsidev);
4501 if (r)
4502 goto err_get_clk;
4503
4504 pm_runtime_enable(&dsidev->dev);
4505
4475 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, 4506 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
4476 dsi_framedone_timeout_work_callback); 4507 dsi_framedone_timeout_work_callback);
4477 4508
@@ -4484,26 +4515,26 @@ static int dsi_init(struct platform_device *dsidev)
4484 if (!dsi_mem) { 4515 if (!dsi_mem) {
4485 DSSERR("can't get IORESOURCE_MEM DSI\n"); 4516 DSSERR("can't get IORESOURCE_MEM DSI\n");
4486 r = -EINVAL; 4517 r = -EINVAL;
4487 goto err1; 4518 goto err_ioremap;
4488 } 4519 }
4489 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); 4520 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem));
4490 if (!dsi->base) { 4521 if (!dsi->base) {
4491 DSSERR("can't ioremap DSI\n"); 4522 DSSERR("can't ioremap DSI\n");
4492 r = -ENOMEM; 4523 r = -ENOMEM;
4493 goto err1; 4524 goto err_ioremap;
4494 } 4525 }
4495 dsi->irq = platform_get_irq(dsi->pdev, 0); 4526 dsi->irq = platform_get_irq(dsi->pdev, 0);
4496 if (dsi->irq < 0) { 4527 if (dsi->irq < 0) {
4497 DSSERR("platform_get_irq failed\n"); 4528 DSSERR("platform_get_irq failed\n");
4498 r = -ENODEV; 4529 r = -ENODEV;
4499 goto err2; 4530 goto err_get_irq;
4500 } 4531 }
4501 4532
4502 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, 4533 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED,
4503 dev_name(&dsidev->dev), dsi->pdev); 4534 dev_name(&dsidev->dev), dsi->pdev);
4504 if (r < 0) { 4535 if (r < 0) {
4505 DSSERR("request_irq failed\n"); 4536 DSSERR("request_irq failed\n");
4506 goto err2; 4537 goto err_get_irq;
4507 } 4538 }
4508 4539
4509 /* DSI VCs initialization */ 4540 /* DSI VCs initialization */
@@ -4515,7 +4546,9 @@ static int dsi_init(struct platform_device *dsidev)
4515 4546
4516 dsi_calc_clock_param_ranges(dsidev); 4547 dsi_calc_clock_param_ranges(dsidev);
4517 4548
4518 enable_clocks(1); 4549 r = dsi_runtime_get(dsidev);
4550 if (r)
4551 goto err_get_dsi;
4519 4552
4520 rev = dsi_read_reg(dsidev, DSI_REVISION); 4553 rev = dsi_read_reg(dsidev, DSI_REVISION);
4521 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", 4554 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
@@ -4523,21 +4556,32 @@ static int dsi_init(struct platform_device *dsidev)
4523 4556
4524 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev); 4557 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
4525 4558
4526 enable_clocks(0); 4559 dsi_runtime_put(dsidev);
4527 4560
4528 return 0; 4561 return 0;
4529err2: 4562
4563err_get_dsi:
4564 free_irq(dsi->irq, dsi->pdev);
4565err_get_irq:
4530 iounmap(dsi->base); 4566 iounmap(dsi->base);
4531err1: 4567err_ioremap:
4568 pm_runtime_disable(&dsidev->dev);
4569err_get_clk:
4532 kfree(dsi); 4570 kfree(dsi);
4533err0: 4571err_alloc:
4534 return r; 4572 return r;
4535} 4573}
4536 4574
4537static void dsi_exit(struct platform_device *dsidev) 4575static int omap_dsi1hw_remove(struct platform_device *dsidev)
4538{ 4576{
4539 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4577 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4540 4578
4579 WARN_ON(dsi->scp_clk_refcount > 0);
4580
4581 pm_runtime_disable(&dsidev->dev);
4582
4583 dsi_put_clocks(dsidev);
4584
4541 if (dsi->vdds_dsi_reg != NULL) { 4585 if (dsi->vdds_dsi_reg != NULL) {
4542 if (dsi->vdds_dsi_enabled) { 4586 if (dsi->vdds_dsi_enabled) {
4543 regulator_disable(dsi->vdds_dsi_reg); 4587 regulator_disable(dsi->vdds_dsi_reg);
@@ -4553,38 +4597,56 @@ static void dsi_exit(struct platform_device *dsidev)
4553 4597
4554 kfree(dsi); 4598 kfree(dsi);
4555 4599
4556 DSSDBG("omap_dsi_exit\n"); 4600 return 0;
4557} 4601}
4558 4602
4559/* DSI1 HW IP initialisation */ 4603static int dsi_runtime_suspend(struct device *dev)
4560static int omap_dsi1hw_probe(struct platform_device *dsidev)
4561{ 4604{
4562 int r; 4605 struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev));
4563 4606
4564 r = dsi_init(dsidev); 4607 clk_disable(dsi->dss_clk);
4565 if (r) { 4608
4566 DSSERR("Failed to initialize DSI\n"); 4609 dispc_runtime_put();
4567 goto err_dsi; 4610 dss_runtime_put();
4568 } 4611
4569err_dsi: 4612 return 0;
4570 return r;
4571} 4613}
4572 4614
4573static int omap_dsi1hw_remove(struct platform_device *dsidev) 4615static int dsi_runtime_resume(struct device *dev)
4574{ 4616{
4575 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4617 struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev));
4618 int r;
4619
4620 r = dss_runtime_get();
4621 if (r)
4622 goto err_get_dss;
4623
4624 r = dispc_runtime_get();
4625 if (r)
4626 goto err_get_dispc;
4627
4628 clk_enable(dsi->dss_clk);
4576 4629
4577 dsi_exit(dsidev);
4578 WARN_ON(dsi->scp_clk_refcount > 0);
4579 return 0; 4630 return 0;
4631
4632err_get_dispc:
4633 dss_runtime_put();
4634err_get_dss:
4635 return r;
4580} 4636}
4581 4637
4638static const struct dev_pm_ops dsi_pm_ops = {
4639 .runtime_suspend = dsi_runtime_suspend,
4640 .runtime_resume = dsi_runtime_resume,
4641};
4642
4582static struct platform_driver omap_dsi1hw_driver = { 4643static struct platform_driver omap_dsi1hw_driver = {
4583 .probe = omap_dsi1hw_probe, 4644 .probe = omap_dsi1hw_probe,
4584 .remove = omap_dsi1hw_remove, 4645 .remove = omap_dsi1hw_remove,
4585 .driver = { 4646 .driver = {
4586 .name = "omapdss_dsi1", 4647 .name = "omapdss_dsi1",
4587 .owner = THIS_MODULE, 4648 .owner = THIS_MODULE,
4649 .pm = &dsi_pm_ops,
4588 }, 4650 },
4589}; 4651};
4590 4652
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index d9489d5c4f08..0f9c3a6457a5 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -28,6 +28,8 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/platform_device.h>
32#include <linux/pm_runtime.h>
31 33
32#include <video/omapdss.h> 34#include <video/omapdss.h>
33#include <plat/clock.h> 35#include <plat/clock.h>
@@ -59,15 +61,9 @@ struct dss_reg {
59static struct { 61static struct {
60 struct platform_device *pdev; 62 struct platform_device *pdev;
61 void __iomem *base; 63 void __iomem *base;
62 int ctx_id;
63 64
64 struct clk *dpll4_m4_ck; 65 struct clk *dpll4_m4_ck;
65 struct clk *dss_ick; 66 struct clk *dss_clk;
66 struct clk *dss_fck;
67 struct clk *dss_sys_clk;
68 struct clk *dss_tv_fck;
69 struct clk *dss_video_fck;
70 unsigned num_clks_enabled;
71 67
72 unsigned long cache_req_pck; 68 unsigned long cache_req_pck;
73 unsigned long cache_prate; 69 unsigned long cache_prate;
@@ -78,6 +74,7 @@ static struct {
78 enum omap_dss_clk_source dispc_clk_source; 74 enum omap_dss_clk_source dispc_clk_source;
79 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; 75 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
80 76
77 bool ctx_valid;
81 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 78 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
82} dss; 79} dss;
83 80
@@ -87,13 +84,6 @@ static const char * const dss_generic_clk_source_names[] = {
87 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", 84 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
88}; 85};
89 86
90static void dss_clk_enable_all_no_ctx(void);
91static void dss_clk_disable_all_no_ctx(void);
92static void dss_clk_enable_no_ctx(enum dss_clock clks);
93static void dss_clk_disable_no_ctx(enum dss_clock clks);
94
95static int _omap_dss_wait_reset(void);
96
97static inline void dss_write_reg(const struct dss_reg idx, u32 val) 87static inline void dss_write_reg(const struct dss_reg idx, u32 val)
98{ 88{
99 __raw_writel(val, dss.base + idx.idx); 89 __raw_writel(val, dss.base + idx.idx);
@@ -109,12 +99,10 @@ static inline u32 dss_read_reg(const struct dss_reg idx)
109#define RR(reg) \ 99#define RR(reg) \
110 dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)]) 100 dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
111 101
112void dss_save_context(void) 102static void dss_save_context(void)
113{ 103{
114 if (cpu_is_omap24xx()) 104 DSSDBG("dss_save_context\n");
115 return;
116 105
117 SR(SYSCONFIG);
118 SR(CONTROL); 106 SR(CONTROL);
119 107
120 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & 108 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
@@ -122,14 +110,19 @@ void dss_save_context(void)
122 SR(SDI_CONTROL); 110 SR(SDI_CONTROL);
123 SR(PLL_CONTROL); 111 SR(PLL_CONTROL);
124 } 112 }
113
114 dss.ctx_valid = true;
115
116 DSSDBG("context saved\n");
125} 117}
126 118
127void dss_restore_context(void) 119static void dss_restore_context(void)
128{ 120{
129 if (_omap_dss_wait_reset()) 121 DSSDBG("dss_restore_context\n");
130 DSSERR("DSS not coming out of reset after sleep\n"); 122
123 if (!dss.ctx_valid)
124 return;
131 125
132 RR(SYSCONFIG);
133 RR(CONTROL); 126 RR(CONTROL);
134 127
135 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & 128 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
@@ -137,6 +130,8 @@ void dss_restore_context(void)
137 RR(SDI_CONTROL); 130 RR(SDI_CONTROL);
138 RR(PLL_CONTROL); 131 RR(PLL_CONTROL);
139 } 132 }
133
134 DSSDBG("context restored\n");
140} 135}
141 136
142#undef SR 137#undef SR
@@ -234,6 +229,7 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
234 return dss_generic_clk_source_names[clk_src]; 229 return dss_generic_clk_source_names[clk_src];
235} 230}
236 231
232
237void dss_dump_clocks(struct seq_file *s) 233void dss_dump_clocks(struct seq_file *s)
238{ 234{
239 unsigned long dpll4_ck_rate; 235 unsigned long dpll4_ck_rate;
@@ -241,13 +237,14 @@ void dss_dump_clocks(struct seq_file *s)
241 const char *fclk_name, *fclk_real_name; 237 const char *fclk_name, *fclk_real_name;
242 unsigned long fclk_rate; 238 unsigned long fclk_rate;
243 239
244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 240 if (dss_runtime_get())
241 return;
245 242
246 seq_printf(s, "- DSS -\n"); 243 seq_printf(s, "- DSS -\n");
247 244
248 fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK); 245 fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
249 fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK); 246 fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
250 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK); 247 fclk_rate = clk_get_rate(dss.dss_clk);
251 248
252 if (dss.dpll4_m4_ck) { 249 if (dss.dpll4_m4_ck) {
253 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 250 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
@@ -273,14 +270,15 @@ void dss_dump_clocks(struct seq_file *s)
273 fclk_rate); 270 fclk_rate);
274 } 271 }
275 272
276 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 273 dss_runtime_put();
277} 274}
278 275
279void dss_dump_regs(struct seq_file *s) 276void dss_dump_regs(struct seq_file *s)
280{ 277{
281#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 278#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
282 279
283 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 280 if (dss_runtime_get())
281 return;
284 282
285 DUMPREG(DSS_REVISION); 283 DUMPREG(DSS_REVISION);
286 DUMPREG(DSS_SYSCONFIG); 284 DUMPREG(DSS_SYSCONFIG);
@@ -294,7 +292,7 @@ void dss_dump_regs(struct seq_file *s)
294 DUMPREG(DSS_SDI_STATUS); 292 DUMPREG(DSS_SDI_STATUS);
295 } 293 }
296 294
297 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 295 dss_runtime_put();
298#undef DUMPREG 296#undef DUMPREG
299} 297}
300 298
@@ -437,7 +435,7 @@ int dss_calc_clock_rates(struct dss_clock_info *cinfo)
437 } else { 435 } else {
438 if (cinfo->fck_div != 0) 436 if (cinfo->fck_div != 0)
439 return -EINVAL; 437 return -EINVAL;
440 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK); 438 cinfo->fck = clk_get_rate(dss.dss_clk);
441 } 439 }
442 440
443 return 0; 441 return 0;
@@ -467,7 +465,7 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
467 465
468int dss_get_clock_div(struct dss_clock_info *cinfo) 466int dss_get_clock_div(struct dss_clock_info *cinfo)
469{ 467{
470 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK); 468 cinfo->fck = clk_get_rate(dss.dss_clk);
471 469
472 if (dss.dpll4_m4_ck) { 470 if (dss.dpll4_m4_ck) {
473 unsigned long prate; 471 unsigned long prate;
@@ -512,7 +510,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
512 510
513 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 511 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
514 512
515 fck = dss_clk_get_rate(DSS_CLK_FCK); 513 fck = clk_get_rate(dss.dss_clk);
516 if (req_pck == dss.cache_req_pck && 514 if (req_pck == dss.cache_req_pck &&
517 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 515 ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
518 dss.cache_dss_cinfo.fck == fck)) { 516 dss.cache_dss_cinfo.fck == fck)) {
@@ -539,7 +537,7 @@ retry:
539 if (dss.dpll4_m4_ck == NULL) { 537 if (dss.dpll4_m4_ck == NULL) {
540 struct dispc_clock_info cur_dispc; 538 struct dispc_clock_info cur_dispc;
541 /* XXX can we change the clock on omap2? */ 539 /* XXX can we change the clock on omap2? */
542 fck = dss_clk_get_rate(DSS_CLK_FCK); 540 fck = clk_get_rate(dss.dss_clk);
543 fck_div = 1; 541 fck_div = 1;
544 542
545 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 543 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -616,28 +614,6 @@ found:
616 return 0; 614 return 0;
617} 615}
618 616
619static int _omap_dss_wait_reset(void)
620{
621 int t = 0;
622
623 while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
624 if (++t > 1000) {
625 DSSERR("soft reset failed\n");
626 return -ENODEV;
627 }
628 udelay(1);
629 }
630
631 return 0;
632}
633
634static int _omap_dss_reset(void)
635{
636 /* Soft reset */
637 REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1);
638 return _omap_dss_wait_reset();
639}
640
641void dss_set_venc_output(enum omap_dss_venc_type type) 617void dss_set_venc_output(enum omap_dss_venc_type type)
642{ 618{
643 int l = 0; 619 int l = 0;
@@ -663,424 +639,88 @@ void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
663 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */ 639 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
664} 640}
665 641
666static int dss_init(void) 642static int dss_get_clocks(void)
667{ 643{
644 struct clk *clk;
668 int r; 645 int r;
669 u32 rev;
670 struct resource *dss_mem;
671 struct clk *dpll4_m4_ck;
672 646
673 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); 647 clk = clk_get(&dss.pdev->dev, "fck");
674 if (!dss_mem) { 648 if (IS_ERR(clk)) {
675 DSSERR("can't get IORESOURCE_MEM DSS\n"); 649 DSSERR("can't get clock fck\n");
676 r = -EINVAL; 650 r = PTR_ERR(clk);
677 goto fail0; 651 goto err;
678 }
679 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
680 if (!dss.base) {
681 DSSERR("can't ioremap DSS\n");
682 r = -ENOMEM;
683 goto fail0;
684 } 652 }
685 653
686 /* disable LCD and DIGIT output. This seems to fix the synclost 654 dss.dss_clk = clk;
687 * problem that we get, if the bootloader starts the DSS and
688 * the kernel resets it */
689 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
690
691#ifdef CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET
692 /* We need to wait here a bit, otherwise we sometimes start to
693 * get synclost errors, and after that only power cycle will
694 * restore DSS functionality. I have no idea why this happens.
695 * And we have to wait _before_ resetting the DSS, but after
696 * enabling clocks.
697 *
698 * This bug was at least present on OMAP3430. It's unknown
699 * if it happens on OMAP2 or OMAP3630.
700 */
701 msleep(50);
702#endif
703
704 _omap_dss_reset();
705 655
706 /* autoidle */
707 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
708
709 /* Select DPLL */
710 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
711
712#ifdef CONFIG_OMAP2_DSS_VENC
713 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
714 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
715 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
716#endif
717 if (cpu_is_omap34xx()) { 656 if (cpu_is_omap34xx()) {
718 dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 657 clk = clk_get(NULL, "dpll4_m4_ck");
719 if (IS_ERR(dpll4_m4_ck)) { 658 if (IS_ERR(clk)) {
720 DSSERR("Failed to get dpll4_m4_ck\n"); 659 DSSERR("Failed to get dpll4_m4_ck\n");
721 r = PTR_ERR(dpll4_m4_ck); 660 r = PTR_ERR(clk);
722 goto fail1; 661 goto err;
723 } 662 }
724 } else if (cpu_is_omap44xx()) { 663 } else if (cpu_is_omap44xx()) {
725 dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck"); 664 clk = clk_get(NULL, "dpll_per_m5x2_ck");
726 if (IS_ERR(dpll4_m4_ck)) { 665 if (IS_ERR(clk)) {
727 DSSERR("Failed to get dpll4_m4_ck\n"); 666 DSSERR("Failed to get dpll_per_m5x2_ck\n");
728 r = PTR_ERR(dpll4_m4_ck); 667 r = PTR_ERR(clk);
729 goto fail1; 668 goto err;
730 } 669 }
731 } else { /* omap24xx */ 670 } else { /* omap24xx */
732 dpll4_m4_ck = NULL; 671 clk = NULL;
733 } 672 }
734 673
735 dss.dpll4_m4_ck = dpll4_m4_ck; 674 dss.dpll4_m4_ck = clk;
736
737 dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
738 dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
739 dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
740 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
741 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
742
743 dss_save_context();
744
745 rev = dss_read_reg(DSS_REVISION);
746 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
747 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
748 675
749 return 0; 676 return 0;
750 677
751fail1: 678err:
752 iounmap(dss.base); 679 if (dss.dss_clk)
753fail0: 680 clk_put(dss.dss_clk);
754 return r;
755}
756
757static void dss_exit(void)
758{
759 if (dss.dpll4_m4_ck) 681 if (dss.dpll4_m4_ck)
760 clk_put(dss.dpll4_m4_ck); 682 clk_put(dss.dpll4_m4_ck);
761 683
762 iounmap(dss.base);
763}
764
765/* CONTEXT */
766static int dss_get_ctx_id(void)
767{
768 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
769 int r;
770
771 if (!pdata->board_data->get_last_off_on_transaction_id)
772 return 0;
773 r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
774 if (r < 0) {
775 dev_err(&dss.pdev->dev, "getting transaction ID failed, "
776 "will force context restore\n");
777 r = -1;
778 }
779 return r;
780}
781
782int dss_need_ctx_restore(void)
783{
784 int id = dss_get_ctx_id();
785
786 if (id < 0 || id != dss.ctx_id) {
787 DSSDBG("ctx id %d -> id %d\n",
788 dss.ctx_id, id);
789 dss.ctx_id = id;
790 return 1;
791 } else {
792 return 0;
793 }
794}
795
796static void save_all_ctx(void)
797{
798 DSSDBG("save context\n");
799
800 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
801
802 dss_save_context();
803 dispc_save_context();
804#ifdef CONFIG_OMAP2_DSS_DSI
805 dsi_save_context();
806#endif
807
808 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
809}
810
811static void restore_all_ctx(void)
812{
813 DSSDBG("restore context\n");
814
815 dss_clk_enable_all_no_ctx();
816
817 dss_restore_context();
818 dispc_restore_context();
819#ifdef CONFIG_OMAP2_DSS_DSI
820 dsi_restore_context();
821#endif
822
823 dss_clk_disable_all_no_ctx();
824}
825
826static int dss_get_clock(struct clk **clock, const char *clk_name)
827{
828 struct clk *clk;
829
830 clk = clk_get(&dss.pdev->dev, clk_name);
831
832 if (IS_ERR(clk)) {
833 DSSERR("can't get clock %s", clk_name);
834 return PTR_ERR(clk);
835 }
836
837 *clock = clk;
838
839 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
840
841 return 0;
842}
843
844static int dss_get_clocks(void)
845{
846 int r;
847 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
848
849 dss.dss_ick = NULL;
850 dss.dss_fck = NULL;
851 dss.dss_sys_clk = NULL;
852 dss.dss_tv_fck = NULL;
853 dss.dss_video_fck = NULL;
854
855 r = dss_get_clock(&dss.dss_ick, "ick");
856 if (r)
857 goto err;
858
859 r = dss_get_clock(&dss.dss_fck, "fck");
860 if (r)
861 goto err;
862
863 if (!pdata->opt_clock_available) {
864 r = -ENODEV;
865 goto err;
866 }
867
868 if (pdata->opt_clock_available("sys_clk")) {
869 r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
870 if (r)
871 goto err;
872 }
873
874 if (pdata->opt_clock_available("tv_clk")) {
875 r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
876 if (r)
877 goto err;
878 }
879
880 if (pdata->opt_clock_available("video_clk")) {
881 r = dss_get_clock(&dss.dss_video_fck, "video_clk");
882 if (r)
883 goto err;
884 }
885
886 return 0;
887
888err:
889 if (dss.dss_ick)
890 clk_put(dss.dss_ick);
891 if (dss.dss_fck)
892 clk_put(dss.dss_fck);
893 if (dss.dss_sys_clk)
894 clk_put(dss.dss_sys_clk);
895 if (dss.dss_tv_fck)
896 clk_put(dss.dss_tv_fck);
897 if (dss.dss_video_fck)
898 clk_put(dss.dss_video_fck);
899
900 return r; 684 return r;
901} 685}
902 686
903static void dss_put_clocks(void) 687static void dss_put_clocks(void)
904{ 688{
905 if (dss.dss_video_fck) 689 if (dss.dpll4_m4_ck)
906 clk_put(dss.dss_video_fck); 690 clk_put(dss.dpll4_m4_ck);
907 if (dss.dss_tv_fck) 691 clk_put(dss.dss_clk);
908 clk_put(dss.dss_tv_fck);
909 if (dss.dss_sys_clk)
910 clk_put(dss.dss_sys_clk);
911 clk_put(dss.dss_fck);
912 clk_put(dss.dss_ick);
913}
914
915unsigned long dss_clk_get_rate(enum dss_clock clk)
916{
917 switch (clk) {
918 case DSS_CLK_ICK:
919 return clk_get_rate(dss.dss_ick);
920 case DSS_CLK_FCK:
921 return clk_get_rate(dss.dss_fck);
922 case DSS_CLK_SYSCK:
923 return clk_get_rate(dss.dss_sys_clk);
924 case DSS_CLK_TVFCK:
925 return clk_get_rate(dss.dss_tv_fck);
926 case DSS_CLK_VIDFCK:
927 return clk_get_rate(dss.dss_video_fck);
928 }
929
930 BUG();
931 return 0;
932}
933
934static unsigned count_clk_bits(enum dss_clock clks)
935{
936 unsigned num_clks = 0;
937
938 if (clks & DSS_CLK_ICK)
939 ++num_clks;
940 if (clks & DSS_CLK_FCK)
941 ++num_clks;
942 if (clks & DSS_CLK_SYSCK)
943 ++num_clks;
944 if (clks & DSS_CLK_TVFCK)
945 ++num_clks;
946 if (clks & DSS_CLK_VIDFCK)
947 ++num_clks;
948
949 return num_clks;
950}
951
952static void dss_clk_enable_no_ctx(enum dss_clock clks)
953{
954 unsigned num_clks = count_clk_bits(clks);
955
956 if (clks & DSS_CLK_ICK)
957 clk_enable(dss.dss_ick);
958 if (clks & DSS_CLK_FCK)
959 clk_enable(dss.dss_fck);
960 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
961 clk_enable(dss.dss_sys_clk);
962 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
963 clk_enable(dss.dss_tv_fck);
964 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
965 clk_enable(dss.dss_video_fck);
966
967 dss.num_clks_enabled += num_clks;
968}
969
970void dss_clk_enable(enum dss_clock clks)
971{
972 bool check_ctx = dss.num_clks_enabled == 0;
973
974 dss_clk_enable_no_ctx(clks);
975
976 /*
977 * HACK: On omap4 the registers may not be accessible right after
978 * enabling the clocks. At some point this will be handled by
979 * pm_runtime, but for the time begin this should make things work.
980 */
981 if (cpu_is_omap44xx() && check_ctx)
982 udelay(10);
983
984 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
985 restore_all_ctx();
986} 692}
987 693
988static void dss_clk_disable_no_ctx(enum dss_clock clks) 694struct clk *dss_get_ick(void)
989{ 695{
990 unsigned num_clks = count_clk_bits(clks); 696 return clk_get(&dss.pdev->dev, "ick");
991
992 if (clks & DSS_CLK_ICK)
993 clk_disable(dss.dss_ick);
994 if (clks & DSS_CLK_FCK)
995 clk_disable(dss.dss_fck);
996 if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk)
997 clk_disable(dss.dss_sys_clk);
998 if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck)
999 clk_disable(dss.dss_tv_fck);
1000 if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck)
1001 clk_disable(dss.dss_video_fck);
1002
1003 dss.num_clks_enabled -= num_clks;
1004} 697}
1005 698
1006void dss_clk_disable(enum dss_clock clks) 699int dss_runtime_get(void)
1007{ 700{
1008 if (cpu_is_omap34xx()) { 701 int r;
1009 unsigned num_clks = count_clk_bits(clks);
1010
1011 BUG_ON(dss.num_clks_enabled < num_clks);
1012 702
1013 if (dss.num_clks_enabled == num_clks) 703 DSSDBG("dss_runtime_get\n");
1014 save_all_ctx();
1015 }
1016 704
1017 dss_clk_disable_no_ctx(clks); 705 r = pm_runtime_get_sync(&dss.pdev->dev);
706 WARN_ON(r < 0);
707 return r < 0 ? r : 0;
1018} 708}
1019 709
1020static void dss_clk_enable_all_no_ctx(void) 710void dss_runtime_put(void)
1021{ 711{
1022 enum dss_clock clks; 712 int r;
1023
1024 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
1025 if (cpu_is_omap34xx())
1026 clks |= DSS_CLK_VIDFCK;
1027 dss_clk_enable_no_ctx(clks);
1028}
1029
1030static void dss_clk_disable_all_no_ctx(void)
1031{
1032 enum dss_clock clks;
1033 713
1034 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; 714 DSSDBG("dss_runtime_put\n");
1035 if (cpu_is_omap34xx())
1036 clks |= DSS_CLK_VIDFCK;
1037 dss_clk_disable_no_ctx(clks);
1038}
1039 715
1040#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 716 r = pm_runtime_put(&dss.pdev->dev);
1041/* CLOCKS */ 717 WARN_ON(r < 0);
1042static void core_dump_clocks(struct seq_file *s)
1043{
1044 int i;
1045 struct clk *clocks[5] = {
1046 dss.dss_ick,
1047 dss.dss_fck,
1048 dss.dss_sys_clk,
1049 dss.dss_tv_fck,
1050 dss.dss_video_fck
1051 };
1052
1053 const char *names[5] = {
1054 "ick",
1055 "fck",
1056 "sys_clk",
1057 "tv_fck",
1058 "video_fck"
1059 };
1060
1061 seq_printf(s, "- CORE -\n");
1062
1063 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
1064
1065 for (i = 0; i < 5; i++) {
1066 if (!clocks[i])
1067 continue;
1068 seq_printf(s, "%s (%s)%*s\t%lu\t%d\n",
1069 names[i],
1070 clocks[i]->name,
1071 24 - strlen(names[i]) - strlen(clocks[i]->name),
1072 "",
1073 clk_get_rate(clocks[i]),
1074 clocks[i]->usecount);
1075 }
1076} 718}
1077#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
1078 719
1079/* DEBUGFS */ 720/* DEBUGFS */
1080#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 721#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1081void dss_debug_dump_clocks(struct seq_file *s) 722void dss_debug_dump_clocks(struct seq_file *s)
1082{ 723{
1083 core_dump_clocks(s);
1084 dss_dump_clocks(s); 724 dss_dump_clocks(s);
1085 dispc_dump_clocks(s); 725 dispc_dump_clocks(s);
1086#ifdef CONFIG_OMAP2_DSS_DSI 726#ifdef CONFIG_OMAP2_DSS_DSI
@@ -1089,28 +729,51 @@ void dss_debug_dump_clocks(struct seq_file *s)
1089} 729}
1090#endif 730#endif
1091 731
1092
1093/* DSS HW IP initialisation */ 732/* DSS HW IP initialisation */
1094static int omap_dsshw_probe(struct platform_device *pdev) 733static int omap_dsshw_probe(struct platform_device *pdev)
1095{ 734{
735 struct resource *dss_mem;
736 u32 rev;
1096 int r; 737 int r;
1097 738
1098 dss.pdev = pdev; 739 dss.pdev = pdev;
1099 740
741 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
742 if (!dss_mem) {
743 DSSERR("can't get IORESOURCE_MEM DSS\n");
744 r = -EINVAL;
745 goto err_ioremap;
746 }
747 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
748 if (!dss.base) {
749 DSSERR("can't ioremap DSS\n");
750 r = -ENOMEM;
751 goto err_ioremap;
752 }
753
1100 r = dss_get_clocks(); 754 r = dss_get_clocks();
1101 if (r) 755 if (r)
1102 goto err_clocks; 756 goto err_clocks;
1103 757
1104 dss_clk_enable_all_no_ctx(); 758 pm_runtime_enable(&pdev->dev);
1105 759
1106 dss.ctx_id = dss_get_ctx_id(); 760 r = dss_runtime_get();
1107 DSSDBG("initial ctx id %u\n", dss.ctx_id); 761 if (r)
762 goto err_runtime_get;
1108 763
1109 r = dss_init(); 764 /* Select DPLL */
1110 if (r) { 765 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
1111 DSSERR("Failed to initialize DSS\n"); 766
1112 goto err_dss; 767#ifdef CONFIG_OMAP2_DSS_VENC
1113 } 768 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
769 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
770 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
771#endif
772 dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
773 dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
774 dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
775 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
776 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1114 777
1115 r = dpi_init(); 778 r = dpi_init();
1116 if (r) { 779 if (r) {
@@ -1124,42 +787,66 @@ static int omap_dsshw_probe(struct platform_device *pdev)
1124 goto err_sdi; 787 goto err_sdi;
1125 } 788 }
1126 789
1127 dss_clk_disable_all_no_ctx(); 790 rev = dss_read_reg(DSS_REVISION);
791 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
792 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
793
794 dss_runtime_put();
795
1128 return 0; 796 return 0;
1129err_sdi: 797err_sdi:
1130 dpi_exit(); 798 dpi_exit();
1131err_dpi: 799err_dpi:
1132 dss_exit(); 800 dss_runtime_put();
1133err_dss: 801err_runtime_get:
1134 dss_clk_disable_all_no_ctx(); 802 pm_runtime_disable(&pdev->dev);
1135 dss_put_clocks(); 803 dss_put_clocks();
1136err_clocks: 804err_clocks:
805 iounmap(dss.base);
806err_ioremap:
1137 return r; 807 return r;
1138} 808}
1139 809
1140static int omap_dsshw_remove(struct platform_device *pdev) 810static int omap_dsshw_remove(struct platform_device *pdev)
1141{ 811{
812 dpi_exit();
813 sdi_exit();
1142 814
1143 dss_exit(); 815 iounmap(dss.base);
1144 816
1145 /* 817 pm_runtime_disable(&pdev->dev);
1146 * As part of hwmod changes, DSS is not the only controller of dss
1147 * clocks; hwmod framework itself will also enable clocks during hwmod
1148 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
1149 * need to disable clocks if their usecounts > 1.
1150 */
1151 WARN_ON(dss.num_clks_enabled > 0);
1152 818
1153 dss_put_clocks(); 819 dss_put_clocks();
820
821 return 0;
822}
823
824static int dss_runtime_suspend(struct device *dev)
825{
826 dss_save_context();
827 clk_disable(dss.dss_clk);
1154 return 0; 828 return 0;
1155} 829}
1156 830
831static int dss_runtime_resume(struct device *dev)
832{
833 clk_enable(dss.dss_clk);
834 dss_restore_context();
835 return 0;
836}
837
838static const struct dev_pm_ops dss_pm_ops = {
839 .runtime_suspend = dss_runtime_suspend,
840 .runtime_resume = dss_runtime_resume,
841};
842
1157static struct platform_driver omap_dsshw_driver = { 843static struct platform_driver omap_dsshw_driver = {
1158 .probe = omap_dsshw_probe, 844 .probe = omap_dsshw_probe,
1159 .remove = omap_dsshw_remove, 845 .remove = omap_dsshw_remove,
1160 .driver = { 846 .driver = {
1161 .name = "omapdss_dss", 847 .name = "omapdss_dss",
1162 .owner = THIS_MODULE, 848 .owner = THIS_MODULE,
849 .pm = &dss_pm_ops,
1163 }, 850 },
1164}; 851};
1165 852
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8ab6d43329bb..9c94b1152c20 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,26 +97,12 @@ extern unsigned int dss_debug;
97#define FLD_MOD(orig, val, start, end) \ 97#define FLD_MOD(orig, val, start, end) \
98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
99 99
100enum omap_burst_size {
101 OMAP_DSS_BURST_4x32 = 0,
102 OMAP_DSS_BURST_8x32 = 1,
103 OMAP_DSS_BURST_16x32 = 2,
104};
105
106enum omap_parallel_interface_mode { 100enum omap_parallel_interface_mode {
107 OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */ 101 OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */
108 OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */ 102 OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */
109 OMAP_DSS_PARALLELMODE_DSI, 103 OMAP_DSS_PARALLELMODE_DSI,
110}; 104};
111 105
112enum dss_clock {
113 DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
114 DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
115 DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
116 DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
118};
119
120enum dss_hdmi_venc_clk_source_select { 106enum dss_hdmi_venc_clk_source_select {
121 DSS_VENC_TV_CLK = 0, 107 DSS_VENC_TV_CLK = 0,
122 DSS_HDMI_M_PCLK = 1, 108 DSS_HDMI_M_PCLK = 1,
@@ -194,7 +180,7 @@ void dss_uninit_device(struct platform_device *pdev,
194bool dss_use_replication(struct omap_dss_device *dssdev, 180bool dss_use_replication(struct omap_dss_device *dssdev,
195 enum omap_color_mode mode); 181 enum omap_color_mode mode);
196void default_get_overlay_fifo_thresholds(enum omap_plane plane, 182void default_get_overlay_fifo_thresholds(enum omap_plane plane,
197 u32 fifo_size, enum omap_burst_size *burst_size, 183 u32 fifo_size, u32 burst_size,
198 u32 *fifo_low, u32 *fifo_high); 184 u32 *fifo_low, u32 *fifo_high);
199 185
200/* manager */ 186/* manager */
@@ -220,13 +206,12 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
220int dss_init_platform_driver(void); 206int dss_init_platform_driver(void);
221void dss_uninit_platform_driver(void); 207void dss_uninit_platform_driver(void);
222 208
209int dss_runtime_get(void);
210void dss_runtime_put(void);
211
212struct clk *dss_get_ick(void);
213
223void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 214void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
224void dss_save_context(void);
225void dss_restore_context(void);
226void dss_clk_enable(enum dss_clock clks);
227void dss_clk_disable(enum dss_clock clks);
228unsigned long dss_clk_get_rate(enum dss_clock clk);
229int dss_need_ctx_restore(void);
230const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 215const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
231void dss_dump_clocks(struct seq_file *s); 216void dss_dump_clocks(struct seq_file *s);
232 217
@@ -283,15 +268,15 @@ struct file_operations;
283int dsi_init_platform_driver(void); 268int dsi_init_platform_driver(void);
284void dsi_uninit_platform_driver(void); 269void dsi_uninit_platform_driver(void);
285 270
271int dsi_runtime_get(struct platform_device *dsidev);
272void dsi_runtime_put(struct platform_device *dsidev);
273
286void dsi_dump_clocks(struct seq_file *s); 274void dsi_dump_clocks(struct seq_file *s);
287void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, 275void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
288 const struct file_operations *debug_fops); 276 const struct file_operations *debug_fops);
289void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, 277void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
290 const struct file_operations *debug_fops); 278 const struct file_operations *debug_fops);
291 279
292void dsi_save_context(void);
293void dsi_restore_context(void);
294
295int dsi_init_display(struct omap_dss_device *display); 280int dsi_init_display(struct omap_dss_device *display);
296void dsi_irq_handler(void); 281void dsi_irq_handler(void);
297unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); 282unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
@@ -304,7 +289,7 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
304 bool enable_hsdiv); 289 bool enable_hsdiv);
305void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); 290void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
306void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 291void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
307 u32 fifo_size, enum omap_burst_size *burst_size, 292 u32 fifo_size, u32 burst_size,
308 u32 *fifo_low, u32 *fifo_high); 293 u32 *fifo_low, u32 *fifo_high);
309void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); 294void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
310void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); 295void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
@@ -317,6 +302,13 @@ static inline int dsi_init_platform_driver(void)
317static inline void dsi_uninit_platform_driver(void) 302static inline void dsi_uninit_platform_driver(void)
318{ 303{
319} 304}
305static inline int dsi_runtime_get(struct platform_device *dsidev)
306{
307 return 0;
308}
309static inline void dsi_runtime_put(struct platform_device *dsidev)
310{
311}
320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) 312static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
321{ 313{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__); 314 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
@@ -384,8 +376,8 @@ void dispc_dump_regs(struct seq_file *s);
384void dispc_irq_handler(void); 376void dispc_irq_handler(void);
385void dispc_fake_vsync_irq(void); 377void dispc_fake_vsync_irq(void);
386 378
387void dispc_save_context(void); 379int dispc_runtime_get(void);
388void dispc_restore_context(void); 380void dispc_runtime_put(void);
389 381
390void dispc_enable_sidle(void); 382void dispc_enable_sidle(void);
391void dispc_disable_sidle(void); 383void dispc_disable_sidle(void);
@@ -398,10 +390,12 @@ void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
398void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height); 390void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
399void dispc_set_digit_size(u16 width, u16 height); 391void dispc_set_digit_size(u16 width, u16 height);
400u32 dispc_get_plane_fifo_size(enum omap_plane plane); 392u32 dispc_get_plane_fifo_size(enum omap_plane plane);
401void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high); 393void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
402void dispc_enable_fifomerge(bool enable); 394void dispc_enable_fifomerge(bool enable);
403void dispc_set_burst_size(enum omap_plane plane, 395u32 dispc_get_burst_size(enum omap_plane plane);
404 enum omap_burst_size burst_size); 396void dispc_enable_cpr(enum omap_channel channel, bool enable);
397void dispc_set_cpr_coef(enum omap_channel channel,
398 struct omap_dss_cpr_coefs *coefs);
405 399
406void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr); 400void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
407void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr); 401void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 1c18888e5df3..b415c4ee621d 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -49,6 +49,9 @@ struct omap_dss_features {
49 const enum omap_color_mode *supported_color_modes; 49 const enum omap_color_mode *supported_color_modes;
50 const char * const *clksrc_names; 50 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params; 51 const struct dss_param_range *dss_params;
52
53 const u32 buffer_size_unit;
54 const u32 burst_size_unit;
52}; 55};
53 56
54/* This struct is assigned to one of the below during initialization */ 57/* This struct is assigned to one of the below during initialization */
@@ -274,6 +277,8 @@ static const struct omap_dss_features omap2_dss_features = {
274 .supported_color_modes = omap2_dss_supported_color_modes, 277 .supported_color_modes = omap2_dss_supported_color_modes,
275 .clksrc_names = omap2_dss_clk_source_names, 278 .clksrc_names = omap2_dss_clk_source_names,
276 .dss_params = omap2_dss_param_range, 279 .dss_params = omap2_dss_param_range,
280 .buffer_size_unit = 1,
281 .burst_size_unit = 8,
277}; 282};
278 283
279/* OMAP3 DSS Features */ 284/* OMAP3 DSS Features */
@@ -286,7 +291,9 @@ static const struct omap_dss_features omap3430_dss_features = {
286 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 291 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
287 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | 292 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
288 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | 293 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
289 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC, 294 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
295 FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
296 FEAT_FIR_COEF_V,
290 297
291 .num_mgrs = 2, 298 .num_mgrs = 2,
292 .num_ovls = 3, 299 .num_ovls = 3,
@@ -294,6 +301,8 @@ static const struct omap_dss_features omap3430_dss_features = {
294 .supported_color_modes = omap3_dss_supported_color_modes, 301 .supported_color_modes = omap3_dss_supported_color_modes,
295 .clksrc_names = omap3_dss_clk_source_names, 302 .clksrc_names = omap3_dss_clk_source_names,
296 .dss_params = omap3_dss_param_range, 303 .dss_params = omap3_dss_param_range,
304 .buffer_size_unit = 1,
305 .burst_size_unit = 8,
297}; 306};
298 307
299static const struct omap_dss_features omap3630_dss_features = { 308static const struct omap_dss_features omap3630_dss_features = {
@@ -306,7 +315,8 @@ static const struct omap_dss_features omap3630_dss_features = {
306 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | 315 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
307 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | 316 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
308 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | 317 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
309 FEAT_DSI_PLL_FREQSEL, 318 FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
319 FEAT_FIR_COEF_V,
310 320
311 .num_mgrs = 2, 321 .num_mgrs = 2,
312 .num_ovls = 3, 322 .num_ovls = 3,
@@ -314,6 +324,8 @@ static const struct omap_dss_features omap3630_dss_features = {
314 .supported_color_modes = omap3_dss_supported_color_modes, 324 .supported_color_modes = omap3_dss_supported_color_modes,
315 .clksrc_names = omap3_dss_clk_source_names, 325 .clksrc_names = omap3_dss_clk_source_names,
316 .dss_params = omap3_dss_param_range, 326 .dss_params = omap3_dss_param_range,
327 .buffer_size_unit = 1,
328 .burst_size_unit = 8,
317}; 329};
318 330
319/* OMAP4 DSS Features */ 331/* OMAP4 DSS Features */
@@ -327,7 +339,8 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
327 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | 339 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
328 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 340 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
329 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 341 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
330 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2, 342 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 |
343 FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V,
331 344
332 .num_mgrs = 3, 345 .num_mgrs = 3,
333 .num_ovls = 3, 346 .num_ovls = 3,
@@ -335,6 +348,8 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
335 .supported_color_modes = omap4_dss_supported_color_modes, 348 .supported_color_modes = omap4_dss_supported_color_modes,
336 .clksrc_names = omap4_dss_clk_source_names, 349 .clksrc_names = omap4_dss_clk_source_names,
337 .dss_params = omap4_dss_param_range, 350 .dss_params = omap4_dss_param_range,
351 .buffer_size_unit = 16,
352 .burst_size_unit = 16,
338}; 353};
339 354
340/* For all the other OMAP4 versions */ 355/* For all the other OMAP4 versions */
@@ -348,7 +363,8 @@ static const struct omap_dss_features omap4_dss_features = {
348 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 363 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
349 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 364 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
350 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | 365 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
351 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2, 366 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
367 FEAT_PRELOAD | FEAT_FIR_COEF_V,
352 368
353 .num_mgrs = 3, 369 .num_mgrs = 3,
354 .num_ovls = 3, 370 .num_ovls = 3,
@@ -356,6 +372,8 @@ static const struct omap_dss_features omap4_dss_features = {
356 .supported_color_modes = omap4_dss_supported_color_modes, 372 .supported_color_modes = omap4_dss_supported_color_modes,
357 .clksrc_names = omap4_dss_clk_source_names, 373 .clksrc_names = omap4_dss_clk_source_names,
358 .dss_params = omap4_dss_param_range, 374 .dss_params = omap4_dss_param_range,
375 .buffer_size_unit = 16,
376 .burst_size_unit = 16,
359}; 377};
360 378
361/* Functions returning values related to a DSS feature */ 379/* Functions returning values related to a DSS feature */
@@ -401,6 +419,16 @@ const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
401 return omap_current_dss_features->clksrc_names[id]; 419 return omap_current_dss_features->clksrc_names[id];
402} 420}
403 421
422u32 dss_feat_get_buffer_size_unit(void)
423{
424 return omap_current_dss_features->buffer_size_unit;
425}
426
427u32 dss_feat_get_burst_size_unit(void)
428{
429 return omap_current_dss_features->burst_size_unit;
430}
431
404/* DSS has_feature check */ 432/* DSS has_feature check */
405bool dss_has_feature(enum dss_feat_id id) 433bool dss_has_feature(enum dss_feat_id id)
406{ 434{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 07b346f7d916..b7398cbcda5f 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -51,6 +51,10 @@ enum dss_feat_id {
51 FEAT_HDMI_CTS_SWMODE = 1 << 19, 51 FEAT_HDMI_CTS_SWMODE = 1 << 19,
52 FEAT_HANDLE_UV_SEPARATE = 1 << 20, 52 FEAT_HANDLE_UV_SEPARATE = 1 << 20,
53 FEAT_ATTR2 = 1 << 21, 53 FEAT_ATTR2 = 1 << 21,
54 FEAT_VENC_REQUIRES_TV_DAC_CLK = 1 << 22,
55 FEAT_CPR = 1 << 23,
56 FEAT_PRELOAD = 1 << 24,
57 FEAT_FIR_COEF_V = 1 << 25,
54}; 58};
55 59
56/* DSS register field id */ 60/* DSS register field id */
@@ -90,6 +94,9 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
90 enum omap_color_mode color_mode); 94 enum omap_color_mode color_mode);
91const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id); 95const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
92 96
97u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
98u32 dss_feat_get_burst_size_unit(void); /* in bytes */
99
93bool dss_has_feature(enum dss_feat_id id); 100bool dss_has_feature(enum dss_feat_id id);
94void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 101void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
95void dss_features_init(void); 102void dss_features_init(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index b0555f4f0a78..256f27a9064a 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -29,6 +29,9 @@
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/platform_device.h>
33#include <linux/pm_runtime.h>
34#include <linux/clk.h>
32#include <video/omapdss.h> 35#include <video/omapdss.h>
33#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 36#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
34 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 37 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
@@ -51,6 +54,9 @@ static struct {
51 u8 edid_set; 54 u8 edid_set;
52 bool custom_set; 55 bool custom_set;
53 struct hdmi_config cfg; 56 struct hdmi_config cfg;
57
58 struct clk *sys_clk;
59 struct clk *hdmi_clk;
54} hdmi; 60} hdmi;
55 61
56/* 62/*
@@ -162,6 +168,27 @@ static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
162 return val; 168 return val;
163} 169}
164 170
171static int hdmi_runtime_get(void)
172{
173 int r;
174
175 DSSDBG("hdmi_runtime_get\n");
176
177 r = pm_runtime_get_sync(&hdmi.pdev->dev);
178 WARN_ON(r < 0);
179 return r < 0 ? r : 0;
180}
181
182static void hdmi_runtime_put(void)
183{
184 int r;
185
186 DSSDBG("hdmi_runtime_put\n");
187
188 r = pm_runtime_put(&hdmi.pdev->dev);
189 WARN_ON(r < 0);
190}
191
165int hdmi_init_display(struct omap_dss_device *dssdev) 192int hdmi_init_display(struct omap_dss_device *dssdev)
166{ 193{
167 DSSDBG("init_display\n"); 194 DSSDBG("init_display\n");
@@ -311,30 +338,11 @@ static int hdmi_phy_init(void)
311 return 0; 338 return 0;
312} 339}
313 340
314static int hdmi_wait_softreset(void)
315{
316 /* reset W1 */
317 REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
318
319 /* wait till SOFTRESET == 0 */
320 if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
321 DSSERR("sysconfig reset failed\n");
322 return -ETIMEDOUT;
323 }
324
325 return 0;
326}
327
328static int hdmi_pll_program(struct hdmi_pll_info *fmt) 341static int hdmi_pll_program(struct hdmi_pll_info *fmt)
329{ 342{
330 u16 r = 0; 343 u16 r = 0;
331 enum hdmi_clk_refsel refsel; 344 enum hdmi_clk_refsel refsel;
332 345
333 /* wait for wrapper reset */
334 r = hdmi_wait_softreset();
335 if (r)
336 return r;
337
338 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); 346 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
339 if (r) 347 if (r)
340 return r; 348 return r;
@@ -1064,7 +1072,7 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1064 unsigned long clkin, refclk; 1072 unsigned long clkin, refclk;
1065 u32 mf; 1073 u32 mf;
1066 1074
1067 clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000; 1075 clkin = clk_get_rate(hdmi.sys_clk) / 10000;
1068 /* 1076 /*
1069 * Input clock is predivided by N + 1 1077 * Input clock is predivided by N + 1
1070 * out put of which is reference clk 1078 * out put of which is reference clk
@@ -1098,16 +1106,6 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1098 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 1106 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1099} 1107}
1100 1108
1101static void hdmi_enable_clocks(int enable)
1102{
1103 if (enable)
1104 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
1105 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1106 else
1107 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
1108 DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
1109}
1110
1111static int hdmi_power_on(struct omap_dss_device *dssdev) 1109static int hdmi_power_on(struct omap_dss_device *dssdev)
1112{ 1110{
1113 int r, code = 0; 1111 int r, code = 0;
@@ -1115,7 +1113,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1115 struct omap_video_timings *p; 1113 struct omap_video_timings *p;
1116 unsigned long phy; 1114 unsigned long phy;
1117 1115
1118 hdmi_enable_clocks(1); 1116 r = hdmi_runtime_get();
1117 if (r)
1118 return r;
1119 1119
1120 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); 1120 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1121 1121
@@ -1180,7 +1180,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1180 1180
1181 return 0; 1181 return 0;
1182err: 1182err:
1183 hdmi_enable_clocks(0); 1183 hdmi_runtime_put();
1184 return -EIO; 1184 return -EIO;
1185} 1185}
1186 1186
@@ -1191,7 +1191,7 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
1191 hdmi_wp_video_start(0); 1191 hdmi_wp_video_start(0);
1192 hdmi_phy_off(); 1192 hdmi_phy_off();
1193 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); 1193 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
1194 hdmi_enable_clocks(0); 1194 hdmi_runtime_put();
1195 1195
1196 hdmi.edid_set = 0; 1196 hdmi.edid_set = 0;
1197} 1197}
@@ -1686,14 +1686,43 @@ static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
1686}; 1686};
1687#endif 1687#endif
1688 1688
1689static int hdmi_get_clocks(struct platform_device *pdev)
1690{
1691 struct clk *clk;
1692
1693 clk = clk_get(&pdev->dev, "sys_clk");
1694 if (IS_ERR(clk)) {
1695 DSSERR("can't get sys_clk\n");
1696 return PTR_ERR(clk);
1697 }
1698
1699 hdmi.sys_clk = clk;
1700
1701 clk = clk_get(&pdev->dev, "dss_48mhz_clk");
1702 if (IS_ERR(clk)) {
1703 DSSERR("can't get hdmi_clk\n");
1704 clk_put(hdmi.sys_clk);
1705 return PTR_ERR(clk);
1706 }
1707
1708 hdmi.hdmi_clk = clk;
1709
1710 return 0;
1711}
1712
1713static void hdmi_put_clocks(void)
1714{
1715 if (hdmi.sys_clk)
1716 clk_put(hdmi.sys_clk);
1717 if (hdmi.hdmi_clk)
1718 clk_put(hdmi.hdmi_clk);
1719}
1720
1689/* HDMI HW IP initialisation */ 1721/* HDMI HW IP initialisation */
1690static int omapdss_hdmihw_probe(struct platform_device *pdev) 1722static int omapdss_hdmihw_probe(struct platform_device *pdev)
1691{ 1723{
1692 struct resource *hdmi_mem; 1724 struct resource *hdmi_mem;
1693#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 1725 int r;
1694 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1695 int ret;
1696#endif
1697 1726
1698 hdmi.pdata = pdev->dev.platform_data; 1727 hdmi.pdata = pdev->dev.platform_data;
1699 hdmi.pdev = pdev; 1728 hdmi.pdev = pdev;
@@ -1713,17 +1742,25 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1713 return -ENOMEM; 1742 return -ENOMEM;
1714 } 1743 }
1715 1744
1745 r = hdmi_get_clocks(pdev);
1746 if (r) {
1747 iounmap(hdmi.base_wp);
1748 return r;
1749 }
1750
1751 pm_runtime_enable(&pdev->dev);
1752
1716 hdmi_panel_init(); 1753 hdmi_panel_init();
1717 1754
1718#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 1755#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1719 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 1756 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1720 1757
1721 /* Register ASoC codec DAI */ 1758 /* Register ASoC codec DAI */
1722 ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, 1759 r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
1723 &hdmi_codec_dai_drv, 1); 1760 &hdmi_codec_dai_drv, 1);
1724 if (ret) { 1761 if (r) {
1725 DSSERR("can't register ASoC HDMI audio codec\n"); 1762 DSSERR("can't register ASoC HDMI audio codec\n");
1726 return ret; 1763 return r;
1727 } 1764 }
1728#endif 1765#endif
1729 return 0; 1766 return 0;
@@ -1738,17 +1775,62 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev)
1738 snd_soc_unregister_codec(&pdev->dev); 1775 snd_soc_unregister_codec(&pdev->dev);
1739#endif 1776#endif
1740 1777
1778 pm_runtime_disable(&pdev->dev);
1779
1780 hdmi_put_clocks();
1781
1741 iounmap(hdmi.base_wp); 1782 iounmap(hdmi.base_wp);
1742 1783
1743 return 0; 1784 return 0;
1744} 1785}
1745 1786
1787static int hdmi_runtime_suspend(struct device *dev)
1788{
1789 clk_disable(hdmi.hdmi_clk);
1790 clk_disable(hdmi.sys_clk);
1791
1792 dispc_runtime_put();
1793 dss_runtime_put();
1794
1795 return 0;
1796}
1797
1798static int hdmi_runtime_resume(struct device *dev)
1799{
1800 int r;
1801
1802 r = dss_runtime_get();
1803 if (r < 0)
1804 goto err_get_dss;
1805
1806 r = dispc_runtime_get();
1807 if (r < 0)
1808 goto err_get_dispc;
1809
1810
1811 clk_enable(hdmi.sys_clk);
1812 clk_enable(hdmi.hdmi_clk);
1813
1814 return 0;
1815
1816err_get_dispc:
1817 dss_runtime_put();
1818err_get_dss:
1819 return r;
1820}
1821
1822static const struct dev_pm_ops hdmi_pm_ops = {
1823 .runtime_suspend = hdmi_runtime_suspend,
1824 .runtime_resume = hdmi_runtime_resume,
1825};
1826
1746static struct platform_driver omapdss_hdmihw_driver = { 1827static struct platform_driver omapdss_hdmihw_driver = {
1747 .probe = omapdss_hdmihw_probe, 1828 .probe = omapdss_hdmihw_probe,
1748 .remove = omapdss_hdmihw_remove, 1829 .remove = omapdss_hdmihw_remove,
1749 .driver = { 1830 .driver = {
1750 .name = "omapdss_hdmi", 1831 .name = "omapdss_hdmi",
1751 .owner = THIS_MODULE, 1832 .owner = THIS_MODULE,
1833 .pm = &hdmi_pm_ops,
1752 }, 1834 },
1753}; 1835};
1754 1836
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 9aeea50e33ff..13d72d5c714b 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -275,6 +275,108 @@ static ssize_t manager_alpha_blending_enabled_store(
275 return size; 275 return size;
276} 276}
277 277
278static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
279 char *buf)
280{
281 return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable);
282}
283
284static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
285 const char *buf, size_t size)
286{
287 struct omap_overlay_manager_info info;
288 int v;
289 int r;
290 bool enable;
291
292 if (!dss_has_feature(FEAT_CPR))
293 return -ENODEV;
294
295 r = kstrtoint(buf, 0, &v);
296 if (r)
297 return r;
298
299 enable = !!v;
300
301 mgr->get_manager_info(mgr, &info);
302
303 if (info.cpr_enable == enable)
304 return size;
305
306 info.cpr_enable = enable;
307
308 r = mgr->set_manager_info(mgr, &info);
309 if (r)
310 return r;
311
312 r = mgr->apply(mgr);
313 if (r)
314 return r;
315
316 return size;
317}
318
319static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
320 char *buf)
321{
322 struct omap_overlay_manager_info info;
323
324 mgr->get_manager_info(mgr, &info);
325
326 return snprintf(buf, PAGE_SIZE,
327 "%d %d %d %d %d %d %d %d %d\n",
328 info.cpr_coefs.rr,
329 info.cpr_coefs.rg,
330 info.cpr_coefs.rb,
331 info.cpr_coefs.gr,
332 info.cpr_coefs.gg,
333 info.cpr_coefs.gb,
334 info.cpr_coefs.br,
335 info.cpr_coefs.bg,
336 info.cpr_coefs.bb);
337}
338
339static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
340 const char *buf, size_t size)
341{
342 struct omap_overlay_manager_info info;
343 struct omap_dss_cpr_coefs coefs;
344 int r, i;
345 s16 *arr;
346
347 if (!dss_has_feature(FEAT_CPR))
348 return -ENODEV;
349
350 if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
351 &coefs.rr, &coefs.rg, &coefs.rb,
352 &coefs.gr, &coefs.gg, &coefs.gb,
353 &coefs.br, &coefs.bg, &coefs.bb) != 9)
354 return -EINVAL;
355
356 arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
357 coefs.gr, coefs.gg, coefs.gb,
358 coefs.br, coefs.bg, coefs.bb };
359
360 for (i = 0; i < 9; ++i) {
361 if (arr[i] < -512 || arr[i] > 511)
362 return -EINVAL;
363 }
364
365 mgr->get_manager_info(mgr, &info);
366
367 info.cpr_coefs = coefs;
368
369 r = mgr->set_manager_info(mgr, &info);
370 if (r)
371 return r;
372
373 r = mgr->apply(mgr);
374 if (r)
375 return r;
376
377 return size;
378}
379
278struct manager_attribute { 380struct manager_attribute {
279 struct attribute attr; 381 struct attribute attr;
280 ssize_t (*show)(struct omap_overlay_manager *, char *); 382 ssize_t (*show)(struct omap_overlay_manager *, char *);
@@ -300,6 +402,12 @@ static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
300static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, 402static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
301 manager_alpha_blending_enabled_show, 403 manager_alpha_blending_enabled_show,
302 manager_alpha_blending_enabled_store); 404 manager_alpha_blending_enabled_store);
405static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
406 manager_cpr_enable_show,
407 manager_cpr_enable_store);
408static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
409 manager_cpr_coef_show,
410 manager_cpr_coef_store);
303 411
304 412
305static struct attribute *manager_sysfs_attrs[] = { 413static struct attribute *manager_sysfs_attrs[] = {
@@ -310,6 +418,8 @@ static struct attribute *manager_sysfs_attrs[] = {
310 &manager_attr_trans_key_value.attr, 418 &manager_attr_trans_key_value.attr,
311 &manager_attr_trans_key_enabled.attr, 419 &manager_attr_trans_key_enabled.attr,
312 &manager_attr_alpha_blending_enabled.attr, 420 &manager_attr_alpha_blending_enabled.attr,
421 &manager_attr_cpr_enable.attr,
422 &manager_attr_cpr_coef.attr,
313 NULL 423 NULL
314}; 424};
315 425
@@ -391,33 +501,14 @@ struct overlay_cache_data {
391 501
392 bool enabled; 502 bool enabled;
393 503
394 u32 paddr; 504 struct omap_overlay_info info;
395 void __iomem *vaddr;
396 u32 p_uv_addr; /* relevant for NV12 format only */
397 u16 screen_width;
398 u16 width;
399 u16 height;
400 enum omap_color_mode color_mode;
401 u8 rotation;
402 enum omap_dss_rotation_type rotation_type;
403 bool mirror;
404
405 u16 pos_x;
406 u16 pos_y;
407 u16 out_width; /* if 0, out_width == width */
408 u16 out_height; /* if 0, out_height == height */
409 u8 global_alpha;
410 u8 pre_mult_alpha;
411 505
412 enum omap_channel channel; 506 enum omap_channel channel;
413 bool replication; 507 bool replication;
414 bool ilace; 508 bool ilace;
415 509
416 enum omap_burst_size burst_size;
417 u32 fifo_low; 510 u32 fifo_low;
418 u32 fifo_high; 511 u32 fifo_high;
419
420 bool manual_update;
421}; 512};
422 513
423struct manager_cache_data { 514struct manager_cache_data {
@@ -429,15 +520,8 @@ struct manager_cache_data {
429 * VSYNC/EVSYNC */ 520 * VSYNC/EVSYNC */
430 bool shadow_dirty; 521 bool shadow_dirty;
431 522
432 u32 default_color; 523 struct omap_overlay_manager_info info;
433
434 enum omap_dss_trans_key_type trans_key_type;
435 u32 trans_key;
436 bool trans_enabled;
437
438 bool alpha_enabled;
439 524
440 bool manual_upd_display;
441 bool manual_update; 525 bool manual_update;
442 bool do_manual_update; 526 bool do_manual_update;
443 527
@@ -539,24 +623,15 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
539 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 623 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
540 return 0; 624 return 0;
541 625
626 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
627 return 0;
628
542 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC 629 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
543 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { 630 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
544 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 631 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
545 } else { 632 } else {
546 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 633 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
547 enum omap_dss_update_mode mode; 634 DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
548 mode = dssdev->driver->get_update_mode(dssdev);
549 if (mode != OMAP_DSS_UPDATE_AUTO)
550 return 0;
551
552 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
553 DISPC_IRQ_FRAMEDONE
554 : DISPC_IRQ_FRAMEDONE2;
555 } else {
556 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
557 DISPC_IRQ_VSYNC
558 : DISPC_IRQ_VSYNC2;
559 }
560 } 635 }
561 636
562 mc = &dss_cache.manager_cache[mgr->id]; 637 mc = &dss_cache.manager_cache[mgr->id];
@@ -617,24 +692,15 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
617 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 692 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
618 return 0; 693 return 0;
619 694
695 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
696 return 0;
697
620 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC 698 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
621 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { 699 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
622 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 700 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
623 } else { 701 } else {
624 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 702 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
625 enum omap_dss_update_mode mode; 703 DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
626 mode = dssdev->driver->get_update_mode(dssdev);
627 if (mode != OMAP_DSS_UPDATE_AUTO)
628 return 0;
629
630 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
631 DISPC_IRQ_FRAMEDONE
632 : DISPC_IRQ_FRAMEDONE2;
633 } else {
634 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
635 DISPC_IRQ_VSYNC
636 : DISPC_IRQ_VSYNC2;
637 }
638 } 704 }
639 705
640 oc = &dss_cache.overlay_cache[ovl->id]; 706 oc = &dss_cache.overlay_cache[ovl->id];
@@ -720,10 +786,12 @@ static bool rectangle_intersects(int x1, int y1, int w1, int h1,
720 786
721static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc) 787static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc)
722{ 788{
723 if (oc->out_width != 0 && oc->width != oc->out_width) 789 struct omap_overlay_info *oi = &oc->info;
790
791 if (oi->out_width != 0 && oi->width != oi->out_width)
724 return true; 792 return true;
725 793
726 if (oc->out_height != 0 && oc->height != oc->out_height) 794 if (oi->out_height != 0 && oi->height != oi->out_height)
727 return true; 795 return true;
728 796
729 return false; 797 return false;
@@ -733,6 +801,8 @@ static int configure_overlay(enum omap_plane plane)
733{ 801{
734 struct overlay_cache_data *c; 802 struct overlay_cache_data *c;
735 struct manager_cache_data *mc; 803 struct manager_cache_data *mc;
804 struct omap_overlay_info *oi;
805 struct omap_overlay_manager_info *mi;
736 u16 outw, outh; 806 u16 outw, outh;
737 u16 x, y, w, h; 807 u16 x, y, w, h;
738 u32 paddr; 808 u32 paddr;
@@ -742,6 +812,7 @@ static int configure_overlay(enum omap_plane plane)
742 DSSDBGF("%d", plane); 812 DSSDBGF("%d", plane);
743 813
744 c = &dss_cache.overlay_cache[plane]; 814 c = &dss_cache.overlay_cache[plane];
815 oi = &c->info;
745 816
746 if (!c->enabled) { 817 if (!c->enabled) {
747 dispc_enable_plane(plane, 0); 818 dispc_enable_plane(plane, 0);
@@ -749,21 +820,22 @@ static int configure_overlay(enum omap_plane plane)
749 } 820 }
750 821
751 mc = &dss_cache.manager_cache[c->channel]; 822 mc = &dss_cache.manager_cache[c->channel];
823 mi = &mc->info;
752 824
753 x = c->pos_x; 825 x = oi->pos_x;
754 y = c->pos_y; 826 y = oi->pos_y;
755 w = c->width; 827 w = oi->width;
756 h = c->height; 828 h = oi->height;
757 outw = c->out_width == 0 ? c->width : c->out_width; 829 outw = oi->out_width == 0 ? oi->width : oi->out_width;
758 outh = c->out_height == 0 ? c->height : c->out_height; 830 outh = oi->out_height == 0 ? oi->height : oi->out_height;
759 paddr = c->paddr; 831 paddr = oi->paddr;
760 832
761 orig_w = w; 833 orig_w = w;
762 orig_h = h; 834 orig_h = h;
763 orig_outw = outw; 835 orig_outw = outw;
764 orig_outh = outh; 836 orig_outh = outh;
765 837
766 if (c->manual_update && mc->do_manual_update) { 838 if (mc->manual_update && mc->do_manual_update) {
767 unsigned bpp; 839 unsigned bpp;
768 unsigned scale_x_m = w, scale_x_d = outw; 840 unsigned scale_x_m = w, scale_x_d = outw;
769 unsigned scale_y_m = h, scale_y_d = outh; 841 unsigned scale_y_m = h, scale_y_d = outh;
@@ -775,7 +847,7 @@ static int configure_overlay(enum omap_plane plane)
775 return 0; 847 return 0;
776 } 848 }
777 849
778 switch (c->color_mode) { 850 switch (oi->color_mode) {
779 case OMAP_DSS_COLOR_NV12: 851 case OMAP_DSS_COLOR_NV12:
780 bpp = 8; 852 bpp = 8;
781 break; 853 break;
@@ -805,23 +877,23 @@ static int configure_overlay(enum omap_plane plane)
805 BUG(); 877 BUG();
806 } 878 }
807 879
808 if (mc->x > c->pos_x) { 880 if (mc->x > oi->pos_x) {
809 x = 0; 881 x = 0;
810 outw -= (mc->x - c->pos_x); 882 outw -= (mc->x - oi->pos_x);
811 paddr += (mc->x - c->pos_x) * 883 paddr += (mc->x - oi->pos_x) *
812 scale_x_m / scale_x_d * bpp / 8; 884 scale_x_m / scale_x_d * bpp / 8;
813 } else { 885 } else {
814 x = c->pos_x - mc->x; 886 x = oi->pos_x - mc->x;
815 } 887 }
816 888
817 if (mc->y > c->pos_y) { 889 if (mc->y > oi->pos_y) {
818 y = 0; 890 y = 0;
819 outh -= (mc->y - c->pos_y); 891 outh -= (mc->y - oi->pos_y);
820 paddr += (mc->y - c->pos_y) * 892 paddr += (mc->y - oi->pos_y) *
821 scale_y_m / scale_y_d * 893 scale_y_m / scale_y_d *
822 c->screen_width * bpp / 8; 894 oi->screen_width * bpp / 8;
823 } else { 895 } else {
824 y = c->pos_y - mc->y; 896 y = oi->pos_y - mc->y;
825 } 897 }
826 898
827 if (mc->w < (x + outw)) 899 if (mc->w < (x + outw))
@@ -840,8 +912,8 @@ static int configure_overlay(enum omap_plane plane)
840 * the width if the original width was bigger. 912 * the width if the original width was bigger.
841 */ 913 */
842 if ((w & 1) && 914 if ((w & 1) &&
843 (c->color_mode == OMAP_DSS_COLOR_YUV2 || 915 (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
844 c->color_mode == OMAP_DSS_COLOR_UYVY)) { 916 oi->color_mode == OMAP_DSS_COLOR_UYVY)) {
845 if (orig_w > w) 917 if (orig_w > w)
846 w += 1; 918 w += 1;
847 else 919 else
@@ -851,19 +923,19 @@ static int configure_overlay(enum omap_plane plane)
851 923
852 r = dispc_setup_plane(plane, 924 r = dispc_setup_plane(plane,
853 paddr, 925 paddr,
854 c->screen_width, 926 oi->screen_width,
855 x, y, 927 x, y,
856 w, h, 928 w, h,
857 outw, outh, 929 outw, outh,
858 c->color_mode, 930 oi->color_mode,
859 c->ilace, 931 c->ilace,
860 c->rotation_type, 932 oi->rotation_type,
861 c->rotation, 933 oi->rotation,
862 c->mirror, 934 oi->mirror,
863 c->global_alpha, 935 oi->global_alpha,
864 c->pre_mult_alpha, 936 oi->pre_mult_alpha,
865 c->channel, 937 c->channel,
866 c->p_uv_addr); 938 oi->p_uv_addr);
867 939
868 if (r) { 940 if (r) {
869 /* this shouldn't happen */ 941 /* this shouldn't happen */
@@ -874,8 +946,7 @@ static int configure_overlay(enum omap_plane plane)
874 946
875 dispc_enable_replication(plane, c->replication); 947 dispc_enable_replication(plane, c->replication);
876 948
877 dispc_set_burst_size(plane, c->burst_size); 949 dispc_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
878 dispc_setup_plane_fifo(plane, c->fifo_low, c->fifo_high);
879 950
880 dispc_enable_plane(plane, 1); 951 dispc_enable_plane(plane, 1);
881 952
@@ -884,16 +955,21 @@ static int configure_overlay(enum omap_plane plane)
884 955
885static void configure_manager(enum omap_channel channel) 956static void configure_manager(enum omap_channel channel)
886{ 957{
887 struct manager_cache_data *c; 958 struct omap_overlay_manager_info *mi;
888 959
889 DSSDBGF("%d", channel); 960 DSSDBGF("%d", channel);
890 961
891 c = &dss_cache.manager_cache[channel]; 962 /* picking info from the cache */
963 mi = &dss_cache.manager_cache[channel].info;
892 964
893 dispc_set_default_color(channel, c->default_color); 965 dispc_set_default_color(channel, mi->default_color);
894 dispc_set_trans_key(channel, c->trans_key_type, c->trans_key); 966 dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
895 dispc_enable_trans_key(channel, c->trans_enabled); 967 dispc_enable_trans_key(channel, mi->trans_enabled);
896 dispc_enable_alpha_blending(channel, c->alpha_enabled); 968 dispc_enable_alpha_blending(channel, mi->alpha_enabled);
969 if (dss_has_feature(FEAT_CPR)) {
970 dispc_enable_cpr(channel, mi->cpr_enable);
971 dispc_set_cpr_coef(channel, &mi->cpr_coefs);
972 }
897} 973}
898 974
899/* configure_dispc() tries to write values from cache to shadow registers. 975/* configure_dispc() tries to write values from cache to shadow registers.
@@ -928,7 +1004,7 @@ static int configure_dispc(void)
928 if (!oc->dirty) 1004 if (!oc->dirty)
929 continue; 1005 continue;
930 1006
931 if (oc->manual_update && !mc->do_manual_update) 1007 if (mc->manual_update && !mc->do_manual_update)
932 continue; 1008 continue;
933 1009
934 if (mgr_busy[oc->channel]) { 1010 if (mgr_busy[oc->channel]) {
@@ -976,7 +1052,7 @@ static int configure_dispc(void)
976 /* We don't need GO with manual update display. LCD iface will 1052 /* We don't need GO with manual update display. LCD iface will
977 * always be turned off after frame, and new settings will be 1053 * always be turned off after frame, and new settings will be
978 * taken in to use at next update */ 1054 * taken in to use at next update */
979 if (!mc->manual_upd_display) 1055 if (!mc->manual_update)
980 dispc_go(i); 1056 dispc_go(i);
981 } 1057 }
982 1058
@@ -1011,6 +1087,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
1011{ 1087{
1012 struct overlay_cache_data *oc; 1088 struct overlay_cache_data *oc;
1013 struct manager_cache_data *mc; 1089 struct manager_cache_data *mc;
1090 struct omap_overlay_info *oi;
1014 const int num_ovls = dss_feat_get_num_ovls(); 1091 const int num_ovls = dss_feat_get_num_ovls();
1015 struct omap_overlay_manager *mgr; 1092 struct omap_overlay_manager *mgr;
1016 int i; 1093 int i;
@@ -1053,6 +1130,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
1053 unsigned outw, outh; 1130 unsigned outw, outh;
1054 1131
1055 oc = &dss_cache.overlay_cache[i]; 1132 oc = &dss_cache.overlay_cache[i];
1133 oi = &oc->info;
1056 1134
1057 if (oc->channel != mgr->id) 1135 if (oc->channel != mgr->id)
1058 continue; 1136 continue;
@@ -1068,39 +1146,39 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
1068 if (!dispc_is_overlay_scaled(oc)) 1146 if (!dispc_is_overlay_scaled(oc))
1069 continue; 1147 continue;
1070 1148
1071 outw = oc->out_width == 0 ? 1149 outw = oi->out_width == 0 ?
1072 oc->width : oc->out_width; 1150 oi->width : oi->out_width;
1073 outh = oc->out_height == 0 ? 1151 outh = oi->out_height == 0 ?
1074 oc->height : oc->out_height; 1152 oi->height : oi->out_height;
1075 1153
1076 /* is the overlay outside the update region? */ 1154 /* is the overlay outside the update region? */
1077 if (!rectangle_intersects(x, y, w, h, 1155 if (!rectangle_intersects(x, y, w, h,
1078 oc->pos_x, oc->pos_y, 1156 oi->pos_x, oi->pos_y,
1079 outw, outh)) 1157 outw, outh))
1080 continue; 1158 continue;
1081 1159
1082 /* if the overlay totally inside the update region? */ 1160 /* if the overlay totally inside the update region? */
1083 if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh, 1161 if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh,
1084 x, y, w, h)) 1162 x, y, w, h))
1085 continue; 1163 continue;
1086 1164
1087 if (x > oc->pos_x) 1165 if (x > oi->pos_x)
1088 x1 = oc->pos_x; 1166 x1 = oi->pos_x;
1089 else 1167 else
1090 x1 = x; 1168 x1 = x;
1091 1169
1092 if (y > oc->pos_y) 1170 if (y > oi->pos_y)
1093 y1 = oc->pos_y; 1171 y1 = oi->pos_y;
1094 else 1172 else
1095 y1 = y; 1173 y1 = y;
1096 1174
1097 if ((x + w) < (oc->pos_x + outw)) 1175 if ((x + w) < (oi->pos_x + outw))
1098 x2 = oc->pos_x + outw; 1176 x2 = oi->pos_x + outw;
1099 else 1177 else
1100 x2 = x + w; 1178 x2 = x + w;
1101 1179
1102 if ((y + h) < (oc->pos_y + outh)) 1180 if ((y + h) < (oi->pos_y + outh))
1103 y2 = oc->pos_y + outh; 1181 y2 = oi->pos_y + outh;
1104 else 1182 else
1105 y2 = y + h; 1183 y2 = y + h;
1106 1184
@@ -1236,6 +1314,10 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1236 1314
1237 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); 1315 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
1238 1316
1317 r = dispc_runtime_get();
1318 if (r)
1319 return r;
1320
1239 spin_lock_irqsave(&dss_cache.lock, flags); 1321 spin_lock_irqsave(&dss_cache.lock, flags);
1240 1322
1241 /* Configure overlays */ 1323 /* Configure overlays */
@@ -1275,23 +1357,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1275 1357
1276 ovl->info_dirty = false; 1358 ovl->info_dirty = false;
1277 oc->dirty = true; 1359 oc->dirty = true;
1278 1360 oc->info = ovl->info;
1279 oc->paddr = ovl->info.paddr;
1280 oc->vaddr = ovl->info.vaddr;
1281 oc->p_uv_addr = ovl->info.p_uv_addr;
1282 oc->screen_width = ovl->info.screen_width;
1283 oc->width = ovl->info.width;
1284 oc->height = ovl->info.height;
1285 oc->color_mode = ovl->info.color_mode;
1286 oc->rotation = ovl->info.rotation;
1287 oc->rotation_type = ovl->info.rotation_type;
1288 oc->mirror = ovl->info.mirror;
1289 oc->pos_x = ovl->info.pos_x;
1290 oc->pos_y = ovl->info.pos_y;
1291 oc->out_width = ovl->info.out_width;
1292 oc->out_height = ovl->info.out_height;
1293 oc->global_alpha = ovl->info.global_alpha;
1294 oc->pre_mult_alpha = ovl->info.pre_mult_alpha;
1295 1361
1296 oc->replication = 1362 oc->replication =
1297 dss_use_replication(dssdev, ovl->info.color_mode); 1363 dss_use_replication(dssdev, ovl->info.color_mode);
@@ -1302,11 +1368,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1302 1368
1303 oc->enabled = true; 1369 oc->enabled = true;
1304 1370
1305 oc->manual_update =
1306 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
1307 dssdev->driver->get_update_mode(dssdev) !=
1308 OMAP_DSS_UPDATE_AUTO;
1309
1310 ++num_planes_enabled; 1371 ++num_planes_enabled;
1311 } 1372 }
1312 1373
@@ -1334,20 +1395,10 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1334 1395
1335 mgr->info_dirty = false; 1396 mgr->info_dirty = false;
1336 mc->dirty = true; 1397 mc->dirty = true;
1337 1398 mc->info = mgr->info;
1338 mc->default_color = mgr->info.default_color;
1339 mc->trans_key_type = mgr->info.trans_key_type;
1340 mc->trans_key = mgr->info.trans_key;
1341 mc->trans_enabled = mgr->info.trans_enabled;
1342 mc->alpha_enabled = mgr->info.alpha_enabled;
1343
1344 mc->manual_upd_display =
1345 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1346 1399
1347 mc->manual_update = 1400 mc->manual_update =
1348 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && 1401 dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1349 dssdev->driver->get_update_mode(dssdev) !=
1350 OMAP_DSS_UPDATE_AUTO;
1351 } 1402 }
1352 1403
1353 /* XXX TODO: Try to get fifomerge working. The problem is that it 1404 /* XXX TODO: Try to get fifomerge working. The problem is that it
@@ -1368,7 +1419,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1368 /* Configure overlay fifos */ 1419 /* Configure overlay fifos */
1369 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 1420 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
1370 struct omap_dss_device *dssdev; 1421 struct omap_dss_device *dssdev;
1371 u32 size; 1422 u32 size, burst_size;
1372 1423
1373 ovl = omap_dss_get_overlay(i); 1424 ovl = omap_dss_get_overlay(i);
1374 1425
@@ -1386,6 +1437,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1386 if (use_fifomerge) 1437 if (use_fifomerge)
1387 size *= 3; 1438 size *= 3;
1388 1439
1440 burst_size = dispc_get_burst_size(ovl->id);
1441
1389 switch (dssdev->type) { 1442 switch (dssdev->type) {
1390 case OMAP_DISPLAY_TYPE_DPI: 1443 case OMAP_DISPLAY_TYPE_DPI:
1391 case OMAP_DISPLAY_TYPE_DBI: 1444 case OMAP_DISPLAY_TYPE_DBI:
@@ -1393,13 +1446,13 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1393 case OMAP_DISPLAY_TYPE_VENC: 1446 case OMAP_DISPLAY_TYPE_VENC:
1394 case OMAP_DISPLAY_TYPE_HDMI: 1447 case OMAP_DISPLAY_TYPE_HDMI:
1395 default_get_overlay_fifo_thresholds(ovl->id, size, 1448 default_get_overlay_fifo_thresholds(ovl->id, size,
1396 &oc->burst_size, &oc->fifo_low, 1449 burst_size, &oc->fifo_low,
1397 &oc->fifo_high); 1450 &oc->fifo_high);
1398 break; 1451 break;
1399#ifdef CONFIG_OMAP2_DSS_DSI 1452#ifdef CONFIG_OMAP2_DSS_DSI
1400 case OMAP_DISPLAY_TYPE_DSI: 1453 case OMAP_DISPLAY_TYPE_DSI:
1401 dsi_get_overlay_fifo_thresholds(ovl->id, size, 1454 dsi_get_overlay_fifo_thresholds(ovl->id, size,
1402 &oc->burst_size, &oc->fifo_low, 1455 burst_size, &oc->fifo_low,
1403 &oc->fifo_high); 1456 &oc->fifo_high);
1404 break; 1457 break;
1405#endif 1458#endif
@@ -1409,7 +1462,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1409 } 1462 }
1410 1463
1411 r = 0; 1464 r = 0;
1412 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1413 if (!dss_cache.irq_enabled) { 1465 if (!dss_cache.irq_enabled) {
1414 u32 mask; 1466 u32 mask;
1415 1467
@@ -1422,10 +1474,11 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1422 dss_cache.irq_enabled = true; 1474 dss_cache.irq_enabled = true;
1423 } 1475 }
1424 configure_dispc(); 1476 configure_dispc();
1425 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1426 1477
1427 spin_unlock_irqrestore(&dss_cache.lock, flags); 1478 spin_unlock_irqrestore(&dss_cache.lock, flags);
1428 1479
1480 dispc_runtime_put();
1481
1429 return r; 1482 return r;
1430} 1483}
1431 1484
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 0f08025b1f0e..c84380c53c39 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -84,32 +84,42 @@ static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
84 84
85 old_mgr = ovl->manager; 85 old_mgr = ovl->manager;
86 86
87 r = dispc_runtime_get();
88 if (r)
89 return r;
90
87 /* detach old manager */ 91 /* detach old manager */
88 if (old_mgr) { 92 if (old_mgr) {
89 r = ovl->unset_manager(ovl); 93 r = ovl->unset_manager(ovl);
90 if (r) { 94 if (r) {
91 DSSERR("detach failed\n"); 95 DSSERR("detach failed\n");
92 return r; 96 goto err;
93 } 97 }
94 98
95 r = old_mgr->apply(old_mgr); 99 r = old_mgr->apply(old_mgr);
96 if (r) 100 if (r)
97 return r; 101 goto err;
98 } 102 }
99 103
100 if (mgr) { 104 if (mgr) {
101 r = ovl->set_manager(ovl, mgr); 105 r = ovl->set_manager(ovl, mgr);
102 if (r) { 106 if (r) {
103 DSSERR("Failed to attach overlay\n"); 107 DSSERR("Failed to attach overlay\n");
104 return r; 108 goto err;
105 } 109 }
106 110
107 r = mgr->apply(mgr); 111 r = mgr->apply(mgr);
108 if (r) 112 if (r)
109 return r; 113 goto err;
110 } 114 }
111 115
116 dispc_runtime_put();
117
112 return size; 118 return size;
119
120err:
121 dispc_runtime_put();
122 return r;
113} 123}
114 124
115static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) 125static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
@@ -238,6 +248,9 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
238 u8 alpha; 248 u8 alpha;
239 struct omap_overlay_info info; 249 struct omap_overlay_info info;
240 250
251 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
252 return -ENODEV;
253
241 r = kstrtou8(buf, 0, &alpha); 254 r = kstrtou8(buf, 0, &alpha);
242 if (r) 255 if (r)
243 return r; 256 return r;
@@ -504,7 +517,6 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
504 517
505 ovl->manager = mgr; 518 ovl->manager = mgr;
506 519
507 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
508 /* XXX: When there is an overlay on a DSI manual update display, and 520 /* XXX: When there is an overlay on a DSI manual update display, and
509 * the overlay is first disabled, then moved to tv, and enabled, we 521 * the overlay is first disabled, then moved to tv, and enabled, we
510 * seem to get SYNC_LOST_DIGIT error. 522 * seem to get SYNC_LOST_DIGIT error.
@@ -518,7 +530,6 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
518 * the overlay, but before moving the overlay to TV. 530 * the overlay, but before moving the overlay to TV.
519 */ 531 */
520 dispc_set_channel_out(ovl->id, mgr->id); 532 dispc_set_channel_out(ovl->id, mgr->id);
521 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
522 533
523 return 0; 534 return 0;
524} 535}
@@ -719,6 +730,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
719 } 730 }
720 731
721 if (mgr) { 732 if (mgr) {
733 dispc_runtime_get();
734
722 for (i = 0; i < dss_feat_get_num_ovls(); i++) { 735 for (i = 0; i < dss_feat_get_num_ovls(); i++) {
723 struct omap_overlay *ovl; 736 struct omap_overlay *ovl;
724 ovl = omap_dss_get_overlay(i); 737 ovl = omap_dss_get_overlay(i);
@@ -728,6 +741,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
728 omap_dss_set_manager(ovl, mgr); 741 omap_dss_set_manager(ovl, mgr);
729 } 742 }
730 } 743 }
744
745 dispc_runtime_put();
731 } 746 }
732} 747}
733 748
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index c06fbe0bc678..39f4c597026a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -33,6 +33,8 @@
33#include <linux/hrtimer.h> 33#include <linux/hrtimer.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/semaphore.h> 35#include <linux/semaphore.h>
36#include <linux/platform_device.h>
37#include <linux/pm_runtime.h>
36 38
37#include <video/omapdss.h> 39#include <video/omapdss.h>
38#include "dss.h" 40#include "dss.h"
@@ -120,12 +122,25 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
120 return __raw_readl(rfbi.base + idx.idx); 122 return __raw_readl(rfbi.base + idx.idx);
121} 123}
122 124
123static void rfbi_enable_clocks(bool enable) 125static int rfbi_runtime_get(void)
124{ 126{
125 if (enable) 127 int r;
126 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 128
127 else 129 DSSDBG("rfbi_runtime_get\n");
128 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 130
131 r = pm_runtime_get_sync(&rfbi.pdev->dev);
132 WARN_ON(r < 0);
133 return r < 0 ? r : 0;
134}
135
136static void rfbi_runtime_put(void)
137{
138 int r;
139
140 DSSDBG("rfbi_runtime_put\n");
141
142 r = pm_runtime_put(&rfbi.pdev->dev);
143 WARN_ON(r < 0);
129} 144}
130 145
131void rfbi_bus_lock(void) 146void rfbi_bus_lock(void)
@@ -805,7 +820,8 @@ void rfbi_dump_regs(struct seq_file *s)
805{ 820{
806#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 821#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
807 822
808 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 823 if (rfbi_runtime_get())
824 return;
809 825
810 DUMPREG(RFBI_REVISION); 826 DUMPREG(RFBI_REVISION);
811 DUMPREG(RFBI_SYSCONFIG); 827 DUMPREG(RFBI_SYSCONFIG);
@@ -836,7 +852,7 @@ void rfbi_dump_regs(struct seq_file *s)
836 DUMPREG(RFBI_VSYNC_WIDTH); 852 DUMPREG(RFBI_VSYNC_WIDTH);
837 DUMPREG(RFBI_HSYNC_WIDTH); 853 DUMPREG(RFBI_HSYNC_WIDTH);
838 854
839 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 855 rfbi_runtime_put();
840#undef DUMPREG 856#undef DUMPREG
841} 857}
842 858
@@ -844,7 +860,9 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
844{ 860{
845 int r; 861 int r;
846 862
847 rfbi_enable_clocks(1); 863 r = rfbi_runtime_get();
864 if (r)
865 return r;
848 866
849 r = omap_dss_start_device(dssdev); 867 r = omap_dss_start_device(dssdev);
850 if (r) { 868 if (r) {
@@ -879,6 +897,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
879err1: 897err1:
880 omap_dss_stop_device(dssdev); 898 omap_dss_stop_device(dssdev);
881err0: 899err0:
900 rfbi_runtime_put();
882 return r; 901 return r;
883} 902}
884EXPORT_SYMBOL(omapdss_rfbi_display_enable); 903EXPORT_SYMBOL(omapdss_rfbi_display_enable);
@@ -889,7 +908,7 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
889 DISPC_IRQ_FRAMEDONE); 908 DISPC_IRQ_FRAMEDONE);
890 omap_dss_stop_device(dssdev); 909 omap_dss_stop_device(dssdev);
891 910
892 rfbi_enable_clocks(0); 911 rfbi_runtime_put();
893} 912}
894EXPORT_SYMBOL(omapdss_rfbi_display_disable); 913EXPORT_SYMBOL(omapdss_rfbi_display_disable);
895 914
@@ -904,8 +923,9 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
904static int omap_rfbihw_probe(struct platform_device *pdev) 923static int omap_rfbihw_probe(struct platform_device *pdev)
905{ 924{
906 u32 rev; 925 u32 rev;
907 u32 l;
908 struct resource *rfbi_mem; 926 struct resource *rfbi_mem;
927 struct clk *clk;
928 int r;
909 929
910 rfbi.pdev = pdev; 930 rfbi.pdev = pdev;
911 931
@@ -914,46 +934,102 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
914 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); 934 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
915 if (!rfbi_mem) { 935 if (!rfbi_mem) {
916 DSSERR("can't get IORESOURCE_MEM RFBI\n"); 936 DSSERR("can't get IORESOURCE_MEM RFBI\n");
917 return -EINVAL; 937 r = -EINVAL;
938 goto err_ioremap;
918 } 939 }
919 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); 940 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
920 if (!rfbi.base) { 941 if (!rfbi.base) {
921 DSSERR("can't ioremap RFBI\n"); 942 DSSERR("can't ioremap RFBI\n");
922 return -ENOMEM; 943 r = -ENOMEM;
944 goto err_ioremap;
923 } 945 }
924 946
925 rfbi_enable_clocks(1); 947 pm_runtime_enable(&pdev->dev);
948
949 r = rfbi_runtime_get();
950 if (r)
951 goto err_get_rfbi;
926 952
927 msleep(10); 953 msleep(10);
928 954
929 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; 955 if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap3630())
956 clk = dss_get_ick();
957 else
958 clk = clk_get(&pdev->dev, "ick");
959 if (IS_ERR(clk)) {
960 DSSERR("can't get ick\n");
961 r = PTR_ERR(clk);
962 goto err_get_ick;
963 }
964
965 rfbi.l4_khz = clk_get_rate(clk) / 1000;
930 966
931 /* Enable autoidle and smart-idle */ 967 clk_put(clk);
932 l = rfbi_read_reg(RFBI_SYSCONFIG);
933 l |= (1 << 0) | (2 << 3);
934 rfbi_write_reg(RFBI_SYSCONFIG, l);
935 968
936 rev = rfbi_read_reg(RFBI_REVISION); 969 rev = rfbi_read_reg(RFBI_REVISION);
937 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n", 970 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
938 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 971 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
939 972
940 rfbi_enable_clocks(0); 973 rfbi_runtime_put();
941 974
942 return 0; 975 return 0;
976
977err_get_ick:
978 rfbi_runtime_put();
979err_get_rfbi:
980 pm_runtime_disable(&pdev->dev);
981 iounmap(rfbi.base);
982err_ioremap:
983 return r;
943} 984}
944 985
945static int omap_rfbihw_remove(struct platform_device *pdev) 986static int omap_rfbihw_remove(struct platform_device *pdev)
946{ 987{
988 pm_runtime_disable(&pdev->dev);
947 iounmap(rfbi.base); 989 iounmap(rfbi.base);
948 return 0; 990 return 0;
949} 991}
950 992
993static int rfbi_runtime_suspend(struct device *dev)
994{
995 dispc_runtime_put();
996 dss_runtime_put();
997
998 return 0;
999}
1000
1001static int rfbi_runtime_resume(struct device *dev)
1002{
1003 int r;
1004
1005 r = dss_runtime_get();
1006 if (r < 0)
1007 goto err_get_dss;
1008
1009 r = dispc_runtime_get();
1010 if (r < 0)
1011 goto err_get_dispc;
1012
1013 return 0;
1014
1015err_get_dispc:
1016 dss_runtime_put();
1017err_get_dss:
1018 return r;
1019}
1020
1021static const struct dev_pm_ops rfbi_pm_ops = {
1022 .runtime_suspend = rfbi_runtime_suspend,
1023 .runtime_resume = rfbi_runtime_resume,
1024};
1025
951static struct platform_driver omap_rfbihw_driver = { 1026static struct platform_driver omap_rfbihw_driver = {
952 .probe = omap_rfbihw_probe, 1027 .probe = omap_rfbihw_probe,
953 .remove = omap_rfbihw_remove, 1028 .remove = omap_rfbihw_remove,
954 .driver = { 1029 .driver = {
955 .name = "omapdss_rfbi", 1030 .name = "omapdss_rfbi",
956 .owner = THIS_MODULE, 1031 .owner = THIS_MODULE,
1032 .pm = &rfbi_pm_ops,
957 }, 1033 },
958}; 1034};
959 1035
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0bd4b0350f80..3a688c871a45 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -20,13 +20,11 @@
20#define DSS_SUBSYS_NAME "SDI" 20#define DSS_SUBSYS_NAME "SDI"
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/clk.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/err.h> 24#include <linux/err.h>
26#include <linux/regulator/consumer.h> 25#include <linux/regulator/consumer.h>
27 26
28#include <video/omapdss.h> 27#include <video/omapdss.h>
29#include <plat/cpu.h>
30#include "dss.h" 28#include "dss.h"
31 29
32static struct { 30static struct {
@@ -60,14 +58,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
60 r = omap_dss_start_device(dssdev); 58 r = omap_dss_start_device(dssdev);
61 if (r) { 59 if (r) {
62 DSSERR("failed to start device\n"); 60 DSSERR("failed to start device\n");
63 goto err0; 61 goto err_start_dev;
64 } 62 }
65 63
66 r = regulator_enable(sdi.vdds_sdi_reg); 64 r = regulator_enable(sdi.vdds_sdi_reg);
67 if (r) 65 if (r)
68 goto err1; 66 goto err_reg_enable;
69 67
70 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 68 r = dss_runtime_get();
69 if (r)
70 goto err_get_dss;
71
72 r = dispc_runtime_get();
73 if (r)
74 goto err_get_dispc;
71 75
72 sdi_basic_init(dssdev); 76 sdi_basic_init(dssdev);
73 77
@@ -80,7 +84,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
80 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 84 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
81 &dss_cinfo, &dispc_cinfo); 85 &dss_cinfo, &dispc_cinfo);
82 if (r) 86 if (r)
83 goto err2; 87 goto err_calc_clock_div;
84 88
85 fck = dss_cinfo.fck; 89 fck = dss_cinfo.fck;
86 lck_div = dispc_cinfo.lck_div; 90 lck_div = dispc_cinfo.lck_div;
@@ -101,27 +105,34 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
101 105
102 r = dss_set_clock_div(&dss_cinfo); 106 r = dss_set_clock_div(&dss_cinfo);
103 if (r) 107 if (r)
104 goto err2; 108 goto err_set_dss_clock_div;
105 109
106 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 110 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
107 if (r) 111 if (r)
108 goto err2; 112 goto err_set_dispc_clock_div;
109 113
110 dss_sdi_init(dssdev->phy.sdi.datapairs); 114 dss_sdi_init(dssdev->phy.sdi.datapairs);
111 r = dss_sdi_enable(); 115 r = dss_sdi_enable();
112 if (r) 116 if (r)
113 goto err1; 117 goto err_sdi_enable;
114 mdelay(2); 118 mdelay(2);
115 119
116 dssdev->manager->enable(dssdev->manager); 120 dssdev->manager->enable(dssdev->manager);
117 121
118 return 0; 122 return 0;
119err2: 123
120 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 124err_sdi_enable:
125err_set_dispc_clock_div:
126err_set_dss_clock_div:
127err_calc_clock_div:
128 dispc_runtime_put();
129err_get_dispc:
130 dss_runtime_put();
131err_get_dss:
121 regulator_disable(sdi.vdds_sdi_reg); 132 regulator_disable(sdi.vdds_sdi_reg);
122err1: 133err_reg_enable:
123 omap_dss_stop_device(dssdev); 134 omap_dss_stop_device(dssdev);
124err0: 135err_start_dev:
125 return r; 136 return r;
126} 137}
127EXPORT_SYMBOL(omapdss_sdi_display_enable); 138EXPORT_SYMBOL(omapdss_sdi_display_enable);
@@ -132,7 +143,8 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
132 143
133 dss_sdi_disable(); 144 dss_sdi_disable();
134 145
135 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 146 dispc_runtime_put();
147 dss_runtime_put();
136 148
137 regulator_disable(sdi.vdds_sdi_reg); 149 regulator_disable(sdi.vdds_sdi_reg);
138 150
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 980f919ed987..173c66430dad 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -33,11 +33,13 @@
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/regulator/consumer.h> 35#include <linux/regulator/consumer.h>
36#include <linux/pm_runtime.h>
36 37
37#include <video/omapdss.h> 38#include <video/omapdss.h>
38#include <plat/cpu.h> 39#include <plat/cpu.h>
39 40
40#include "dss.h" 41#include "dss.h"
42#include "dss_features.h"
41 43
42/* Venc registers */ 44/* Venc registers */
43#define VENC_REV_ID 0x00 45#define VENC_REV_ID 0x00
@@ -292,6 +294,9 @@ static struct {
292 struct mutex venc_lock; 294 struct mutex venc_lock;
293 u32 wss_data; 295 u32 wss_data;
294 struct regulator *vdda_dac_reg; 296 struct regulator *vdda_dac_reg;
297
298 struct clk *tv_clk;
299 struct clk *tv_dac_clk;
295} venc; 300} venc;
296 301
297static inline void venc_write_reg(int idx, u32 val) 302static inline void venc_write_reg(int idx, u32 val)
@@ -380,14 +385,25 @@ static void venc_reset(void)
380#endif 385#endif
381} 386}
382 387
383static void venc_enable_clocks(int enable) 388static int venc_runtime_get(void)
389{
390 int r;
391
392 DSSDBG("venc_runtime_get\n");
393
394 r = pm_runtime_get_sync(&venc.pdev->dev);
395 WARN_ON(r < 0);
396 return r < 0 ? r : 0;
397}
398
399static void venc_runtime_put(void)
384{ 400{
385 if (enable) 401 int r;
386 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | 402
387 DSS_CLK_VIDFCK); 403 DSSDBG("venc_runtime_put\n");
388 else 404
389 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | 405 r = pm_runtime_put(&venc.pdev->dev);
390 DSS_CLK_VIDFCK); 406 WARN_ON(r < 0);
391} 407}
392 408
393static const struct venc_config *venc_timings_to_config( 409static const struct venc_config *venc_timings_to_config(
@@ -406,8 +422,6 @@ static void venc_power_on(struct omap_dss_device *dssdev)
406{ 422{
407 u32 l; 423 u32 l;
408 424
409 venc_enable_clocks(1);
410
411 venc_reset(); 425 venc_reset();
412 venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); 426 venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
413 427
@@ -448,8 +462,6 @@ static void venc_power_off(struct omap_dss_device *dssdev)
448 dssdev->platform_disable(dssdev); 462 dssdev->platform_disable(dssdev);
449 463
450 regulator_disable(venc.vdda_dac_reg); 464 regulator_disable(venc.vdda_dac_reg);
451
452 venc_enable_clocks(0);
453} 465}
454 466
455 467
@@ -487,6 +499,10 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
487 goto err1; 499 goto err1;
488 } 500 }
489 501
502 r = venc_runtime_get();
503 if (r)
504 goto err1;
505
490 venc_power_on(dssdev); 506 venc_power_on(dssdev);
491 507
492 venc.wss_data = 0; 508 venc.wss_data = 0;
@@ -520,6 +536,8 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
520 536
521 venc_power_off(dssdev); 537 venc_power_off(dssdev);
522 538
539 venc_runtime_put();
540
523 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 541 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
524 542
525 omap_dss_stop_device(dssdev); 543 omap_dss_stop_device(dssdev);
@@ -538,20 +556,6 @@ static int venc_panel_resume(struct omap_dss_device *dssdev)
538 return venc_panel_enable(dssdev); 556 return venc_panel_enable(dssdev);
539} 557}
540 558
541static enum omap_dss_update_mode venc_get_update_mode(
542 struct omap_dss_device *dssdev)
543{
544 return OMAP_DSS_UPDATE_AUTO;
545}
546
547static int venc_set_update_mode(struct omap_dss_device *dssdev,
548 enum omap_dss_update_mode mode)
549{
550 if (mode != OMAP_DSS_UPDATE_AUTO)
551 return -EINVAL;
552 return 0;
553}
554
555static void venc_get_timings(struct omap_dss_device *dssdev, 559static void venc_get_timings(struct omap_dss_device *dssdev,
556 struct omap_video_timings *timings) 560 struct omap_video_timings *timings)
557{ 561{
@@ -598,6 +602,7 @@ static u32 venc_get_wss(struct omap_dss_device *dssdev)
598static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) 602static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
599{ 603{
600 const struct venc_config *config; 604 const struct venc_config *config;
605 int r;
601 606
602 DSSDBG("venc_set_wss\n"); 607 DSSDBG("venc_set_wss\n");
603 608
@@ -608,16 +613,19 @@ static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
608 /* Invert due to VENC_L21_WC_CTL:INV=1 */ 613 /* Invert due to VENC_L21_WC_CTL:INV=1 */
609 venc.wss_data = (wss ^ 0xfffff) << 8; 614 venc.wss_data = (wss ^ 0xfffff) << 8;
610 615
611 venc_enable_clocks(1); 616 r = venc_runtime_get();
617 if (r)
618 goto err;
612 619
613 venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | 620 venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data |
614 venc.wss_data); 621 venc.wss_data);
615 622
616 venc_enable_clocks(0); 623 venc_runtime_put();
617 624
625err:
618 mutex_unlock(&venc.venc_lock); 626 mutex_unlock(&venc.venc_lock);
619 627
620 return 0; 628 return r;
621} 629}
622 630
623static struct omap_dss_driver venc_driver = { 631static struct omap_dss_driver venc_driver = {
@@ -632,9 +640,6 @@ static struct omap_dss_driver venc_driver = {
632 .get_resolution = omapdss_default_get_resolution, 640 .get_resolution = omapdss_default_get_resolution,
633 .get_recommended_bpp = omapdss_default_get_recommended_bpp, 641 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
634 642
635 .set_update_mode = venc_set_update_mode,
636 .get_update_mode = venc_get_update_mode,
637
638 .get_timings = venc_get_timings, 643 .get_timings = venc_get_timings,
639 .set_timings = venc_set_timings, 644 .set_timings = venc_set_timings,
640 .check_timings = venc_check_timings, 645 .check_timings = venc_check_timings,
@@ -673,7 +678,8 @@ void venc_dump_regs(struct seq_file *s)
673{ 678{
674#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) 679#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
675 680
676 venc_enable_clocks(1); 681 if (venc_runtime_get())
682 return;
677 683
678 DUMPREG(VENC_F_CONTROL); 684 DUMPREG(VENC_F_CONTROL);
679 DUMPREG(VENC_VIDOUT_CTRL); 685 DUMPREG(VENC_VIDOUT_CTRL);
@@ -717,16 +723,56 @@ void venc_dump_regs(struct seq_file *s)
717 DUMPREG(VENC_OUTPUT_CONTROL); 723 DUMPREG(VENC_OUTPUT_CONTROL);
718 DUMPREG(VENC_OUTPUT_TEST); 724 DUMPREG(VENC_OUTPUT_TEST);
719 725
720 venc_enable_clocks(0); 726 venc_runtime_put();
721 727
722#undef DUMPREG 728#undef DUMPREG
723} 729}
724 730
731static int venc_get_clocks(struct platform_device *pdev)
732{
733 struct clk *clk;
734
735 clk = clk_get(&pdev->dev, "fck");
736 if (IS_ERR(clk)) {
737 DSSERR("can't get fck\n");
738 return PTR_ERR(clk);
739 }
740
741 venc.tv_clk = clk;
742
743 if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
744 if (cpu_is_omap34xx() || cpu_is_omap3630())
745 clk = clk_get(&pdev->dev, "dss_96m_fck");
746 else
747 clk = clk_get(&pdev->dev, "tv_dac_clk");
748 if (IS_ERR(clk)) {
749 DSSERR("can't get tv_dac_clk\n");
750 clk_put(venc.tv_clk);
751 return PTR_ERR(clk);
752 }
753 } else {
754 clk = NULL;
755 }
756
757 venc.tv_dac_clk = clk;
758
759 return 0;
760}
761
762static void venc_put_clocks(void)
763{
764 if (venc.tv_clk)
765 clk_put(venc.tv_clk);
766 if (venc.tv_dac_clk)
767 clk_put(venc.tv_dac_clk);
768}
769
725/* VENC HW IP initialisation */ 770/* VENC HW IP initialisation */
726static int omap_venchw_probe(struct platform_device *pdev) 771static int omap_venchw_probe(struct platform_device *pdev)
727{ 772{
728 u8 rev_id; 773 u8 rev_id;
729 struct resource *venc_mem; 774 struct resource *venc_mem;
775 int r;
730 776
731 venc.pdev = pdev; 777 venc.pdev = pdev;
732 778
@@ -737,22 +783,40 @@ static int omap_venchw_probe(struct platform_device *pdev)
737 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0); 783 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
738 if (!venc_mem) { 784 if (!venc_mem) {
739 DSSERR("can't get IORESOURCE_MEM VENC\n"); 785 DSSERR("can't get IORESOURCE_MEM VENC\n");
740 return -EINVAL; 786 r = -EINVAL;
787 goto err_ioremap;
741 } 788 }
742 venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); 789 venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
743 if (!venc.base) { 790 if (!venc.base) {
744 DSSERR("can't ioremap VENC\n"); 791 DSSERR("can't ioremap VENC\n");
745 return -ENOMEM; 792 r = -ENOMEM;
793 goto err_ioremap;
746 } 794 }
747 795
748 venc_enable_clocks(1); 796 r = venc_get_clocks(pdev);
797 if (r)
798 goto err_get_clk;
799
800 pm_runtime_enable(&pdev->dev);
801
802 r = venc_runtime_get();
803 if (r)
804 goto err_get_venc;
749 805
750 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); 806 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
751 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id); 807 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
752 808
753 venc_enable_clocks(0); 809 venc_runtime_put();
754 810
755 return omap_dss_register_driver(&venc_driver); 811 return omap_dss_register_driver(&venc_driver);
812
813err_get_venc:
814 pm_runtime_disable(&pdev->dev);
815 venc_put_clocks();
816err_get_clk:
817 iounmap(venc.base);
818err_ioremap:
819 return r;
756} 820}
757 821
758static int omap_venchw_remove(struct platform_device *pdev) 822static int omap_venchw_remove(struct platform_device *pdev)
@@ -763,16 +827,61 @@ static int omap_venchw_remove(struct platform_device *pdev)
763 } 827 }
764 omap_dss_unregister_driver(&venc_driver); 828 omap_dss_unregister_driver(&venc_driver);
765 829
830 pm_runtime_disable(&pdev->dev);
831 venc_put_clocks();
832
766 iounmap(venc.base); 833 iounmap(venc.base);
767 return 0; 834 return 0;
768} 835}
769 836
837static int venc_runtime_suspend(struct device *dev)
838{
839 if (venc.tv_dac_clk)
840 clk_disable(venc.tv_dac_clk);
841 clk_disable(venc.tv_clk);
842
843 dispc_runtime_put();
844 dss_runtime_put();
845
846 return 0;
847}
848
849static int venc_runtime_resume(struct device *dev)
850{
851 int r;
852
853 r = dss_runtime_get();
854 if (r < 0)
855 goto err_get_dss;
856
857 r = dispc_runtime_get();
858 if (r < 0)
859 goto err_get_dispc;
860
861 clk_enable(venc.tv_clk);
862 if (venc.tv_dac_clk)
863 clk_enable(venc.tv_dac_clk);
864
865 return 0;
866
867err_get_dispc:
868 dss_runtime_put();
869err_get_dss:
870 return r;
871}
872
873static const struct dev_pm_ops venc_pm_ops = {
874 .runtime_suspend = venc_runtime_suspend,
875 .runtime_resume = venc_runtime_resume,
876};
877
770static struct platform_driver omap_venchw_driver = { 878static struct platform_driver omap_venchw_driver = {
771 .probe = omap_venchw_probe, 879 .probe = omap_venchw_probe,
772 .remove = omap_venchw_remove, 880 .remove = omap_venchw_remove,
773 .driver = { 881 .driver = {
774 .name = "omapdss_venc", 882 .name = "omapdss_venc",
775 .owner = THIS_MODULE, 883 .owner = THIS_MODULE,
884 .pm = &venc_pm_ops,
776 }, 885 },
777}; 886};
778 887
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index cff450392b79..6b1ac23dbbd3 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -316,67 +316,67 @@ int omapfb_update_window(struct fb_info *fbi,
316} 316}
317EXPORT_SYMBOL(omapfb_update_window); 317EXPORT_SYMBOL(omapfb_update_window);
318 318
319static int omapfb_set_update_mode(struct fb_info *fbi, 319int omapfb_set_update_mode(struct fb_info *fbi,
320 enum omapfb_update_mode mode) 320 enum omapfb_update_mode mode)
321{ 321{
322 struct omap_dss_device *display = fb2display(fbi); 322 struct omap_dss_device *display = fb2display(fbi);
323 enum omap_dss_update_mode um; 323 struct omapfb_info *ofbi = FB2OFB(fbi);
324 struct omapfb2_device *fbdev = ofbi->fbdev;
325 struct omapfb_display_data *d;
324 int r; 326 int r;
325 327
326 if (!display || !display->driver->set_update_mode) 328 if (!display)
327 return -EINVAL; 329 return -EINVAL;
328 330
329 switch (mode) { 331 if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE)
330 case OMAPFB_UPDATE_DISABLED: 332 return -EINVAL;
331 um = OMAP_DSS_UPDATE_DISABLED;
332 break;
333 333
334 case OMAPFB_AUTO_UPDATE: 334 omapfb_lock(fbdev);
335 um = OMAP_DSS_UPDATE_AUTO;
336 break;
337 335
338 case OMAPFB_MANUAL_UPDATE: 336 d = get_display_data(fbdev, display);
339 um = OMAP_DSS_UPDATE_MANUAL;
340 break;
341 337
342 default: 338 if (d->update_mode == mode) {
343 return -EINVAL; 339 omapfb_unlock(fbdev);
340 return 0;
344 } 341 }
345 342
346 r = display->driver->set_update_mode(display, um); 343 r = 0;
344
345 if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
346 if (mode == OMAPFB_AUTO_UPDATE)
347 omapfb_start_auto_update(fbdev, display);
348 else /* MANUAL_UPDATE */
349 omapfb_stop_auto_update(fbdev, display);
350
351 d->update_mode = mode;
352 } else { /* AUTO_UPDATE */
353 if (mode == OMAPFB_MANUAL_UPDATE)
354 r = -EINVAL;
355 }
356
357 omapfb_unlock(fbdev);
347 358
348 return r; 359 return r;
349} 360}
350 361
351static int omapfb_get_update_mode(struct fb_info *fbi, 362int omapfb_get_update_mode(struct fb_info *fbi,
352 enum omapfb_update_mode *mode) 363 enum omapfb_update_mode *mode)
353{ 364{
354 struct omap_dss_device *display = fb2display(fbi); 365 struct omap_dss_device *display = fb2display(fbi);
355 enum omap_dss_update_mode m; 366 struct omapfb_info *ofbi = FB2OFB(fbi);
367 struct omapfb2_device *fbdev = ofbi->fbdev;
368 struct omapfb_display_data *d;
356 369
357 if (!display) 370 if (!display)
358 return -EINVAL; 371 return -EINVAL;
359 372
360 if (!display->driver->get_update_mode) { 373 omapfb_lock(fbdev);
361 *mode = OMAPFB_AUTO_UPDATE;
362 return 0;
363 }
364 374
365 m = display->driver->get_update_mode(display); 375 d = get_display_data(fbdev, display);
366 376
367 switch (m) { 377 *mode = d->update_mode;
368 case OMAP_DSS_UPDATE_DISABLED: 378
369 *mode = OMAPFB_UPDATE_DISABLED; 379 omapfb_unlock(fbdev);
370 break;
371 case OMAP_DSS_UPDATE_AUTO:
372 *mode = OMAPFB_AUTO_UPDATE;
373 break;
374 case OMAP_DSS_UPDATE_MANUAL:
375 *mode = OMAPFB_MANUAL_UPDATE;
376 break;
377 default:
378 BUG();
379 }
380 380
381 return 0; 381 return 0;
382} 382}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 505bc12a3031..602b71a92d3c 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -46,6 +46,10 @@ static char *def_vram;
46static int def_vrfb; 46static int def_vrfb;
47static int def_rotate; 47static int def_rotate;
48static int def_mirror; 48static int def_mirror;
49static bool auto_update;
50static unsigned int auto_update_freq;
51module_param(auto_update, bool, 0);
52module_param(auto_update_freq, uint, 0644);
49 53
50#ifdef DEBUG 54#ifdef DEBUG
51unsigned int omapfb_debug; 55unsigned int omapfb_debug;
@@ -1242,6 +1246,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1242 struct omapfb_info *ofbi = FB2OFB(fbi); 1246 struct omapfb_info *ofbi = FB2OFB(fbi);
1243 struct omapfb2_device *fbdev = ofbi->fbdev; 1247 struct omapfb2_device *fbdev = ofbi->fbdev;
1244 struct omap_dss_device *display = fb2display(fbi); 1248 struct omap_dss_device *display = fb2display(fbi);
1249 struct omapfb_display_data *d;
1245 int r = 0; 1250 int r = 0;
1246 1251
1247 if (!display) 1252 if (!display)
@@ -1249,6 +1254,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1249 1254
1250 omapfb_lock(fbdev); 1255 omapfb_lock(fbdev);
1251 1256
1257 d = get_display_data(fbdev, display);
1258
1252 switch (blank) { 1259 switch (blank) {
1253 case FB_BLANK_UNBLANK: 1260 case FB_BLANK_UNBLANK:
1254 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1261 if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
@@ -1257,6 +1264,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1257 if (display->driver->resume) 1264 if (display->driver->resume)
1258 r = display->driver->resume(display); 1265 r = display->driver->resume(display);
1259 1266
1267 if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
1268 d->update_mode == OMAPFB_AUTO_UPDATE &&
1269 !d->auto_update_work_enabled)
1270 omapfb_start_auto_update(fbdev, display);
1271
1260 break; 1272 break;
1261 1273
1262 case FB_BLANK_NORMAL: 1274 case FB_BLANK_NORMAL:
@@ -1268,6 +1280,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1268 if (display->state != OMAP_DSS_DISPLAY_ACTIVE) 1280 if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
1269 goto exit; 1281 goto exit;
1270 1282
1283 if (d->auto_update_work_enabled)
1284 omapfb_stop_auto_update(fbdev, display);
1285
1271 if (display->driver->suspend) 1286 if (display->driver->suspend)
1272 r = display->driver->suspend(display); 1287 r = display->driver->suspend(display);
1273 1288
@@ -1724,6 +1739,78 @@ err:
1724 return r; 1739 return r;
1725} 1740}
1726 1741
1742static void omapfb_auto_update_work(struct work_struct *work)
1743{
1744 struct omap_dss_device *dssdev;
1745 struct omap_dss_driver *dssdrv;
1746 struct omapfb_display_data *d;
1747 u16 w, h;
1748 unsigned int freq;
1749 struct omapfb2_device *fbdev;
1750
1751 d = container_of(work, struct omapfb_display_data,
1752 auto_update_work.work);
1753
1754 dssdev = d->dssdev;
1755 dssdrv = dssdev->driver;
1756 fbdev = d->fbdev;
1757
1758 if (!dssdrv || !dssdrv->update)
1759 return;
1760
1761 if (dssdrv->sync)
1762 dssdrv->sync(dssdev);
1763
1764 dssdrv->get_resolution(dssdev, &w, &h);
1765 dssdrv->update(dssdev, 0, 0, w, h);
1766
1767 freq = auto_update_freq;
1768 if (freq == 0)
1769 freq = 20;
1770 queue_delayed_work(fbdev->auto_update_wq,
1771 &d->auto_update_work, HZ / freq);
1772}
1773
1774void omapfb_start_auto_update(struct omapfb2_device *fbdev,
1775 struct omap_dss_device *display)
1776{
1777 struct omapfb_display_data *d;
1778
1779 if (fbdev->auto_update_wq == NULL) {
1780 struct workqueue_struct *wq;
1781
1782 wq = create_singlethread_workqueue("omapfb_auto_update");
1783
1784 if (wq == NULL) {
1785 dev_err(fbdev->dev, "Failed to create workqueue for "
1786 "auto-update\n");
1787 return;
1788 }
1789
1790 fbdev->auto_update_wq = wq;
1791 }
1792
1793 d = get_display_data(fbdev, display);
1794
1795 INIT_DELAYED_WORK(&d->auto_update_work, omapfb_auto_update_work);
1796
1797 d->auto_update_work_enabled = true;
1798
1799 omapfb_auto_update_work(&d->auto_update_work.work);
1800}
1801
1802void omapfb_stop_auto_update(struct omapfb2_device *fbdev,
1803 struct omap_dss_device *display)
1804{
1805 struct omapfb_display_data *d;
1806
1807 d = get_display_data(fbdev, display);
1808
1809 cancel_delayed_work_sync(&d->auto_update_work);
1810
1811 d->auto_update_work_enabled = false;
1812}
1813
1727/* initialize fb_info, var, fix to something sane based on the display */ 1814/* initialize fb_info, var, fix to something sane based on the display */
1728static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) 1815static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1729{ 1816{
@@ -1858,10 +1945,21 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1858 } 1945 }
1859 1946
1860 for (i = 0; i < fbdev->num_displays; i++) { 1947 for (i = 0; i < fbdev->num_displays; i++) {
1861 if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) 1948 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
1862 fbdev->displays[i]->driver->disable(fbdev->displays[i]); 1949
1950 if (fbdev->displays[i].auto_update_work_enabled)
1951 omapfb_stop_auto_update(fbdev, dssdev);
1952
1953 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
1954 dssdev->driver->disable(dssdev);
1955
1956 omap_dss_put_device(dssdev);
1957 }
1863 1958
1864 omap_dss_put_device(fbdev->displays[i]); 1959 if (fbdev->auto_update_wq != NULL) {
1960 flush_workqueue(fbdev->auto_update_wq);
1961 destroy_workqueue(fbdev->auto_update_wq);
1962 fbdev->auto_update_wq = NULL;
1865 } 1963 }
1866 1964
1867 dev_set_drvdata(fbdev->dev, NULL); 1965 dev_set_drvdata(fbdev->dev, NULL);
@@ -2084,14 +2182,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2084 int r; 2182 int r;
2085 u8 bpp; 2183 u8 bpp;
2086 struct omap_video_timings timings, temp_timings; 2184 struct omap_video_timings timings, temp_timings;
2185 struct omapfb_display_data *d;
2087 2186
2088 r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2187 r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
2089 if (r) 2188 if (r)
2090 return r; 2189 return r;
2091 2190
2092 fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display; 2191 d = get_display_data(fbdev, display);
2093 fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; 2192 d->bpp_override = bpp;
2094 ++fbdev->num_bpp_overrides;
2095 2193
2096 if (display->driver->check_timings) { 2194 if (display->driver->check_timings) {
2097 r = display->driver->check_timings(display, &timings); 2195 r = display->driver->check_timings(display, &timings);
@@ -2117,14 +2215,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
2117static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, 2215static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
2118 struct omap_dss_device *dssdev) 2216 struct omap_dss_device *dssdev)
2119{ 2217{
2120 int i; 2218 struct omapfb_display_data *d;
2121 2219
2122 BUG_ON(dssdev->driver->get_recommended_bpp == NULL); 2220 BUG_ON(dssdev->driver->get_recommended_bpp == NULL);
2123 2221
2124 for (i = 0; i < fbdev->num_bpp_overrides; ++i) { 2222 d = get_display_data(fbdev, dssdev);
2125 if (dssdev == fbdev->bpp_overrides[i].dssdev) 2223
2126 return fbdev->bpp_overrides[i].bpp; 2224 if (d->bpp_override != 0)
2127 } 2225 return d->bpp_override;
2128 2226
2129 return dssdev->driver->get_recommended_bpp(dssdev); 2227 return dssdev->driver->get_recommended_bpp(dssdev);
2130} 2228}
@@ -2156,9 +2254,9 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2156 2254
2157 display = NULL; 2255 display = NULL;
2158 for (i = 0; i < fbdev->num_displays; ++i) { 2256 for (i = 0; i < fbdev->num_displays; ++i) {
2159 if (strcmp(fbdev->displays[i]->name, 2257 if (strcmp(fbdev->displays[i].dssdev->name,
2160 display_str) == 0) { 2258 display_str) == 0) {
2161 display = fbdev->displays[i]; 2259 display = fbdev->displays[i].dssdev;
2162 break; 2260 break;
2163 } 2261 }
2164 } 2262 }
@@ -2182,6 +2280,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
2182 struct omap_dss_device *dssdev) 2280 struct omap_dss_device *dssdev)
2183{ 2281{
2184 struct omap_dss_driver *dssdrv = dssdev->driver; 2282 struct omap_dss_driver *dssdrv = dssdev->driver;
2283 struct omapfb_display_data *d;
2185 int r; 2284 int r;
2186 2285
2187 r = dssdrv->enable(dssdev); 2286 r = dssdrv->enable(dssdev);
@@ -2191,8 +2290,20 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
2191 return r; 2290 return r;
2192 } 2291 }
2193 2292
2293 d = get_display_data(fbdev, dssdev);
2294
2295 d->fbdev = fbdev;
2296
2194 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 2297 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2195 u16 w, h; 2298 u16 w, h;
2299
2300 if (auto_update) {
2301 omapfb_start_auto_update(fbdev, dssdev);
2302 d->update_mode = OMAPFB_AUTO_UPDATE;
2303 } else {
2304 d->update_mode = OMAPFB_MANUAL_UPDATE;
2305 }
2306
2196 if (dssdrv->enable_te) { 2307 if (dssdrv->enable_te) {
2197 r = dssdrv->enable_te(dssdev, 1); 2308 r = dssdrv->enable_te(dssdev, 1);
2198 if (r) { 2309 if (r) {
@@ -2201,16 +2312,6 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
2201 } 2312 }
2202 } 2313 }
2203 2314
2204 if (dssdrv->set_update_mode) {
2205 r = dssdrv->set_update_mode(dssdev,
2206 OMAP_DSS_UPDATE_MANUAL);
2207 if (r) {
2208 dev_err(fbdev->dev,
2209 "Failed to set update mode\n");
2210 return r;
2211 }
2212 }
2213
2214 dssdrv->get_resolution(dssdev, &w, &h); 2315 dssdrv->get_resolution(dssdev, &w, &h);
2215 r = dssdrv->update(dssdev, 0, 0, w, h); 2316 r = dssdrv->update(dssdev, 0, 0, w, h);
2216 if (r) { 2317 if (r) {
@@ -2219,15 +2320,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
2219 return r; 2320 return r;
2220 } 2321 }
2221 } else { 2322 } else {
2222 if (dssdrv->set_update_mode) { 2323 d->update_mode = OMAPFB_AUTO_UPDATE;
2223 r = dssdrv->set_update_mode(dssdev,
2224 OMAP_DSS_UPDATE_AUTO);
2225 if (r) {
2226 dev_err(fbdev->dev,
2227 "Failed to set update mode\n");
2228 return r;
2229 }
2230 }
2231 } 2324 }
2232 2325
2233 return 0; 2326 return 0;
@@ -2275,6 +2368,8 @@ static int omapfb_probe(struct platform_device *pdev)
2275 fbdev->num_displays = 0; 2368 fbdev->num_displays = 0;
2276 dssdev = NULL; 2369 dssdev = NULL;
2277 for_each_dss_dev(dssdev) { 2370 for_each_dss_dev(dssdev) {
2371 struct omapfb_display_data *d;
2372
2278 omap_dss_get_device(dssdev); 2373 omap_dss_get_device(dssdev);
2279 2374
2280 if (!dssdev->driver) { 2375 if (!dssdev->driver) {
@@ -2282,7 +2377,12 @@ static int omapfb_probe(struct platform_device *pdev)
2282 r = -ENODEV; 2377 r = -ENODEV;
2283 } 2378 }
2284 2379
2285 fbdev->displays[fbdev->num_displays++] = dssdev; 2380 d = &fbdev->displays[fbdev->num_displays++];
2381 d->dssdev = dssdev;
2382 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
2383 d->update_mode = OMAPFB_MANUAL_UPDATE;
2384 else
2385 d->update_mode = OMAPFB_AUTO_UPDATE;
2286 } 2386 }
2287 2387
2288 if (r) 2388 if (r)
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 2f5e817b2a9a..153bf1aceebc 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -518,6 +518,39 @@ static ssize_t show_virt(struct device *dev,
518 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr); 518 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
519} 519}
520 520
521static ssize_t show_upd_mode(struct device *dev,
522 struct device_attribute *attr, char *buf)
523{
524 struct fb_info *fbi = dev_get_drvdata(dev);
525 enum omapfb_update_mode mode;
526 int r;
527
528 r = omapfb_get_update_mode(fbi, &mode);
529
530 if (r)
531 return r;
532
533 return snprintf(buf, PAGE_SIZE, "%u\n", (unsigned)mode);
534}
535
536static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr,
537 const char *buf, size_t count)
538{
539 struct fb_info *fbi = dev_get_drvdata(dev);
540 unsigned mode;
541 int r;
542
543 r = kstrtouint(buf, 0, &mode);
544 if (r)
545 return r;
546
547 r = omapfb_set_update_mode(fbi, mode);
548 if (r)
549 return r;
550
551 return count;
552}
553
521static struct device_attribute omapfb_attrs[] = { 554static struct device_attribute omapfb_attrs[] = {
522 __ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type, 555 __ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type,
523 store_rotate_type), 556 store_rotate_type),
@@ -528,6 +561,7 @@ static struct device_attribute omapfb_attrs[] = {
528 store_overlays_rotate), 561 store_overlays_rotate),
529 __ATTR(phys_addr, S_IRUGO, show_phys, NULL), 562 __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
530 __ATTR(virt_addr, S_IRUGO, show_virt, NULL), 563 __ATTR(virt_addr, S_IRUGO, show_virt, NULL),
564 __ATTR(update_mode, S_IRUGO | S_IWUSR, show_upd_mode, store_upd_mode),
531}; 565};
532 566
533int omapfb_create_sysfs(struct omapfb2_device *fbdev) 567int omapfb_create_sysfs(struct omapfb2_device *fbdev)
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index aa1b1d974276..fdf0edeccf4e 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -73,6 +73,15 @@ struct omapfb_info {
73 bool mirror; 73 bool mirror;
74}; 74};
75 75
76struct omapfb_display_data {
77 struct omapfb2_device *fbdev;
78 struct omap_dss_device *dssdev;
79 u8 bpp_override;
80 enum omapfb_update_mode update_mode;
81 bool auto_update_work_enabled;
82 struct delayed_work auto_update_work;
83};
84
76struct omapfb2_device { 85struct omapfb2_device {
77 struct device *dev; 86 struct device *dev;
78 struct mutex mtx; 87 struct mutex mtx;
@@ -86,17 +95,13 @@ struct omapfb2_device {
86 struct omapfb2_mem_region regions[10]; 95 struct omapfb2_mem_region regions[10];
87 96
88 unsigned num_displays; 97 unsigned num_displays;
89 struct omap_dss_device *displays[10]; 98 struct omapfb_display_data displays[10];
90 unsigned num_overlays; 99 unsigned num_overlays;
91 struct omap_overlay *overlays[10]; 100 struct omap_overlay *overlays[10];
92 unsigned num_managers; 101 unsigned num_managers;
93 struct omap_overlay_manager *managers[10]; 102 struct omap_overlay_manager *managers[10];
94 103
95 unsigned num_bpp_overrides; 104 struct workqueue_struct *auto_update_wq;
96 struct {
97 struct omap_dss_device *dssdev;
98 u8 bpp;
99 } bpp_overrides[10];
100}; 105};
101 106
102struct omapfb_colormode { 107struct omapfb_colormode {
@@ -128,6 +133,13 @@ int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
128int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, 133int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
129 u16 posx, u16 posy, u16 outw, u16 outh); 134 u16 posx, u16 posy, u16 outw, u16 outh);
130 135
136void omapfb_start_auto_update(struct omapfb2_device *fbdev,
137 struct omap_dss_device *display);
138void omapfb_stop_auto_update(struct omapfb2_device *fbdev,
139 struct omap_dss_device *display);
140int omapfb_get_update_mode(struct fb_info *fbi, enum omapfb_update_mode *mode);
141int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
142
131/* find the display connected to this fb, if any */ 143/* find the display connected to this fb, if any */
132static inline struct omap_dss_device *fb2display(struct fb_info *fbi) 144static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
133{ 145{
@@ -143,6 +155,19 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
143 return NULL; 155 return NULL;
144} 156}
145 157
158static inline struct omapfb_display_data *get_display_data(
159 struct omapfb2_device *fbdev, struct omap_dss_device *dssdev)
160{
161 int i;
162
163 for (i = 0; i < fbdev->num_displays; ++i)
164 if (fbdev->displays[i].dssdev == dssdev)
165 return &fbdev->displays[i];
166
167 /* This should never happen */
168 BUG();
169}
170
146static inline void omapfb_lock(struct omapfb2_device *fbdev) 171static inline void omapfb_lock(struct omapfb2_device *fbdev)
147{ 172{
148 mutex_lock(&fbdev->mtx); 173 mutex_lock(&fbdev->mtx);
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index 32549d177b19..dcaab9012ca2 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -55,7 +55,7 @@
55 55
56#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) 56#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
57 57
58#define S3_SAVAGE4_SERIES(chip) ((chip>=S3_SAVAGE4) || (chip<=S3_PROSAVAGEDDR)) 58#define S3_SAVAGE4_SERIES(chip) ((chip>=S3_SAVAGE4) && (chip<=S3_PROSAVAGEDDR))
59 59
60#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) 60#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
61 61
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 019dbd3f12b2..b048417247e8 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -24,7 +24,7 @@
24#include <linux/backlight.h> 24#include <linux/backlight.h>
25#include <linux/gpio.h> 25#include <linux/gpio.h>
26#include <video/sh_mobile_lcdc.h> 26#include <video/sh_mobile_lcdc.h>
27#include <asm/atomic.h> 27#include <linux/atomic.h>
28 28
29#include "sh_mobile_lcdcfb.h" 29#include "sh_mobile_lcdcfb.h"
30#include "sh_mobile_meram.h" 30#include "sh_mobile_meram.h"
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h
index 7491abfcf1fc..43d11ec197fc 100644
--- a/drivers/video/vermilion/vermilion.h
+++ b/drivers/video/vermilion/vermilion.h
@@ -31,7 +31,7 @@
31 31
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <asm/atomic.h> 34#include <linux/atomic.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36 36
37#define VML_DEVICE_GPU 0x5002 37#define VML_DEVICE_GPU 0x5002