aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r--drivers/video/omap2/dss/Kconfig47
-rw-r--r--drivers/video/omap2/dss/Makefile4
-rw-r--r--drivers/video/omap2/dss/core.c496
-rw-r--r--drivers/video/omap2/dss/dispc.c2467
-rw-r--r--drivers/video/omap2/dss/dispc.h691
-rw-r--r--drivers/video/omap2/dss/display.c81
-rw-r--r--drivers/video/omap2/dss/dpi.c180
-rw-r--r--drivers/video/omap2/dss/dsi.c2938
-rw-r--r--drivers/video/omap2/dss/dss.c831
-rw-r--r--drivers/video/omap2/dss/dss.h246
-rw-r--r--drivers/video/omap2/dss/dss_features.c433
-rw-r--r--drivers/video/omap2/dss/dss_features.h96
-rw-r--r--drivers/video/omap2/dss/hdmi.c1763
-rw-r--r--drivers/video/omap2/dss/hdmi.h631
-rw-r--r--drivers/video/omap2/dss/hdmi_omap4_panel.c222
-rw-r--r--drivers/video/omap2/dss/manager.c138
-rw-r--r--drivers/video/omap2/dss/overlay.c128
-rw-r--r--drivers/video/omap2/dss/rfbi.c310
-rw-r--r--drivers/video/omap2/dss/sdi.c86
-rw-r--r--drivers/video/omap2/dss/venc.c151
20 files changed, 8950 insertions, 2989 deletions
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43b64403eaa4..6b3e2da11419 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,8 +1,8 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" 2 tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
3 depends on ARCH_OMAP2 || ARCH_OMAP3 3 depends on ARCH_OMAP2PLUS
4 help 4 help
5 OMAP2/3 Display Subsystem support. 5 OMAP2+ Display Subsystem support.
6 6
7if OMAP2_DSS 7if OMAP2_DSS
8 8
@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
60 help 60 help
61 OMAP Video Encoder support for S-Video and composite TV-out. 61 OMAP Video Encoder support for S-Video and composite TV-out.
62 62
63config OMAP4_DSS_HDMI
64 bool "HDMI support"
65 depends on ARCH_OMAP4
66 default y
67 help
68 HDMI Interface. This adds the High Definition Multimedia Interface.
69 See http://www.hdmi.org/ for HDMI specification.
70
63config OMAP2_DSS_SDI 71config OMAP2_DSS_SDI
64 bool "SDI support" 72 bool "SDI support"
65 depends on ARCH_OMAP3 73 depends on ARCH_OMAP3
@@ -72,7 +80,7 @@ config OMAP2_DSS_SDI
72 80
73config OMAP2_DSS_DSI 81config OMAP2_DSS_DSI
74 bool "DSI support" 82 bool "DSI support"
75 depends on ARCH_OMAP3 83 depends on ARCH_OMAP3 || ARCH_OMAP4
76 default n 84 default n
77 help 85 help
78 MIPI DSI (Display Serial Interface) support. 86 MIPI DSI (Display Serial Interface) support.
@@ -82,14 +90,6 @@ config OMAP2_DSS_DSI
82 90
83 See http://www.mipi.org/ for DSI spesifications. 91 See http://www.mipi.org/ for DSI spesifications.
84 92
85config OMAP2_DSS_USE_DSI_PLL
86 bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
87 default n
88 depends on OMAP2_DSS_DSI
89 help
90 Use DSI PLL to generate pixel clock. Currently only for DPI output.
91 DSI PLL can be used to generate higher and more precise pixel clocks.
92
93config OMAP2_DSS_FAKE_VSYNC 93config OMAP2_DSS_FAKE_VSYNC
94 bool "Fake VSYNC irq from manual update displays" 94 bool "Fake VSYNC irq from manual update displays"
95 default n 95 default n
@@ -117,4 +117,27 @@ 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
133 bool "Sleep 20ms after VENC reset"
134 default y
135 help
136 There is a 20ms sleep after VENC reset which seemed to fix the
137 reset. The reason for the bug is unclear, and it's also unclear
138 on what platforms this happens.
139
140 This option enables the sleep, and is enabled by default. You can
141 disable the sleep if it doesn't cause problems on your platform.
142
120endif 143endif
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index d71b5d9d71b1..10d9d3bb3e24 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,7 +1,9 @@
1obj-$(CONFIG_OMAP2_DSS) += omapdss.o 1obj-$(CONFIG_OMAP2_DSS) += omapdss.o
2omapdss-y := core.o dss.o dispc.o display.o manager.o overlay.o 2omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o
3omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o 3omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
4omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o 4omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 5omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
9 hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index b3a498f22d36..3da426719dd6 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -33,331 +33,29 @@
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <video/omapdss.h>
37#include <plat/clock.h>
38 37
39#include "dss.h" 38#include "dss.h"
39#include "dss_features.h"
40 40
41static struct { 41static struct {
42 struct platform_device *pdev; 42 struct platform_device *pdev;
43 int ctx_id;
44
45 struct clk *dss_ick;
46 struct clk *dss1_fck;
47 struct clk *dss2_fck;
48 struct clk *dss_54m_fck;
49 struct clk *dss_96m_fck;
50 unsigned num_clks_enabled;
51 43
52 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
53 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
54 struct regulator *vdda_dac_reg;
55} core; 46} core;
56 47
57static void dss_clk_enable_all_no_ctx(void);
58static void dss_clk_disable_all_no_ctx(void);
59static void dss_clk_enable_no_ctx(enum dss_clock clks);
60static void dss_clk_disable_no_ctx(enum dss_clock clks);
61
62static char *def_disp_name; 48static char *def_disp_name;
63module_param_named(def_disp, def_disp_name, charp, 0); 49module_param_named(def_disp, def_disp_name, charp, 0);
64MODULE_PARM_DESC(def_disp_name, "default display name"); 50MODULE_PARM_DESC(def_disp, "default display name");
65 51
66#ifdef DEBUG 52#ifdef DEBUG
67unsigned int dss_debug; 53unsigned int dss_debug;
68module_param_named(debug, dss_debug, bool, 0644); 54module_param_named(debug, dss_debug, bool, 0644);
69#endif 55#endif
70 56
71/* CONTEXT */ 57static int omap_dss_register_device(struct omap_dss_device *);
72static int dss_get_ctx_id(void) 58static void omap_dss_unregister_device(struct omap_dss_device *);
73{
74 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
75 int r;
76
77 if (!pdata->get_last_off_on_transaction_id)
78 return 0;
79 r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
80 if (r < 0) {
81 dev_err(&core.pdev->dev, "getting transaction ID failed, "
82 "will force context restore\n");
83 r = -1;
84 }
85 return r;
86}
87
88int dss_need_ctx_restore(void)
89{
90 int id = dss_get_ctx_id();
91
92 if (id < 0 || id != core.ctx_id) {
93 DSSDBG("ctx id %d -> id %d\n",
94 core.ctx_id, id);
95 core.ctx_id = id;
96 return 1;
97 } else {
98 return 0;
99 }
100}
101
102static void save_all_ctx(void)
103{
104 DSSDBG("save context\n");
105
106 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
107
108 dss_save_context();
109 dispc_save_context();
110#ifdef CONFIG_OMAP2_DSS_DSI
111 dsi_save_context();
112#endif
113
114 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
115}
116
117static void restore_all_ctx(void)
118{
119 DSSDBG("restore context\n");
120
121 dss_clk_enable_all_no_ctx();
122
123 dss_restore_context();
124 dispc_restore_context();
125#ifdef CONFIG_OMAP2_DSS_DSI
126 dsi_restore_context();
127#endif
128
129 dss_clk_disable_all_no_ctx();
130}
131
132#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
133/* CLOCKS */
134static void core_dump_clocks(struct seq_file *s)
135{
136 int i;
137 struct clk *clocks[5] = {
138 core.dss_ick,
139 core.dss1_fck,
140 core.dss2_fck,
141 core.dss_54m_fck,
142 core.dss_96m_fck
143 };
144
145 seq_printf(s, "- CORE -\n");
146
147 seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
148
149 for (i = 0; i < 5; i++) {
150 if (!clocks[i])
151 continue;
152 seq_printf(s, "%-15s\t%lu\t%d\n",
153 clocks[i]->name,
154 clk_get_rate(clocks[i]),
155 clocks[i]->usecount);
156 }
157}
158#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
159
160static int dss_get_clock(struct clk **clock, const char *clk_name)
161{
162 struct clk *clk;
163
164 clk = clk_get(&core.pdev->dev, clk_name);
165
166 if (IS_ERR(clk)) {
167 DSSERR("can't get clock %s", clk_name);
168 return PTR_ERR(clk);
169 }
170
171 *clock = clk;
172
173 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
174
175 return 0;
176}
177
178static int dss_get_clocks(void)
179{
180 int r;
181
182 core.dss_ick = NULL;
183 core.dss1_fck = NULL;
184 core.dss2_fck = NULL;
185 core.dss_54m_fck = NULL;
186 core.dss_96m_fck = NULL;
187
188 r = dss_get_clock(&core.dss_ick, "ick");
189 if (r)
190 goto err;
191
192 r = dss_get_clock(&core.dss1_fck, "dss1_fck");
193 if (r)
194 goto err;
195
196 r = dss_get_clock(&core.dss2_fck, "dss2_fck");
197 if (r)
198 goto err;
199
200 r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
201 if (r)
202 goto err;
203
204 r = dss_get_clock(&core.dss_96m_fck, "video_fck");
205 if (r)
206 goto err;
207
208 return 0;
209
210err:
211 if (core.dss_ick)
212 clk_put(core.dss_ick);
213 if (core.dss1_fck)
214 clk_put(core.dss1_fck);
215 if (core.dss2_fck)
216 clk_put(core.dss2_fck);
217 if (core.dss_54m_fck)
218 clk_put(core.dss_54m_fck);
219 if (core.dss_96m_fck)
220 clk_put(core.dss_96m_fck);
221
222 return r;
223}
224
225static void dss_put_clocks(void)
226{
227 if (core.dss_96m_fck)
228 clk_put(core.dss_96m_fck);
229 clk_put(core.dss_54m_fck);
230 clk_put(core.dss1_fck);
231 clk_put(core.dss2_fck);
232 clk_put(core.dss_ick);
233}
234
235unsigned long dss_clk_get_rate(enum dss_clock clk)
236{
237 switch (clk) {
238 case DSS_CLK_ICK:
239 return clk_get_rate(core.dss_ick);
240 case DSS_CLK_FCK1:
241 return clk_get_rate(core.dss1_fck);
242 case DSS_CLK_FCK2:
243 return clk_get_rate(core.dss2_fck);
244 case DSS_CLK_54M:
245 return clk_get_rate(core.dss_54m_fck);
246 case DSS_CLK_96M:
247 return clk_get_rate(core.dss_96m_fck);
248 }
249
250 BUG();
251 return 0;
252}
253
254static unsigned count_clk_bits(enum dss_clock clks)
255{
256 unsigned num_clks = 0;
257
258 if (clks & DSS_CLK_ICK)
259 ++num_clks;
260 if (clks & DSS_CLK_FCK1)
261 ++num_clks;
262 if (clks & DSS_CLK_FCK2)
263 ++num_clks;
264 if (clks & DSS_CLK_54M)
265 ++num_clks;
266 if (clks & DSS_CLK_96M)
267 ++num_clks;
268
269 return num_clks;
270}
271
272static void dss_clk_enable_no_ctx(enum dss_clock clks)
273{
274 unsigned num_clks = count_clk_bits(clks);
275
276 if (clks & DSS_CLK_ICK)
277 clk_enable(core.dss_ick);
278 if (clks & DSS_CLK_FCK1)
279 clk_enable(core.dss1_fck);
280 if (clks & DSS_CLK_FCK2)
281 clk_enable(core.dss2_fck);
282 if (clks & DSS_CLK_54M)
283 clk_enable(core.dss_54m_fck);
284 if (clks & DSS_CLK_96M)
285 clk_enable(core.dss_96m_fck);
286
287 core.num_clks_enabled += num_clks;
288}
289
290void dss_clk_enable(enum dss_clock clks)
291{
292 bool check_ctx = core.num_clks_enabled == 0;
293
294 dss_clk_enable_no_ctx(clks);
295
296 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
297 restore_all_ctx();
298}
299
300static void dss_clk_disable_no_ctx(enum dss_clock clks)
301{
302 unsigned num_clks = count_clk_bits(clks);
303
304 if (clks & DSS_CLK_ICK)
305 clk_disable(core.dss_ick);
306 if (clks & DSS_CLK_FCK1)
307 clk_disable(core.dss1_fck);
308 if (clks & DSS_CLK_FCK2)
309 clk_disable(core.dss2_fck);
310 if (clks & DSS_CLK_54M)
311 clk_disable(core.dss_54m_fck);
312 if (clks & DSS_CLK_96M)
313 clk_disable(core.dss_96m_fck);
314
315 core.num_clks_enabled -= num_clks;
316}
317
318void dss_clk_disable(enum dss_clock clks)
319{
320 if (cpu_is_omap34xx()) {
321 unsigned num_clks = count_clk_bits(clks);
322
323 BUG_ON(core.num_clks_enabled < num_clks);
324
325 if (core.num_clks_enabled == num_clks)
326 save_all_ctx();
327 }
328
329 dss_clk_disable_no_ctx(clks);
330}
331
332static void dss_clk_enable_all_no_ctx(void)
333{
334 enum dss_clock clks;
335
336 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
337 if (cpu_is_omap34xx())
338 clks |= DSS_CLK_96M;
339 dss_clk_enable_no_ctx(clks);
340}
341
342static void dss_clk_disable_all_no_ctx(void)
343{
344 enum dss_clock clks;
345
346 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
347 if (cpu_is_omap34xx())
348 clks |= DSS_CLK_96M;
349 dss_clk_disable_no_ctx(clks);
350}
351
352static void dss_clk_disable_all(void)
353{
354 enum dss_clock clks;
355
356 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
357 if (cpu_is_omap34xx())
358 clks |= DSS_CLK_96M;
359 dss_clk_disable(clks);
360}
361 59
362/* REGULATORS */ 60/* REGULATORS */
363 61
@@ -389,32 +87,7 @@ struct regulator *dss_get_vdds_sdi(void)
389 return reg; 87 return reg;
390} 88}
391 89
392struct regulator *dss_get_vdda_dac(void)
393{
394 struct regulator *reg;
395
396 if (core.vdda_dac_reg != NULL)
397 return core.vdda_dac_reg;
398
399 reg = regulator_get(&core.pdev->dev, "vdda_dac");
400 if (!IS_ERR(reg))
401 core.vdda_dac_reg = reg;
402
403 return reg;
404}
405
406/* DEBUGFS */
407#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 90#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
408static void dss_debug_dump_clocks(struct seq_file *s)
409{
410 core_dump_clocks(s);
411 dss_dump_clocks(s);
412 dispc_dump_clocks(s);
413#ifdef CONFIG_OMAP2_DSS_DSI
414 dsi_dump_clocks(s);
415#endif
416}
417
418static int dss_debug_show(struct seq_file *s, void *unused) 91static int dss_debug_show(struct seq_file *s, void *unused)
419{ 92{
420 void (*func)(struct seq_file *) = s->private; 93 void (*func)(struct seq_file *) = s->private;
@@ -454,8 +127,7 @@ static int dss_initialize_debugfs(void)
454#endif 127#endif
455 128
456#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS) 129#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
457 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, 130 dsi_create_debugfs_files_irq(dss_debugfs_dir, &dss_debug_fops);
458 &dsi_dump_irqs, &dss_debug_fops);
459#endif 131#endif
460 132
461 debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, 133 debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
@@ -467,8 +139,7 @@ static int dss_initialize_debugfs(void)
467 &rfbi_dump_regs, &dss_debug_fops); 139 &rfbi_dump_regs, &dss_debug_fops);
468#endif 140#endif
469#ifdef CONFIG_OMAP2_DSS_DSI 141#ifdef CONFIG_OMAP2_DSS_DSI
470 debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir, 142 dsi_create_debugfs_files_reg(dss_debugfs_dir, &dss_debug_fops);
471 &dsi_dump_regs, &dss_debug_fops);
472#endif 143#endif
473#ifdef CONFIG_OMAP2_DSS_VENC 144#ifdef CONFIG_OMAP2_DSS_VENC
474 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir, 145 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
@@ -496,72 +167,53 @@ static inline void dss_uninitialize_debugfs(void)
496static int omap_dss_probe(struct platform_device *pdev) 167static int omap_dss_probe(struct platform_device *pdev)
497{ 168{
498 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 169 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
499 int skip_init = 0;
500 int r; 170 int r;
501 int i; 171 int i;
502 172
503 core.pdev = pdev; 173 core.pdev = pdev;
504 174
175 dss_features_init();
176
505 dss_init_overlay_managers(pdev); 177 dss_init_overlay_managers(pdev);
506 dss_init_overlays(pdev); 178 dss_init_overlays(pdev);
507 179
508 r = dss_get_clocks(); 180 r = dss_init_platform_driver();
509 if (r)
510 goto err_clocks;
511
512 dss_clk_enable_all_no_ctx();
513
514 core.ctx_id = dss_get_ctx_id();
515 DSSDBG("initial ctx id %u\n", core.ctx_id);
516
517#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
518 /* DISPC_CONTROL */
519 if (omap_readl(0x48050440) & 1) /* LCD enabled? */
520 skip_init = 1;
521#endif
522
523 r = dss_init(skip_init);
524 if (r) { 181 if (r) {
525 DSSERR("Failed to initialize DSS\n"); 182 DSSERR("Failed to initialize DSS platform driver\n");
526 goto err_dss; 183 goto err_dss;
527 } 184 }
528 185
529 r = rfbi_init(); 186 /* keep clocks enabled to prevent context saves/restores during init */
530 if (r) { 187 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
531 DSSERR("Failed to initialize rfbi\n");
532 goto err_rfbi;
533 }
534 188
535 r = dpi_init(pdev); 189 r = rfbi_init_platform_driver();
536 if (r) { 190 if (r) {
537 DSSERR("Failed to initialize dpi\n"); 191 DSSERR("Failed to initialize rfbi platform driver\n");
538 goto err_dpi; 192 goto err_rfbi;
539 } 193 }
540 194
541 r = dispc_init(); 195 r = dispc_init_platform_driver();
542 if (r) { 196 if (r) {
543 DSSERR("Failed to initialize dispc\n"); 197 DSSERR("Failed to initialize dispc platform driver\n");
544 goto err_dispc; 198 goto err_dispc;
545 } 199 }
546 200
547 r = venc_init(pdev); 201 r = venc_init_platform_driver();
548 if (r) { 202 if (r) {
549 DSSERR("Failed to initialize venc\n"); 203 DSSERR("Failed to initialize venc platform driver\n");
550 goto err_venc; 204 goto err_venc;
551 } 205 }
552 206
553 if (cpu_is_omap34xx()) { 207 r = dsi_init_platform_driver();
554 r = sdi_init(skip_init); 208 if (r) {
555 if (r) { 209 DSSERR("Failed to initialize DSI platform driver\n");
556 DSSERR("Failed to initialize SDI\n"); 210 goto err_dsi;
557 goto err_sdi; 211 }
558 }
559 212
560 r = dsi_init(pdev); 213 r = hdmi_init_platform_driver();
561 if (r) { 214 if (r) {
562 DSSERR("Failed to initialize DSI\n"); 215 DSSERR("Failed to initialize hdmi\n");
563 goto err_dsi; 216 goto err_hdmi;
564 }
565 } 217 }
566 218
567 r = dss_initialize_debugfs(); 219 r = dss_initialize_debugfs();
@@ -586,32 +238,25 @@ static int omap_dss_probe(struct platform_device *pdev)
586 pdata->default_device = dssdev; 238 pdata->default_device = dssdev;
587 } 239 }
588 240
589 dss_clk_disable_all(); 241 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
590 242
591 return 0; 243 return 0;
592 244
593err_register: 245err_register:
594 dss_uninitialize_debugfs(); 246 dss_uninitialize_debugfs();
595err_debugfs: 247err_debugfs:
596 if (cpu_is_omap34xx()) 248 hdmi_uninit_platform_driver();
597 dsi_exit(); 249err_hdmi:
250 dsi_uninit_platform_driver();
598err_dsi: 251err_dsi:
599 if (cpu_is_omap34xx()) 252 venc_uninit_platform_driver();
600 sdi_exit();
601err_sdi:
602 venc_exit();
603err_venc: 253err_venc:
604 dispc_exit(); 254 dispc_uninit_platform_driver();
605err_dispc: 255err_dispc:
606 dpi_exit(); 256 rfbi_uninit_platform_driver();
607err_dpi:
608 rfbi_exit();
609err_rfbi: 257err_rfbi:
610 dss_exit(); 258 dss_uninit_platform_driver();
611err_dss: 259err_dss:
612 dss_clk_disable_all_no_ctx();
613 dss_put_clocks();
614err_clocks:
615 260
616 return r; 261 return r;
617} 262}
@@ -620,61 +265,15 @@ static int omap_dss_remove(struct platform_device *pdev)
620{ 265{
621 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 266 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
622 int i; 267 int i;
623 int c;
624 268
625 dss_uninitialize_debugfs(); 269 dss_uninitialize_debugfs();
626 270
627 venc_exit(); 271 venc_uninit_platform_driver();
628 dispc_exit(); 272 dispc_uninit_platform_driver();
629 dpi_exit(); 273 rfbi_uninit_platform_driver();
630 rfbi_exit(); 274 dsi_uninit_platform_driver();
631 if (cpu_is_omap34xx()) { 275 hdmi_uninit_platform_driver();
632 dsi_exit(); 276 dss_uninit_platform_driver();
633 sdi_exit();
634 }
635
636 dss_exit();
637
638 /* these should be removed at some point */
639 c = core.dss_ick->usecount;
640 if (c > 0) {
641 DSSERR("warning: dss_ick usecount %d, disabling\n", c);
642 while (c-- > 0)
643 clk_disable(core.dss_ick);
644 }
645
646 c = core.dss1_fck->usecount;
647 if (c > 0) {
648 DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
649 while (c-- > 0)
650 clk_disable(core.dss1_fck);
651 }
652
653 c = core.dss2_fck->usecount;
654 if (c > 0) {
655 DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
656 while (c-- > 0)
657 clk_disable(core.dss2_fck);
658 }
659
660 c = core.dss_54m_fck->usecount;
661 if (c > 0) {
662 DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
663 while (c-- > 0)
664 clk_disable(core.dss_54m_fck);
665 }
666
667 if (core.dss_96m_fck) {
668 c = core.dss_96m_fck->usecount;
669 if (c > 0) {
670 DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
671 c);
672 while (c-- > 0)
673 clk_disable(core.dss_96m_fck);
674 }
675 }
676
677 dss_put_clocks();
678 277
679 dss_uninit_overlays(pdev); 278 dss_uninit_overlays(pdev);
680 dss_uninit_overlay_managers(pdev); 279 dss_uninit_overlay_managers(pdev);
@@ -882,7 +481,7 @@ static void omap_dss_dev_release(struct device *dev)
882 reset_device(dev, 0); 481 reset_device(dev, 0);
883} 482}
884 483
885int omap_dss_register_device(struct omap_dss_device *dssdev) 484static int omap_dss_register_device(struct omap_dss_device *dssdev)
886{ 485{
887 static int dev_num; 486 static int dev_num;
888 487
@@ -896,7 +495,7 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
896 return device_register(&dssdev->dev); 495 return device_register(&dssdev->dev);
897} 496}
898 497
899void omap_dss_unregister_device(struct omap_dss_device *dssdev) 498static void omap_dss_unregister_device(struct omap_dss_device *dssdev)
900{ 499{
901 device_unregister(&dssdev->dev); 500 device_unregister(&dssdev->dev);
902} 501}
@@ -962,11 +561,6 @@ static void __exit omap_dss_exit(void)
962 core.vdds_sdi_reg = NULL; 561 core.vdds_sdi_reg = NULL;
963 } 562 }
964 563
965 if (core.vdda_dac_reg != NULL) {
966 regulator_put(core.vdda_dac_reg);
967 core.vdda_dac_reg = NULL;
968 }
969
970 platform_driver_unregister(&omap_dss_driver); 564 platform_driver_unregister(&omap_dss_driver);
971 565
972 omap_dss_bus_unregister(); 566 omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5ecdc0004094..7a9a2e7d9685 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -32,97 +32,19 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
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 36
36#include <plat/sram.h> 37#include <plat/sram.h>
37#include <plat/clock.h> 38#include <plat/clock.h>
38 39
39#include <plat/display.h> 40#include <video/omapdss.h>
40 41
41#include "dss.h" 42#include "dss.h"
43#include "dss_features.h"
44#include "dispc.h"
42 45
43/* DISPC */ 46/* DISPC */
44#define DISPC_BASE 0x48050400 47#define DISPC_SZ_REGS SZ_4K
45
46#define DISPC_SZ_REGS SZ_1K
47
48struct dispc_reg { u16 idx; };
49
50#define DISPC_REG(idx) ((const struct dispc_reg) { idx })
51
52/* DISPC common */
53#define DISPC_REVISION DISPC_REG(0x0000)
54#define DISPC_SYSCONFIG DISPC_REG(0x0010)
55#define DISPC_SYSSTATUS DISPC_REG(0x0014)
56#define DISPC_IRQSTATUS DISPC_REG(0x0018)
57#define DISPC_IRQENABLE DISPC_REG(0x001C)
58#define DISPC_CONTROL DISPC_REG(0x0040)
59#define DISPC_CONFIG DISPC_REG(0x0044)
60#define DISPC_CAPABLE DISPC_REG(0x0048)
61#define DISPC_DEFAULT_COLOR0 DISPC_REG(0x004C)
62#define DISPC_DEFAULT_COLOR1 DISPC_REG(0x0050)
63#define DISPC_TRANS_COLOR0 DISPC_REG(0x0054)
64#define DISPC_TRANS_COLOR1 DISPC_REG(0x0058)
65#define DISPC_LINE_STATUS DISPC_REG(0x005C)
66#define DISPC_LINE_NUMBER DISPC_REG(0x0060)
67#define DISPC_TIMING_H DISPC_REG(0x0064)
68#define DISPC_TIMING_V DISPC_REG(0x0068)
69#define DISPC_POL_FREQ DISPC_REG(0x006C)
70#define DISPC_DIVISOR DISPC_REG(0x0070)
71#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
72#define DISPC_SIZE_DIG DISPC_REG(0x0078)
73#define DISPC_SIZE_LCD DISPC_REG(0x007C)
74
75/* DISPC GFX plane */
76#define DISPC_GFX_BA0 DISPC_REG(0x0080)
77#define DISPC_GFX_BA1 DISPC_REG(0x0084)
78#define DISPC_GFX_POSITION DISPC_REG(0x0088)
79#define DISPC_GFX_SIZE DISPC_REG(0x008C)
80#define DISPC_GFX_ATTRIBUTES DISPC_REG(0x00A0)
81#define DISPC_GFX_FIFO_THRESHOLD DISPC_REG(0x00A4)
82#define DISPC_GFX_FIFO_SIZE_STATUS DISPC_REG(0x00A8)
83#define DISPC_GFX_ROW_INC DISPC_REG(0x00AC)
84#define DISPC_GFX_PIXEL_INC DISPC_REG(0x00B0)
85#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4)
86#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8)
87
88#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4)
89#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8)
90#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC)
91
92#define DISPC_CPR_COEF_R DISPC_REG(0x0220)
93#define DISPC_CPR_COEF_G DISPC_REG(0x0224)
94#define DISPC_CPR_COEF_B DISPC_REG(0x0228)
95
96#define DISPC_GFX_PRELOAD DISPC_REG(0x022C)
97
98/* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */
99#define DISPC_VID_REG(n, idx) DISPC_REG(0x00BC + (n)*0x90 + idx)
100
101#define DISPC_VID_BA0(n) DISPC_VID_REG(n, 0x0000)
102#define DISPC_VID_BA1(n) DISPC_VID_REG(n, 0x0004)
103#define DISPC_VID_POSITION(n) DISPC_VID_REG(n, 0x0008)
104#define DISPC_VID_SIZE(n) DISPC_VID_REG(n, 0x000C)
105#define DISPC_VID_ATTRIBUTES(n) DISPC_VID_REG(n, 0x0010)
106#define DISPC_VID_FIFO_THRESHOLD(n) DISPC_VID_REG(n, 0x0014)
107#define DISPC_VID_FIFO_SIZE_STATUS(n) DISPC_VID_REG(n, 0x0018)
108#define DISPC_VID_ROW_INC(n) DISPC_VID_REG(n, 0x001C)
109#define DISPC_VID_PIXEL_INC(n) DISPC_VID_REG(n, 0x0020)
110#define DISPC_VID_FIR(n) DISPC_VID_REG(n, 0x0024)
111#define DISPC_VID_PICTURE_SIZE(n) DISPC_VID_REG(n, 0x0028)
112#define DISPC_VID_ACCU0(n) DISPC_VID_REG(n, 0x002C)
113#define DISPC_VID_ACCU1(n) DISPC_VID_REG(n, 0x0030)
114
115/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
116#define DISPC_VID_FIR_COEF_H(n, i) DISPC_REG(0x00F0 + (n)*0x90 + (i)*0x8)
117/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
118#define DISPC_VID_FIR_COEF_HV(n, i) DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8)
119/* coef index i = {0, 1, 2, 3, 4} */
120#define DISPC_VID_CONV_COEF(n, i) DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4)
121/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
122#define DISPC_VID_FIR_COEF_V(n, i) DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4)
123
124#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
125
126 48
127#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ 49#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
128 DISPC_IRQ_OCP_ERR | \ 50 DISPC_IRQ_OCP_ERR | \
@@ -139,16 +61,28 @@ struct omap_dispc_isr_data {
139 u32 mask; 61 u32 mask;
140}; 62};
141 63
64struct dispc_h_coef {
65 s8 hc4;
66 s8 hc3;
67 u8 hc2;
68 s8 hc1;
69 s8 hc0;
70};
71
72struct dispc_v_coef {
73 s8 vc22;
74 s8 vc2;
75 u8 vc1;
76 s8 vc0;
77 s8 vc00;
78};
79
142#define REG_GET(idx, start, end) \ 80#define REG_GET(idx, start, end) \
143 FLD_GET(dispc_read_reg(idx), start, end) 81 FLD_GET(dispc_read_reg(idx), start, end)
144 82
145#define REG_FLD_MOD(idx, val, start, end) \ 83#define REG_FLD_MOD(idx, val, start, end) \
146 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end)) 84 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
147 85
148static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES,
149 DISPC_VID_ATTRIBUTES(0),
150 DISPC_VID_ATTRIBUTES(1) };
151
152struct dispc_irq_stats { 86struct dispc_irq_stats {
153 unsigned long last_reset; 87 unsigned long last_reset;
154 unsigned irq_count; 88 unsigned irq_count;
@@ -156,7 +90,9 @@ struct dispc_irq_stats {
156}; 90};
157 91
158static struct { 92static struct {
93 struct platform_device *pdev;
159 void __iomem *base; 94 void __iomem *base;
95 int irq;
160 96
161 u32 fifo_size[3]; 97 u32 fifo_size[3];
162 98
@@ -174,25 +110,38 @@ static struct {
174#endif 110#endif
175} dispc; 111} dispc;
176 112
113enum omap_color_component {
114 /* used for all color formats for OMAP3 and earlier
115 * and for RGB and Y color component on OMAP4
116 */
117 DISPC_COLOR_COMPONENT_RGB_Y = 1 << 0,
118 /* used for UV component for
119 * OMAP_DSS_COLOR_YUV2, OMAP_DSS_COLOR_UYVY, OMAP_DSS_COLOR_NV12
120 * color formats on OMAP4
121 */
122 DISPC_COLOR_COMPONENT_UV = 1 << 1,
123};
124
177static void _omap_dispc_set_irqs(void); 125static void _omap_dispc_set_irqs(void);
178 126
179static inline void dispc_write_reg(const struct dispc_reg idx, u32 val) 127static inline void dispc_write_reg(const u16 idx, u32 val)
180{ 128{
181 __raw_writel(val, dispc.base + idx.idx); 129 __raw_writel(val, dispc.base + idx);
182} 130}
183 131
184static inline u32 dispc_read_reg(const struct dispc_reg idx) 132static inline u32 dispc_read_reg(const u16 idx)
185{ 133{
186 return __raw_readl(dispc.base + idx.idx); 134 return __raw_readl(dispc.base + idx);
187} 135}
188 136
189#define SR(reg) \ 137#define SR(reg) \
190 dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 138 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
191#define RR(reg) \ 139#define RR(reg) \
192 dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)]) 140 dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)])
193 141
194void dispc_save_context(void) 142void dispc_save_context(void)
195{ 143{
144 int i;
196 if (cpu_is_omap24xx()) 145 if (cpu_is_omap24xx())
197 return; 146 return;
198 147
@@ -200,280 +149,320 @@ void dispc_save_context(void)
200 SR(IRQENABLE); 149 SR(IRQENABLE);
201 SR(CONTROL); 150 SR(CONTROL);
202 SR(CONFIG); 151 SR(CONFIG);
203 SR(DEFAULT_COLOR0); 152 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
204 SR(DEFAULT_COLOR1); 153 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
205 SR(TRANS_COLOR0); 154 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
206 SR(TRANS_COLOR1); 155 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
207 SR(LINE_NUMBER); 156 SR(LINE_NUMBER);
208 SR(TIMING_H); 157 SR(TIMING_H(OMAP_DSS_CHANNEL_LCD));
209 SR(TIMING_V); 158 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
210 SR(POL_FREQ); 159 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
211 SR(DIVISOR); 160 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
212 SR(GLOBAL_ALPHA); 161 SR(GLOBAL_ALPHA);
213 SR(SIZE_DIG); 162 SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
214 SR(SIZE_LCD); 163 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
215 164 if (dss_has_feature(FEAT_MGR_LCD2)) {
216 SR(GFX_BA0); 165 SR(CONTROL2);
217 SR(GFX_BA1); 166 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
218 SR(GFX_POSITION); 167 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
219 SR(GFX_SIZE); 168 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
220 SR(GFX_ATTRIBUTES); 169 SR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
221 SR(GFX_FIFO_THRESHOLD); 170 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
222 SR(GFX_ROW_INC); 171 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
223 SR(GFX_PIXEL_INC); 172 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
224 SR(GFX_WINDOW_SKIP); 173 SR(CONFIG2);
225 SR(GFX_TABLE_BA); 174 }
226 175
227 SR(DATA_CYCLE1); 176 SR(OVL_BA0(OMAP_DSS_GFX));
228 SR(DATA_CYCLE2); 177 SR(OVL_BA1(OMAP_DSS_GFX));
229 SR(DATA_CYCLE3); 178 SR(OVL_POSITION(OMAP_DSS_GFX));
230 179 SR(OVL_SIZE(OMAP_DSS_GFX));
231 SR(CPR_COEF_R); 180 SR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
232 SR(CPR_COEF_G); 181 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
233 SR(CPR_COEF_B); 182 SR(OVL_ROW_INC(OMAP_DSS_GFX));
234 183 SR(OVL_PIXEL_INC(OMAP_DSS_GFX));
235 SR(GFX_PRELOAD); 184 SR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
185 SR(OVL_TABLE_BA(OMAP_DSS_GFX));
186
187 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
188 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
189 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
190
191 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
192 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
193 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
194 if (dss_has_feature(FEAT_MGR_LCD2)) {
195 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
196 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
197 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
198
199 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
200 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
201 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
202 }
203
204 SR(OVL_PRELOAD(OMAP_DSS_GFX));
236 205
237 /* VID1 */ 206 /* VID1 */
238 SR(VID_BA0(0)); 207 SR(OVL_BA0(OMAP_DSS_VIDEO1));
239 SR(VID_BA1(0)); 208 SR(OVL_BA1(OMAP_DSS_VIDEO1));
240 SR(VID_POSITION(0)); 209 SR(OVL_POSITION(OMAP_DSS_VIDEO1));
241 SR(VID_SIZE(0)); 210 SR(OVL_SIZE(OMAP_DSS_VIDEO1));
242 SR(VID_ATTRIBUTES(0)); 211 SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
243 SR(VID_FIFO_THRESHOLD(0)); 212 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
244 SR(VID_ROW_INC(0)); 213 SR(OVL_ROW_INC(OMAP_DSS_VIDEO1));
245 SR(VID_PIXEL_INC(0)); 214 SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
246 SR(VID_FIR(0)); 215 SR(OVL_FIR(OMAP_DSS_VIDEO1));
247 SR(VID_PICTURE_SIZE(0)); 216 SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
248 SR(VID_ACCU0(0)); 217 SR(OVL_ACCU0(OMAP_DSS_VIDEO1));
249 SR(VID_ACCU1(0)); 218 SR(OVL_ACCU1(OMAP_DSS_VIDEO1));
250 219
251 SR(VID_FIR_COEF_H(0, 0)); 220 for (i = 0; i < 8; i++)
252 SR(VID_FIR_COEF_H(0, 1)); 221 SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i));
253 SR(VID_FIR_COEF_H(0, 2)); 222
254 SR(VID_FIR_COEF_H(0, 3)); 223 for (i = 0; i < 8; i++)
255 SR(VID_FIR_COEF_H(0, 4)); 224 SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
256 SR(VID_FIR_COEF_H(0, 5)); 225
257 SR(VID_FIR_COEF_H(0, 6)); 226 for (i = 0; i < 5; i++)
258 SR(VID_FIR_COEF_H(0, 7)); 227 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
259 228
260 SR(VID_FIR_COEF_HV(0, 0)); 229 for (i = 0; i < 8; i++)
261 SR(VID_FIR_COEF_HV(0, 1)); 230 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
262 SR(VID_FIR_COEF_HV(0, 2)); 231
263 SR(VID_FIR_COEF_HV(0, 3)); 232 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
264 SR(VID_FIR_COEF_HV(0, 4)); 233 SR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
265 SR(VID_FIR_COEF_HV(0, 5)); 234 SR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
266 SR(VID_FIR_COEF_HV(0, 6)); 235 SR(OVL_FIR2(OMAP_DSS_VIDEO1));
267 SR(VID_FIR_COEF_HV(0, 7)); 236 SR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
268 237 SR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
269 SR(VID_CONV_COEF(0, 0)); 238
270 SR(VID_CONV_COEF(0, 1)); 239 for (i = 0; i < 8; i++)
271 SR(VID_CONV_COEF(0, 2)); 240 SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
272 SR(VID_CONV_COEF(0, 3)); 241
273 SR(VID_CONV_COEF(0, 4)); 242 for (i = 0; i < 8; i++)
274 243 SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
275 SR(VID_FIR_COEF_V(0, 0)); 244
276 SR(VID_FIR_COEF_V(0, 1)); 245 for (i = 0; i < 8; i++)
277 SR(VID_FIR_COEF_V(0, 2)); 246 SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
278 SR(VID_FIR_COEF_V(0, 3)); 247 }
279 SR(VID_FIR_COEF_V(0, 4)); 248 if (dss_has_feature(FEAT_ATTR2))
280 SR(VID_FIR_COEF_V(0, 5)); 249 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
281 SR(VID_FIR_COEF_V(0, 6)); 250
282 SR(VID_FIR_COEF_V(0, 7)); 251 SR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
283
284 SR(VID_PRELOAD(0));
285 252
286 /* VID2 */ 253 /* VID2 */
287 SR(VID_BA0(1)); 254 SR(OVL_BA0(OMAP_DSS_VIDEO2));
288 SR(VID_BA1(1)); 255 SR(OVL_BA1(OMAP_DSS_VIDEO2));
289 SR(VID_POSITION(1)); 256 SR(OVL_POSITION(OMAP_DSS_VIDEO2));
290 SR(VID_SIZE(1)); 257 SR(OVL_SIZE(OMAP_DSS_VIDEO2));
291 SR(VID_ATTRIBUTES(1)); 258 SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
292 SR(VID_FIFO_THRESHOLD(1)); 259 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
293 SR(VID_ROW_INC(1)); 260 SR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
294 SR(VID_PIXEL_INC(1)); 261 SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
295 SR(VID_FIR(1)); 262 SR(OVL_FIR(OMAP_DSS_VIDEO2));
296 SR(VID_PICTURE_SIZE(1)); 263 SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
297 SR(VID_ACCU0(1)); 264 SR(OVL_ACCU0(OMAP_DSS_VIDEO2));
298 SR(VID_ACCU1(1)); 265 SR(OVL_ACCU1(OMAP_DSS_VIDEO2));
299 266
300 SR(VID_FIR_COEF_H(1, 0)); 267 for (i = 0; i < 8; i++)
301 SR(VID_FIR_COEF_H(1, 1)); 268 SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i));
302 SR(VID_FIR_COEF_H(1, 2)); 269
303 SR(VID_FIR_COEF_H(1, 3)); 270 for (i = 0; i < 8; i++)
304 SR(VID_FIR_COEF_H(1, 4)); 271 SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i));
305 SR(VID_FIR_COEF_H(1, 5)); 272
306 SR(VID_FIR_COEF_H(1, 6)); 273 for (i = 0; i < 5; i++)
307 SR(VID_FIR_COEF_H(1, 7)); 274 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
308 275
309 SR(VID_FIR_COEF_HV(1, 0)); 276 for (i = 0; i < 8; i++)
310 SR(VID_FIR_COEF_HV(1, 1)); 277 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
311 SR(VID_FIR_COEF_HV(1, 2)); 278
312 SR(VID_FIR_COEF_HV(1, 3)); 279 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
313 SR(VID_FIR_COEF_HV(1, 4)); 280 SR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
314 SR(VID_FIR_COEF_HV(1, 5)); 281 SR(OVL_BA1_UV(OMAP_DSS_VIDEO2));
315 SR(VID_FIR_COEF_HV(1, 6)); 282 SR(OVL_FIR2(OMAP_DSS_VIDEO2));
316 SR(VID_FIR_COEF_HV(1, 7)); 283 SR(OVL_ACCU2_0(OMAP_DSS_VIDEO2));
317 284 SR(OVL_ACCU2_1(OMAP_DSS_VIDEO2));
318 SR(VID_CONV_COEF(1, 0)); 285
319 SR(VID_CONV_COEF(1, 1)); 286 for (i = 0; i < 8; i++)
320 SR(VID_CONV_COEF(1, 2)); 287 SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i));
321 SR(VID_CONV_COEF(1, 3)); 288
322 SR(VID_CONV_COEF(1, 4)); 289 for (i = 0; i < 8; i++)
323 290 SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i));
324 SR(VID_FIR_COEF_V(1, 0)); 291
325 SR(VID_FIR_COEF_V(1, 1)); 292 for (i = 0; i < 8; i++)
326 SR(VID_FIR_COEF_V(1, 2)); 293 SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i));
327 SR(VID_FIR_COEF_V(1, 3)); 294 }
328 SR(VID_FIR_COEF_V(1, 4)); 295 if (dss_has_feature(FEAT_ATTR2))
329 SR(VID_FIR_COEF_V(1, 5)); 296 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
330 SR(VID_FIR_COEF_V(1, 6)); 297
331 SR(VID_FIR_COEF_V(1, 7)); 298 SR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
332 299
333 SR(VID_PRELOAD(1)); 300 if (dss_has_feature(FEAT_CORE_CLK_DIV))
301 SR(DIVISOR);
334} 302}
335 303
336void dispc_restore_context(void) 304void dispc_restore_context(void)
337{ 305{
306 int i;
338 RR(SYSCONFIG); 307 RR(SYSCONFIG);
339 /*RR(IRQENABLE);*/ 308 /*RR(IRQENABLE);*/
340 /*RR(CONTROL);*/ 309 /*RR(CONTROL);*/
341 RR(CONFIG); 310 RR(CONFIG);
342 RR(DEFAULT_COLOR0); 311 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
343 RR(DEFAULT_COLOR1); 312 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
344 RR(TRANS_COLOR0); 313 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
345 RR(TRANS_COLOR1); 314 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
346 RR(LINE_NUMBER); 315 RR(LINE_NUMBER);
347 RR(TIMING_H); 316 RR(TIMING_H(OMAP_DSS_CHANNEL_LCD));
348 RR(TIMING_V); 317 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
349 RR(POL_FREQ); 318 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
350 RR(DIVISOR); 319 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
351 RR(GLOBAL_ALPHA); 320 RR(GLOBAL_ALPHA);
352 RR(SIZE_DIG); 321 RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
353 RR(SIZE_LCD); 322 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
354 323 if (dss_has_feature(FEAT_MGR_LCD2)) {
355 RR(GFX_BA0); 324 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
356 RR(GFX_BA1); 325 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
357 RR(GFX_POSITION); 326 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
358 RR(GFX_SIZE); 327 RR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
359 RR(GFX_ATTRIBUTES); 328 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
360 RR(GFX_FIFO_THRESHOLD); 329 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
361 RR(GFX_ROW_INC); 330 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
362 RR(GFX_PIXEL_INC); 331 RR(CONFIG2);
363 RR(GFX_WINDOW_SKIP); 332 }
364 RR(GFX_TABLE_BA); 333
365 334 RR(OVL_BA0(OMAP_DSS_GFX));
366 RR(DATA_CYCLE1); 335 RR(OVL_BA1(OMAP_DSS_GFX));
367 RR(DATA_CYCLE2); 336 RR(OVL_POSITION(OMAP_DSS_GFX));
368 RR(DATA_CYCLE3); 337 RR(OVL_SIZE(OMAP_DSS_GFX));
369 338 RR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
370 RR(CPR_COEF_R); 339 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
371 RR(CPR_COEF_G); 340 RR(OVL_ROW_INC(OMAP_DSS_GFX));
372 RR(CPR_COEF_B); 341 RR(OVL_PIXEL_INC(OMAP_DSS_GFX));
373 342 RR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
374 RR(GFX_PRELOAD); 343 RR(OVL_TABLE_BA(OMAP_DSS_GFX));
344
345
346 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
347 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
348 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
349
350 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
351 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
352 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
353 if (dss_has_feature(FEAT_MGR_LCD2)) {
354 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
355 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
356 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
357
358 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
359 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
360 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
361 }
362
363 RR(OVL_PRELOAD(OMAP_DSS_GFX));
375 364
376 /* VID1 */ 365 /* VID1 */
377 RR(VID_BA0(0)); 366 RR(OVL_BA0(OMAP_DSS_VIDEO1));
378 RR(VID_BA1(0)); 367 RR(OVL_BA1(OMAP_DSS_VIDEO1));
379 RR(VID_POSITION(0)); 368 RR(OVL_POSITION(OMAP_DSS_VIDEO1));
380 RR(VID_SIZE(0)); 369 RR(OVL_SIZE(OMAP_DSS_VIDEO1));
381 RR(VID_ATTRIBUTES(0)); 370 RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
382 RR(VID_FIFO_THRESHOLD(0)); 371 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
383 RR(VID_ROW_INC(0)); 372 RR(OVL_ROW_INC(OMAP_DSS_VIDEO1));
384 RR(VID_PIXEL_INC(0)); 373 RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
385 RR(VID_FIR(0)); 374 RR(OVL_FIR(OMAP_DSS_VIDEO1));
386 RR(VID_PICTURE_SIZE(0)); 375 RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
387 RR(VID_ACCU0(0)); 376 RR(OVL_ACCU0(OMAP_DSS_VIDEO1));
388 RR(VID_ACCU1(0)); 377 RR(OVL_ACCU1(OMAP_DSS_VIDEO1));
389 378
390 RR(VID_FIR_COEF_H(0, 0)); 379 for (i = 0; i < 8; i++)
391 RR(VID_FIR_COEF_H(0, 1)); 380 RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i));
392 RR(VID_FIR_COEF_H(0, 2)); 381
393 RR(VID_FIR_COEF_H(0, 3)); 382 for (i = 0; i < 8; i++)
394 RR(VID_FIR_COEF_H(0, 4)); 383 RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
395 RR(VID_FIR_COEF_H(0, 5)); 384
396 RR(VID_FIR_COEF_H(0, 6)); 385 for (i = 0; i < 5; i++)
397 RR(VID_FIR_COEF_H(0, 7)); 386 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
398 387
399 RR(VID_FIR_COEF_HV(0, 0)); 388 for (i = 0; i < 8; i++)
400 RR(VID_FIR_COEF_HV(0, 1)); 389 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
401 RR(VID_FIR_COEF_HV(0, 2)); 390
402 RR(VID_FIR_COEF_HV(0, 3)); 391 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
403 RR(VID_FIR_COEF_HV(0, 4)); 392 RR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
404 RR(VID_FIR_COEF_HV(0, 5)); 393 RR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
405 RR(VID_FIR_COEF_HV(0, 6)); 394 RR(OVL_FIR2(OMAP_DSS_VIDEO1));
406 RR(VID_FIR_COEF_HV(0, 7)); 395 RR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
407 396 RR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
408 RR(VID_CONV_COEF(0, 0)); 397
409 RR(VID_CONV_COEF(0, 1)); 398 for (i = 0; i < 8; i++)
410 RR(VID_CONV_COEF(0, 2)); 399 RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
411 RR(VID_CONV_COEF(0, 3)); 400
412 RR(VID_CONV_COEF(0, 4)); 401 for (i = 0; i < 8; i++)
413 402 RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
414 RR(VID_FIR_COEF_V(0, 0)); 403
415 RR(VID_FIR_COEF_V(0, 1)); 404 for (i = 0; i < 8; i++)
416 RR(VID_FIR_COEF_V(0, 2)); 405 RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
417 RR(VID_FIR_COEF_V(0, 3)); 406 }
418 RR(VID_FIR_COEF_V(0, 4)); 407 if (dss_has_feature(FEAT_ATTR2))
419 RR(VID_FIR_COEF_V(0, 5)); 408 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
420 RR(VID_FIR_COEF_V(0, 6)); 409
421 RR(VID_FIR_COEF_V(0, 7)); 410 RR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
422
423 RR(VID_PRELOAD(0));
424 411
425 /* VID2 */ 412 /* VID2 */
426 RR(VID_BA0(1)); 413 RR(OVL_BA0(OMAP_DSS_VIDEO2));
427 RR(VID_BA1(1)); 414 RR(OVL_BA1(OMAP_DSS_VIDEO2));
428 RR(VID_POSITION(1)); 415 RR(OVL_POSITION(OMAP_DSS_VIDEO2));
429 RR(VID_SIZE(1)); 416 RR(OVL_SIZE(OMAP_DSS_VIDEO2));
430 RR(VID_ATTRIBUTES(1)); 417 RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
431 RR(VID_FIFO_THRESHOLD(1)); 418 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
432 RR(VID_ROW_INC(1)); 419 RR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
433 RR(VID_PIXEL_INC(1)); 420 RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
434 RR(VID_FIR(1)); 421 RR(OVL_FIR(OMAP_DSS_VIDEO2));
435 RR(VID_PICTURE_SIZE(1)); 422 RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
436 RR(VID_ACCU0(1)); 423 RR(OVL_ACCU0(OMAP_DSS_VIDEO2));
437 RR(VID_ACCU1(1)); 424 RR(OVL_ACCU1(OMAP_DSS_VIDEO2));
438 425
439 RR(VID_FIR_COEF_H(1, 0)); 426 for (i = 0; i < 8; i++)
440 RR(VID_FIR_COEF_H(1, 1)); 427 RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i));
441 RR(VID_FIR_COEF_H(1, 2)); 428
442 RR(VID_FIR_COEF_H(1, 3)); 429 for (i = 0; i < 8; i++)
443 RR(VID_FIR_COEF_H(1, 4)); 430 RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i));
444 RR(VID_FIR_COEF_H(1, 5)); 431
445 RR(VID_FIR_COEF_H(1, 6)); 432 for (i = 0; i < 5; i++)
446 RR(VID_FIR_COEF_H(1, 7)); 433 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
447 434
448 RR(VID_FIR_COEF_HV(1, 0)); 435 for (i = 0; i < 8; i++)
449 RR(VID_FIR_COEF_HV(1, 1)); 436 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
450 RR(VID_FIR_COEF_HV(1, 2)); 437
451 RR(VID_FIR_COEF_HV(1, 3)); 438 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
452 RR(VID_FIR_COEF_HV(1, 4)); 439 RR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
453 RR(VID_FIR_COEF_HV(1, 5)); 440 RR(OVL_BA1_UV(OMAP_DSS_VIDEO2));
454 RR(VID_FIR_COEF_HV(1, 6)); 441 RR(OVL_FIR2(OMAP_DSS_VIDEO2));
455 RR(VID_FIR_COEF_HV(1, 7)); 442 RR(OVL_ACCU2_0(OMAP_DSS_VIDEO2));
456 443 RR(OVL_ACCU2_1(OMAP_DSS_VIDEO2));
457 RR(VID_CONV_COEF(1, 0)); 444
458 RR(VID_CONV_COEF(1, 1)); 445 for (i = 0; i < 8; i++)
459 RR(VID_CONV_COEF(1, 2)); 446 RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i));
460 RR(VID_CONV_COEF(1, 3)); 447
461 RR(VID_CONV_COEF(1, 4)); 448 for (i = 0; i < 8; i++)
462 449 RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i));
463 RR(VID_FIR_COEF_V(1, 0)); 450
464 RR(VID_FIR_COEF_V(1, 1)); 451 for (i = 0; i < 8; i++)
465 RR(VID_FIR_COEF_V(1, 2)); 452 RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i));
466 RR(VID_FIR_COEF_V(1, 3)); 453 }
467 RR(VID_FIR_COEF_V(1, 4)); 454 if (dss_has_feature(FEAT_ATTR2))
468 RR(VID_FIR_COEF_V(1, 5)); 455 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
469 RR(VID_FIR_COEF_V(1, 6)); 456
470 RR(VID_FIR_COEF_V(1, 7)); 457 RR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
471 458
472 RR(VID_PRELOAD(1)); 459 if (dss_has_feature(FEAT_CORE_CLK_DIV))
460 RR(DIVISOR);
473 461
474 /* enable last, because LCD & DIGIT enable are here */ 462 /* enable last, because LCD & DIGIT enable are here */
475 RR(CONTROL); 463 RR(CONTROL);
476 464 if (dss_has_feature(FEAT_MGR_LCD2))
465 RR(CONTROL2);
477 /* clear spurious SYNC_LOST_DIGIT interrupts */ 466 /* clear spurious SYNC_LOST_DIGIT interrupts */
478 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 467 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
479 468
@@ -490,180 +479,188 @@ void dispc_restore_context(void)
490static inline void enable_clocks(bool enable) 479static inline void enable_clocks(bool enable)
491{ 480{
492 if (enable) 481 if (enable)
493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 482 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
494 else 483 else
495 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 484 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
496} 485}
497 486
498bool dispc_go_busy(enum omap_channel channel) 487bool dispc_go_busy(enum omap_channel channel)
499{ 488{
500 int bit; 489 int bit;
501 490
502 if (channel == OMAP_DSS_CHANNEL_LCD) 491 if (channel == OMAP_DSS_CHANNEL_LCD ||
492 channel == OMAP_DSS_CHANNEL_LCD2)
503 bit = 5; /* GOLCD */ 493 bit = 5; /* GOLCD */
504 else 494 else
505 bit = 6; /* GODIGIT */ 495 bit = 6; /* GODIGIT */
506 496
507 return REG_GET(DISPC_CONTROL, bit, bit) == 1; 497 if (channel == OMAP_DSS_CHANNEL_LCD2)
498 return REG_GET(DISPC_CONTROL2, bit, bit) == 1;
499 else
500 return REG_GET(DISPC_CONTROL, bit, bit) == 1;
508} 501}
509 502
510void dispc_go(enum omap_channel channel) 503void dispc_go(enum omap_channel channel)
511{ 504{
512 int bit; 505 int bit;
506 bool enable_bit, go_bit;
513 507
514 enable_clocks(1); 508 enable_clocks(1);
515 509
516 if (channel == OMAP_DSS_CHANNEL_LCD) 510 if (channel == OMAP_DSS_CHANNEL_LCD ||
511 channel == OMAP_DSS_CHANNEL_LCD2)
517 bit = 0; /* LCDENABLE */ 512 bit = 0; /* LCDENABLE */
518 else 513 else
519 bit = 1; /* DIGITALENABLE */ 514 bit = 1; /* DIGITALENABLE */
520 515
521 /* if the channel is not enabled, we don't need GO */ 516 /* if the channel is not enabled, we don't need GO */
522 if (REG_GET(DISPC_CONTROL, bit, bit) == 0) 517 if (channel == OMAP_DSS_CHANNEL_LCD2)
518 enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
519 else
520 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
521
522 if (!enable_bit)
523 goto end; 523 goto end;
524 524
525 if (channel == OMAP_DSS_CHANNEL_LCD) 525 if (channel == OMAP_DSS_CHANNEL_LCD ||
526 channel == OMAP_DSS_CHANNEL_LCD2)
526 bit = 5; /* GOLCD */ 527 bit = 5; /* GOLCD */
527 else 528 else
528 bit = 6; /* GODIGIT */ 529 bit = 6; /* GODIGIT */
529 530
530 if (REG_GET(DISPC_CONTROL, bit, bit) == 1) { 531 if (channel == OMAP_DSS_CHANNEL_LCD2)
532 go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
533 else
534 go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
535
536 if (go_bit) {
531 DSSERR("GO bit not down for channel %d\n", channel); 537 DSSERR("GO bit not down for channel %d\n", channel);
532 goto end; 538 goto end;
533 } 539 }
534 540
535 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : "DIGIT"); 541 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" :
542 (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT"));
536 543
537 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); 544 if (channel == OMAP_DSS_CHANNEL_LCD2)
545 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
546 else
547 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
538end: 548end:
539 enable_clocks(0); 549 enable_clocks(0);
540} 550}
541 551
542static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) 552static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
543{ 553{
554 dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
555}
556
557static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
558{
559 dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value);
560}
561
562static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value)
563{
564 dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value);
565}
566
567static void _dispc_write_firh2_reg(enum omap_plane plane, int reg, u32 value)
568{
544 BUG_ON(plane == OMAP_DSS_GFX); 569 BUG_ON(plane == OMAP_DSS_GFX);
545 570
546 dispc_write_reg(DISPC_VID_FIR_COEF_H(plane-1, reg), value); 571 dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value);
547} 572}
548 573
549static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value) 574static void _dispc_write_firhv2_reg(enum omap_plane plane, int reg, u32 value)
550{ 575{
551 BUG_ON(plane == OMAP_DSS_GFX); 576 BUG_ON(plane == OMAP_DSS_GFX);
552 577
553 dispc_write_reg(DISPC_VID_FIR_COEF_HV(plane-1, reg), value); 578 dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value);
554} 579}
555 580
556static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value) 581static void _dispc_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
557{ 582{
558 BUG_ON(plane == OMAP_DSS_GFX); 583 BUG_ON(plane == OMAP_DSS_GFX);
559 584
560 dispc_write_reg(DISPC_VID_FIR_COEF_V(plane-1, reg), value); 585 dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
561} 586}
562 587
563static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup, 588static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
564 int vscaleup, int five_taps) 589 int vscaleup, int five_taps,
590 enum omap_color_component color_comp)
565{ 591{
566 /* Coefficients for horizontal up-sampling */ 592 /* Coefficients for horizontal up-sampling */
567 static const u32 coef_hup[8] = { 593 static const struct dispc_h_coef coef_hup[8] = {
568 0x00800000, 594 { 0, 0, 128, 0, 0 },
569 0x0D7CF800, 595 { -1, 13, 124, -8, 0 },
570 0x1E70F5FF, 596 { -2, 30, 112, -11, -1 },
571 0x335FF5FE, 597 { -5, 51, 95, -11, -2 },
572 0xF74949F7, 598 { 0, -9, 73, 73, -9 },
573 0xF55F33FB, 599 { -2, -11, 95, 51, -5 },
574 0xF5701EFE, 600 { -1, -11, 112, 30, -2 },
575 0xF87C0DFF, 601 { 0, -8, 124, 13, -1 },
576 }; 602 };
577 603
578 /* Coefficients for horizontal down-sampling */ 604 /* Coefficients for vertical up-sampling */
579 static const u32 coef_hdown[8] = { 605 static const struct dispc_v_coef coef_vup_3tap[8] = {
580 0x24382400, 606 { 0, 0, 128, 0, 0 },
581 0x28371FFE, 607 { 0, 3, 123, 2, 0 },
582 0x2C361BFB, 608 { 0, 12, 111, 5, 0 },
583 0x303516F9, 609 { 0, 32, 89, 7, 0 },
584 0x11343311, 610 { 0, 0, 64, 64, 0 },
585 0x1635300C, 611 { 0, 7, 89, 32, 0 },
586 0x1B362C08, 612 { 0, 5, 111, 12, 0 },
587 0x1F372804, 613 { 0, 2, 123, 3, 0 },
588 }; 614 };
589 615
590 /* Coefficients for horizontal and vertical up-sampling */ 616 static const struct dispc_v_coef coef_vup_5tap[8] = {
591 static const u32 coef_hvup[2][8] = { 617 { 0, 0, 128, 0, 0 },
592 { 618 { -1, 13, 124, -8, 0 },
593 0x00800000, 619 { -2, 30, 112, -11, -1 },
594 0x037B02FF, 620 { -5, 51, 95, -11, -2 },
595 0x0C6F05FE, 621 { 0, -9, 73, 73, -9 },
596 0x205907FB, 622 { -2, -11, 95, 51, -5 },
597 0x00404000, 623 { -1, -11, 112, 30, -2 },
598 0x075920FE, 624 { 0, -8, 124, 13, -1 },
599 0x056F0CFF,
600 0x027B0300,
601 },
602 {
603 0x00800000,
604 0x0D7CF8FF,
605 0x1E70F5FE,
606 0x335FF5FB,
607 0xF7404000,
608 0xF55F33FE,
609 0xF5701EFF,
610 0xF87C0D00,
611 },
612 }; 625 };
613 626
614 /* Coefficients for horizontal and vertical down-sampling */ 627 /* Coefficients for horizontal down-sampling */
615 static const u32 coef_hvdown[2][8] = { 628 static const struct dispc_h_coef coef_hdown[8] = {
616 { 629 { 0, 36, 56, 36, 0 },
617 0x24382400, 630 { 4, 40, 55, 31, -2 },
618 0x28391F04, 631 { 8, 44, 54, 27, -5 },
619 0x2D381B08, 632 { 12, 48, 53, 22, -7 },
620 0x3237170C, 633 { -9, 17, 52, 51, 17 },
621 0x123737F7, 634 { -7, 22, 53, 48, 12 },
622 0x173732F9, 635 { -5, 27, 54, 44, 8 },
623 0x1B382DFB, 636 { -2, 31, 55, 40, 4 },
624 0x1F3928FE,
625 },
626 {
627 0x24382400,
628 0x28371F04,
629 0x2C361B08,
630 0x3035160C,
631 0x113433F7,
632 0x163530F9,
633 0x1B362CFB,
634 0x1F3728FE,
635 },
636 }; 637 };
637 638
638 /* Coefficients for vertical up-sampling */ 639 /* Coefficients for vertical down-sampling */
639 static const u32 coef_vup[8] = { 640 static const struct dispc_v_coef coef_vdown_3tap[8] = {
640 0x00000000, 641 { 0, 36, 56, 36, 0 },
641 0x0000FF00, 642 { 0, 40, 57, 31, 0 },
642 0x0000FEFF, 643 { 0, 45, 56, 27, 0 },
643 0x0000FBFE, 644 { 0, 50, 55, 23, 0 },
644 0x000000F7, 645 { 0, 18, 55, 55, 0 },
645 0x0000FEFB, 646 { 0, 23, 55, 50, 0 },
646 0x0000FFFE, 647 { 0, 27, 56, 45, 0 },
647 0x000000FF, 648 { 0, 31, 57, 40, 0 },
648 }; 649 };
649 650
650 651 static const struct dispc_v_coef coef_vdown_5tap[8] = {
651 /* Coefficients for vertical down-sampling */ 652 { 0, 36, 56, 36, 0 },
652 static const u32 coef_vdown[8] = { 653 { 4, 40, 55, 31, -2 },
653 0x00000000, 654 { 8, 44, 54, 27, -5 },
654 0x000004FE, 655 { 12, 48, 53, 22, -7 },
655 0x000008FB, 656 { -9, 17, 52, 51, 17 },
656 0x00000CF9, 657 { -7, 22, 53, 48, 12 },
657 0x0000F711, 658 { -5, 27, 54, 44, 8 },
658 0x0000F90C, 659 { -2, 31, 55, 40, 4 },
659 0x0000FB08,
660 0x0000FE04,
661 }; 660 };
662 661
663 const u32 *h_coef; 662 const struct dispc_h_coef *h_coef;
664 const u32 *hv_coef; 663 const struct dispc_v_coef *v_coef;
665 const u32 *hv_coef_mod;
666 const u32 *v_coef;
667 int i; 664 int i;
668 665
669 if (hscaleup) 666 if (hscaleup)
@@ -671,47 +668,43 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
671 else 668 else
672 h_coef = coef_hdown; 669 h_coef = coef_hdown;
673 670
674 if (vscaleup) { 671 if (vscaleup)
675 hv_coef = coef_hvup[five_taps]; 672 v_coef = five_taps ? coef_vup_5tap : coef_vup_3tap;
676 v_coef = coef_vup; 673 else
677 674 v_coef = five_taps ? coef_vdown_5tap : coef_vdown_3tap;
678 if (hscaleup)
679 hv_coef_mod = NULL;
680 else
681 hv_coef_mod = coef_hvdown[five_taps];
682 } else {
683 hv_coef = coef_hvdown[five_taps];
684 v_coef = coef_vdown;
685
686 if (hscaleup)
687 hv_coef_mod = coef_hvup[five_taps];
688 else
689 hv_coef_mod = NULL;
690 }
691 675
692 for (i = 0; i < 8; i++) { 676 for (i = 0; i < 8; i++) {
693 u32 h, hv; 677 u32 h, hv;
694 678
695 h = h_coef[i]; 679 h = FLD_VAL(h_coef[i].hc0, 7, 0)
696 680 | FLD_VAL(h_coef[i].hc1, 15, 8)
697 hv = hv_coef[i]; 681 | FLD_VAL(h_coef[i].hc2, 23, 16)
698 682 | FLD_VAL(h_coef[i].hc3, 31, 24);
699 if (hv_coef_mod) { 683 hv = FLD_VAL(h_coef[i].hc4, 7, 0)
700 hv &= 0xffffff00; 684 | FLD_VAL(v_coef[i].vc0, 15, 8)
701 hv |= (hv_coef_mod[i] & 0xff); 685 | FLD_VAL(v_coef[i].vc1, 23, 16)
686 | FLD_VAL(v_coef[i].vc2, 31, 24);
687
688 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
689 _dispc_write_firh_reg(plane, i, h);
690 _dispc_write_firhv_reg(plane, i, hv);
691 } else {
692 _dispc_write_firh2_reg(plane, i, h);
693 _dispc_write_firhv2_reg(plane, i, hv);
702 } 694 }
703 695
704 _dispc_write_firh_reg(plane, i, h);
705 _dispc_write_firhv_reg(plane, i, hv);
706 } 696 }
707 697
708 if (!five_taps) 698 if (five_taps) {
709 return; 699 for (i = 0; i < 8; i++) {
710 700 u32 v;
711 for (i = 0; i < 8; i++) { 701 v = FLD_VAL(v_coef[i].vc00, 7, 0)
712 u32 v; 702 | FLD_VAL(v_coef[i].vc22, 15, 8);
713 v = v_coef[i]; 703 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
714 _dispc_write_firv_reg(plane, i, v); 704 _dispc_write_firv_reg(plane, i, v);
705 else
706 _dispc_write_firv2_reg(plane, i, v);
707 }
715 } 708 }
716} 709}
717 710
@@ -730,80 +723,104 @@ static void _dispc_setup_color_conv_coef(void)
730 723
731 ct = &ctbl_bt601_5; 724 ct = &ctbl_bt601_5;
732 725
733 dispc_write_reg(DISPC_VID_CONV_COEF(0, 0), CVAL(ct->rcr, ct->ry)); 726 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0),
734 dispc_write_reg(DISPC_VID_CONV_COEF(0, 1), CVAL(ct->gy, ct->rcb)); 727 CVAL(ct->rcr, ct->ry));
735 dispc_write_reg(DISPC_VID_CONV_COEF(0, 2), CVAL(ct->gcb, ct->gcr)); 728 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1),
736 dispc_write_reg(DISPC_VID_CONV_COEF(0, 3), CVAL(ct->bcr, ct->by)); 729 CVAL(ct->gy, ct->rcb));
737 dispc_write_reg(DISPC_VID_CONV_COEF(0, 4), CVAL(0, ct->bcb)); 730 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2),
738 731 CVAL(ct->gcb, ct->gcr));
739 dispc_write_reg(DISPC_VID_CONV_COEF(1, 0), CVAL(ct->rcr, ct->ry)); 732 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3),
740 dispc_write_reg(DISPC_VID_CONV_COEF(1, 1), CVAL(ct->gy, ct->rcb)); 733 CVAL(ct->bcr, ct->by));
741 dispc_write_reg(DISPC_VID_CONV_COEF(1, 2), CVAL(ct->gcb, ct->gcr)); 734 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4),
742 dispc_write_reg(DISPC_VID_CONV_COEF(1, 3), CVAL(ct->bcr, ct->by)); 735 CVAL(0, ct->bcb));
743 dispc_write_reg(DISPC_VID_CONV_COEF(1, 4), CVAL(0, ct->bcb)); 736
737 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0),
738 CVAL(ct->rcr, ct->ry));
739 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1),
740 CVAL(ct->gy, ct->rcb));
741 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2),
742 CVAL(ct->gcb, ct->gcr));
743 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3),
744 CVAL(ct->bcr, ct->by));
745 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4),
746 CVAL(0, ct->bcb));
744 747
745#undef CVAL 748#undef CVAL
746 749
747 REG_FLD_MOD(DISPC_VID_ATTRIBUTES(0), ct->full_range, 11, 11); 750 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1),
748 REG_FLD_MOD(DISPC_VID_ATTRIBUTES(1), ct->full_range, 11, 11); 751 ct->full_range, 11, 11);
752 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2),
753 ct->full_range, 11, 11);
749} 754}
750 755
751 756
752static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr) 757static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr)
753{ 758{
754 const struct dispc_reg ba0_reg[] = { DISPC_GFX_BA0, 759 dispc_write_reg(DISPC_OVL_BA0(plane), paddr);
755 DISPC_VID_BA0(0),
756 DISPC_VID_BA0(1) };
757
758 dispc_write_reg(ba0_reg[plane], paddr);
759} 760}
760 761
761static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr) 762static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr)
762{ 763{
763 const struct dispc_reg ba1_reg[] = { DISPC_GFX_BA1, 764 dispc_write_reg(DISPC_OVL_BA1(plane), paddr);
764 DISPC_VID_BA1(0), 765}
765 DISPC_VID_BA1(1) };
766 766
767 dispc_write_reg(ba1_reg[plane], paddr); 767static void _dispc_set_plane_ba0_uv(enum omap_plane plane, u32 paddr)
768{
769 dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr);
768} 770}
769 771
770static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y) 772static void _dispc_set_plane_ba1_uv(enum omap_plane plane, u32 paddr)
771{ 773{
772 const struct dispc_reg pos_reg[] = { DISPC_GFX_POSITION, 774 dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
773 DISPC_VID_POSITION(0), 775}
774 DISPC_VID_POSITION(1) };
775 776
777static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y)
778{
776 u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); 779 u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
777 dispc_write_reg(pos_reg[plane], val); 780
781 dispc_write_reg(DISPC_OVL_POSITION(plane), val);
778} 782}
779 783
780static void _dispc_set_pic_size(enum omap_plane plane, int width, int height) 784static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
781{ 785{
782 const struct dispc_reg siz_reg[] = { DISPC_GFX_SIZE,
783 DISPC_VID_PICTURE_SIZE(0),
784 DISPC_VID_PICTURE_SIZE(1) };
785 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 786 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
786 dispc_write_reg(siz_reg[plane], val); 787
788 if (plane == OMAP_DSS_GFX)
789 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
790 else
791 dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
787} 792}
788 793
789static void _dispc_set_vid_size(enum omap_plane plane, int width, int height) 794static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
790{ 795{
791 u32 val; 796 u32 val;
792 const struct dispc_reg vsi_reg[] = { DISPC_VID_SIZE(0),
793 DISPC_VID_SIZE(1) };
794 797
795 BUG_ON(plane == OMAP_DSS_GFX); 798 BUG_ON(plane == OMAP_DSS_GFX);
796 799
797 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 800 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
798 dispc_write_reg(vsi_reg[plane-1], val); 801
802 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
799} 803}
800 804
801static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) 805static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable)
802{ 806{
807 if (!dss_has_feature(FEAT_PRE_MULT_ALPHA))
808 return;
803 809
804 BUG_ON(plane == OMAP_DSS_VIDEO1); 810 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
811 plane == OMAP_DSS_VIDEO1)
812 return;
805 813
806 if (cpu_is_omap24xx()) 814 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
815}
816
817static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
818{
819 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
820 return;
821
822 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
823 plane == OMAP_DSS_VIDEO1)
807 return; 824 return;
808 825
809 if (plane == OMAP_DSS_GFX) 826 if (plane == OMAP_DSS_GFX)
@@ -814,61 +831,93 @@ static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
814 831
815static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc) 832static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc)
816{ 833{
817 const struct dispc_reg ri_reg[] = { DISPC_GFX_PIXEL_INC, 834 dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc);
818 DISPC_VID_PIXEL_INC(0),
819 DISPC_VID_PIXEL_INC(1) };
820
821 dispc_write_reg(ri_reg[plane], inc);
822} 835}
823 836
824static void _dispc_set_row_inc(enum omap_plane plane, s32 inc) 837static void _dispc_set_row_inc(enum omap_plane plane, s32 inc)
825{ 838{
826 const struct dispc_reg ri_reg[] = { DISPC_GFX_ROW_INC, 839 dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc);
827 DISPC_VID_ROW_INC(0),
828 DISPC_VID_ROW_INC(1) };
829
830 dispc_write_reg(ri_reg[plane], inc);
831} 840}
832 841
833static void _dispc_set_color_mode(enum omap_plane plane, 842static void _dispc_set_color_mode(enum omap_plane plane,
834 enum omap_color_mode color_mode) 843 enum omap_color_mode color_mode)
835{ 844{
836 u32 m = 0; 845 u32 m = 0;
837 846 if (plane != OMAP_DSS_GFX) {
838 switch (color_mode) { 847 switch (color_mode) {
839 case OMAP_DSS_COLOR_CLUT1: 848 case OMAP_DSS_COLOR_NV12:
840 m = 0x0; break; 849 m = 0x0; break;
841 case OMAP_DSS_COLOR_CLUT2: 850 case OMAP_DSS_COLOR_RGB12U:
842 m = 0x1; break; 851 m = 0x1; break;
843 case OMAP_DSS_COLOR_CLUT4: 852 case OMAP_DSS_COLOR_RGBA16:
844 m = 0x2; break; 853 m = 0x2; break;
845 case OMAP_DSS_COLOR_CLUT8: 854 case OMAP_DSS_COLOR_RGBX16:
846 m = 0x3; break; 855 m = 0x4; break;
847 case OMAP_DSS_COLOR_RGB12U: 856 case OMAP_DSS_COLOR_ARGB16:
848 m = 0x4; break; 857 m = 0x5; break;
849 case OMAP_DSS_COLOR_ARGB16: 858 case OMAP_DSS_COLOR_RGB16:
850 m = 0x5; break; 859 m = 0x6; break;
851 case OMAP_DSS_COLOR_RGB16: 860 case OMAP_DSS_COLOR_ARGB16_1555:
852 m = 0x6; break; 861 m = 0x7; break;
853 case OMAP_DSS_COLOR_RGB24U: 862 case OMAP_DSS_COLOR_RGB24U:
854 m = 0x8; break; 863 m = 0x8; break;
855 case OMAP_DSS_COLOR_RGB24P: 864 case OMAP_DSS_COLOR_RGB24P:
856 m = 0x9; break; 865 m = 0x9; break;
857 case OMAP_DSS_COLOR_YUV2: 866 case OMAP_DSS_COLOR_YUV2:
858 m = 0xa; break; 867 m = 0xa; break;
859 case OMAP_DSS_COLOR_UYVY: 868 case OMAP_DSS_COLOR_UYVY:
860 m = 0xb; break; 869 m = 0xb; break;
861 case OMAP_DSS_COLOR_ARGB32: 870 case OMAP_DSS_COLOR_ARGB32:
862 m = 0xc; break; 871 m = 0xc; break;
863 case OMAP_DSS_COLOR_RGBA32: 872 case OMAP_DSS_COLOR_RGBA32:
864 m = 0xd; break; 873 m = 0xd; break;
865 case OMAP_DSS_COLOR_RGBX32: 874 case OMAP_DSS_COLOR_RGBX32:
866 m = 0xe; break; 875 m = 0xe; break;
867 default: 876 case OMAP_DSS_COLOR_XRGB16_1555:
868 BUG(); break; 877 m = 0xf; break;
878 default:
879 BUG(); break;
880 }
881 } else {
882 switch (color_mode) {
883 case OMAP_DSS_COLOR_CLUT1:
884 m = 0x0; break;
885 case OMAP_DSS_COLOR_CLUT2:
886 m = 0x1; break;
887 case OMAP_DSS_COLOR_CLUT4:
888 m = 0x2; break;
889 case OMAP_DSS_COLOR_CLUT8:
890 m = 0x3; break;
891 case OMAP_DSS_COLOR_RGB12U:
892 m = 0x4; break;
893 case OMAP_DSS_COLOR_ARGB16:
894 m = 0x5; break;
895 case OMAP_DSS_COLOR_RGB16:
896 m = 0x6; break;
897 case OMAP_DSS_COLOR_ARGB16_1555:
898 m = 0x7; break;
899 case OMAP_DSS_COLOR_RGB24U:
900 m = 0x8; break;
901 case OMAP_DSS_COLOR_RGB24P:
902 m = 0x9; break;
903 case OMAP_DSS_COLOR_YUV2:
904 m = 0xa; break;
905 case OMAP_DSS_COLOR_UYVY:
906 m = 0xb; break;
907 case OMAP_DSS_COLOR_ARGB32:
908 m = 0xc; break;
909 case OMAP_DSS_COLOR_RGBA32:
910 m = 0xd; break;
911 case OMAP_DSS_COLOR_RGBX32:
912 m = 0xe; break;
913 case OMAP_DSS_COLOR_XRGB16_1555:
914 m = 0xf; break;
915 default:
916 BUG(); break;
917 }
869 } 918 }
870 919
871 REG_FLD_MOD(dispc_reg_att[plane], m, 4, 1); 920 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
872} 921}
873 922
874static void _dispc_set_channel_out(enum omap_plane plane, 923static void _dispc_set_channel_out(enum omap_plane plane,
@@ -876,6 +925,7 @@ static void _dispc_set_channel_out(enum omap_plane plane,
876{ 925{
877 int shift; 926 int shift;
878 u32 val; 927 u32 val;
928 int chan = 0, chan2 = 0;
879 929
880 switch (plane) { 930 switch (plane) {
881 case OMAP_DSS_GFX: 931 case OMAP_DSS_GFX:
@@ -890,9 +940,31 @@ static void _dispc_set_channel_out(enum omap_plane plane,
890 return; 940 return;
891 } 941 }
892 942
893 val = dispc_read_reg(dispc_reg_att[plane]); 943 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
894 val = FLD_MOD(val, channel, shift, shift); 944 if (dss_has_feature(FEAT_MGR_LCD2)) {
895 dispc_write_reg(dispc_reg_att[plane], val); 945 switch (channel) {
946 case OMAP_DSS_CHANNEL_LCD:
947 chan = 0;
948 chan2 = 0;
949 break;
950 case OMAP_DSS_CHANNEL_DIGIT:
951 chan = 1;
952 chan2 = 0;
953 break;
954 case OMAP_DSS_CHANNEL_LCD2:
955 chan = 0;
956 chan2 = 1;
957 break;
958 default:
959 BUG();
960 }
961
962 val = FLD_MOD(val, chan, shift, shift);
963 val = FLD_MOD(val, chan2, 31, 30);
964 } else {
965 val = FLD_MOD(val, channel, shift, shift);
966 }
967 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
896} 968}
897 969
898void dispc_set_burst_size(enum omap_plane plane, 970void dispc_set_burst_size(enum omap_plane plane,
@@ -916,22 +988,36 @@ void dispc_set_burst_size(enum omap_plane plane,
916 return; 988 return;
917 } 989 }
918 990
919 val = dispc_read_reg(dispc_reg_att[plane]); 991 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
920 val = FLD_MOD(val, burst_size, shift+1, shift); 992 val = FLD_MOD(val, burst_size, shift+1, shift);
921 dispc_write_reg(dispc_reg_att[plane], val); 993 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
922 994
923 enable_clocks(0); 995 enable_clocks(0);
924} 996}
925 997
998void dispc_enable_gamma_table(bool enable)
999{
1000 /*
1001 * This is partially implemented to support only disabling of
1002 * the gamma table.
1003 */
1004 if (enable) {
1005 DSSWARN("Gamma table enabling for TV not yet supported");
1006 return;
1007 }
1008
1009 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1010}
1011
926static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1012static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
927{ 1013{
928 u32 val; 1014 u32 val;
929 1015
930 BUG_ON(plane == OMAP_DSS_GFX); 1016 BUG_ON(plane == OMAP_DSS_GFX);
931 1017
932 val = dispc_read_reg(dispc_reg_att[plane]); 1018 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
933 val = FLD_MOD(val, enable, 9, 9); 1019 val = FLD_MOD(val, enable, 9, 9);
934 dispc_write_reg(dispc_reg_att[plane], val); 1020 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
935} 1021}
936 1022
937void dispc_enable_replication(enum omap_plane plane, bool enable) 1023void dispc_enable_replication(enum omap_plane plane, bool enable)
@@ -944,17 +1030,17 @@ void dispc_enable_replication(enum omap_plane plane, bool enable)
944 bit = 10; 1030 bit = 10;
945 1031
946 enable_clocks(1); 1032 enable_clocks(1);
947 REG_FLD_MOD(dispc_reg_att[plane], enable, bit, bit); 1033 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
948 enable_clocks(0); 1034 enable_clocks(0);
949} 1035}
950 1036
951void dispc_set_lcd_size(u16 width, u16 height) 1037void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
952{ 1038{
953 u32 val; 1039 u32 val;
954 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1040 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
955 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1041 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
956 enable_clocks(1); 1042 enable_clocks(1);
957 dispc_write_reg(DISPC_SIZE_LCD, val); 1043 dispc_write_reg(DISPC_SIZE_MGR(channel), val);
958 enable_clocks(0); 1044 enable_clocks(0);
959} 1045}
960 1046
@@ -964,28 +1050,23 @@ void dispc_set_digit_size(u16 width, u16 height)
964 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1050 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
965 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1051 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
966 enable_clocks(1); 1052 enable_clocks(1);
967 dispc_write_reg(DISPC_SIZE_DIG, val); 1053 dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val);
968 enable_clocks(0); 1054 enable_clocks(0);
969} 1055}
970 1056
971static void dispc_read_plane_fifo_sizes(void) 1057static void dispc_read_plane_fifo_sizes(void)
972{ 1058{
973 const struct dispc_reg fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
974 DISPC_VID_FIFO_SIZE_STATUS(0),
975 DISPC_VID_FIFO_SIZE_STATUS(1) };
976 u32 size; 1059 u32 size;
977 int plane; 1060 int plane;
1061 u8 start, end;
978 1062
979 enable_clocks(1); 1063 enable_clocks(1);
980 1064
981 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) { 1065 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
982 if (cpu_is_omap24xx())
983 size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 8, 0);
984 else if (cpu_is_omap34xx())
985 size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 10, 0);
986 else
987 BUG();
988 1066
1067 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) {
1068 size = FLD_GET(dispc_read_reg(DISPC_OVL_FIFO_SIZE_STATUS(plane)),
1069 start, end);
989 dispc.fifo_size[plane] = size; 1070 dispc.fifo_size[plane] = size;
990 } 1071 }
991 1072
@@ -999,23 +1080,24 @@ u32 dispc_get_plane_fifo_size(enum omap_plane plane)
999 1080
1000void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high) 1081void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high)
1001{ 1082{
1002 const struct dispc_reg ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD, 1083 u8 hi_start, hi_end, lo_start, lo_end;
1003 DISPC_VID_FIFO_THRESHOLD(0), 1084
1004 DISPC_VID_FIFO_THRESHOLD(1) }; 1085 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);
1087
1005 enable_clocks(1); 1088 enable_clocks(1);
1006 1089
1007 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", 1090 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
1008 plane, 1091 plane,
1009 REG_GET(ftrs_reg[plane], 11, 0), 1092 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1010 REG_GET(ftrs_reg[plane], 27, 16), 1093 lo_start, lo_end),
1094 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1095 hi_start, hi_end),
1011 low, high); 1096 low, high);
1012 1097
1013 if (cpu_is_omap24xx()) 1098 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
1014 dispc_write_reg(ftrs_reg[plane], 1099 FLD_VAL(high, hi_start, hi_end) |
1015 FLD_VAL(high, 24, 16) | FLD_VAL(low, 8, 0)); 1100 FLD_VAL(low, lo_start, lo_end));
1016 else
1017 dispc_write_reg(ftrs_reg[plane],
1018 FLD_VAL(high, 27, 16) | FLD_VAL(low, 11, 0));
1019 1101
1020 enable_clocks(0); 1102 enable_clocks(0);
1021} 1103}
@@ -1030,91 +1112,129 @@ void dispc_enable_fifomerge(bool enable)
1030 enable_clocks(0); 1112 enable_clocks(0);
1031} 1113}
1032 1114
1033static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc) 1115static void _dispc_set_fir(enum omap_plane plane,
1116 int hinc, int vinc,
1117 enum omap_color_component color_comp)
1034{ 1118{
1035 u32 val; 1119 u32 val;
1036 const struct dispc_reg fir_reg[] = { DISPC_VID_FIR(0),
1037 DISPC_VID_FIR(1) };
1038 1120
1039 BUG_ON(plane == OMAP_DSS_GFX); 1121 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
1122 u8 hinc_start, hinc_end, vinc_start, vinc_end;
1040 1123
1041 if (cpu_is_omap24xx()) 1124 dss_feat_get_reg_field(FEAT_REG_FIRHINC,
1042 val = FLD_VAL(vinc, 27, 16) | FLD_VAL(hinc, 11, 0); 1125 &hinc_start, &hinc_end);
1043 else 1126 dss_feat_get_reg_field(FEAT_REG_FIRVINC,
1127 &vinc_start, &vinc_end);
1128 val = FLD_VAL(vinc, vinc_start, vinc_end) |
1129 FLD_VAL(hinc, hinc_start, hinc_end);
1130
1131 dispc_write_reg(DISPC_OVL_FIR(plane), val);
1132 } else {
1044 val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0); 1133 val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0);
1045 dispc_write_reg(fir_reg[plane-1], val); 1134 dispc_write_reg(DISPC_OVL_FIR2(plane), val);
1135 }
1046} 1136}
1047 1137
1048static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) 1138static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1049{ 1139{
1050 u32 val; 1140 u32 val;
1051 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), 1141 u8 hor_start, hor_end, vert_start, vert_end;
1052 DISPC_VID_ACCU0(1) };
1053 1142
1054 BUG_ON(plane == OMAP_DSS_GFX); 1143 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1144 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1145
1146 val = FLD_VAL(vaccu, vert_start, vert_end) |
1147 FLD_VAL(haccu, hor_start, hor_end);
1055 1148
1056 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1149 dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
1057 dispc_write_reg(ac0_reg[plane-1], val);
1058} 1150}
1059 1151
1060static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) 1152static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1061{ 1153{
1062 u32 val; 1154 u32 val;
1063 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), 1155 u8 hor_start, hor_end, vert_start, vert_end;
1064 DISPC_VID_ACCU1(1) };
1065 1156
1066 BUG_ON(plane == OMAP_DSS_GFX); 1157 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1158 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1159
1160 val = FLD_VAL(vaccu, vert_start, vert_end) |
1161 FLD_VAL(haccu, hor_start, hor_end);
1067 1162
1068 val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); 1163 dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
1069 dispc_write_reg(ac1_reg[plane-1], val);
1070} 1164}
1071 1165
1166static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu)
1167{
1168 u32 val;
1072 1169
1073static void _dispc_set_scaling(enum omap_plane plane, 1170 val = FLD_VAL(vaccu, 26, 16) | FLD_VAL(haccu, 10, 0);
1171 dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val);
1172}
1173
1174static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu)
1175{
1176 u32 val;
1177
1178 val = FLD_VAL(vaccu, 26, 16) | FLD_VAL(haccu, 10, 0);
1179 dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val);
1180}
1181
1182static void _dispc_set_scale_param(enum omap_plane plane,
1074 u16 orig_width, u16 orig_height, 1183 u16 orig_width, u16 orig_height,
1075 u16 out_width, u16 out_height, 1184 u16 out_width, u16 out_height,
1076 bool ilace, bool five_taps, 1185 bool five_taps, u8 rotation,
1077 bool fieldmode) 1186 enum omap_color_component color_comp)
1078{ 1187{
1079 int fir_hinc; 1188 int fir_hinc, fir_vinc;
1080 int fir_vinc;
1081 int hscaleup, vscaleup; 1189 int hscaleup, vscaleup;
1082 int accu0 = 0;
1083 int accu1 = 0;
1084 u32 l;
1085
1086 BUG_ON(plane == OMAP_DSS_GFX);
1087 1190
1088 hscaleup = orig_width <= out_width; 1191 hscaleup = orig_width <= out_width;
1089 vscaleup = orig_height <= out_height; 1192 vscaleup = orig_height <= out_height;
1090 1193
1091 _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps); 1194 _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps, color_comp);
1092 1195
1093 if (!orig_width || orig_width == out_width) 1196 fir_hinc = 1024 * orig_width / out_width;
1094 fir_hinc = 0; 1197 fir_vinc = 1024 * orig_height / out_height;
1095 else
1096 fir_hinc = 1024 * orig_width / out_width;
1097 1198
1098 if (!orig_height || orig_height == out_height) 1199 _dispc_set_fir(plane, fir_hinc, fir_vinc, color_comp);
1099 fir_vinc = 0; 1200}
1100 else
1101 fir_vinc = 1024 * orig_height / out_height;
1102 1201
1103 _dispc_set_fir(plane, fir_hinc, fir_vinc); 1202static void _dispc_set_scaling_common(enum omap_plane plane,
1203 u16 orig_width, u16 orig_height,
1204 u16 out_width, u16 out_height,
1205 bool ilace, bool five_taps,
1206 bool fieldmode, enum omap_color_mode color_mode,
1207 u8 rotation)
1208{
1209 int accu0 = 0;
1210 int accu1 = 0;
1211 u32 l;
1104 1212
1105 l = dispc_read_reg(dispc_reg_att[plane]); 1213 _dispc_set_scale_param(plane, orig_width, orig_height,
1106 l &= ~((0x0f << 5) | (0x3 << 21)); 1214 out_width, out_height, five_taps,
1215 rotation, DISPC_COLOR_COMPONENT_RGB_Y);
1216 l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
1107 1217
1108 l |= fir_hinc ? (1 << 5) : 0; 1218 /* RESIZEENABLE and VERTICALTAPS */
1109 l |= fir_vinc ? (1 << 6) : 0; 1219 l &= ~((0x3 << 5) | (0x1 << 21));
1220 l |= (orig_width != out_width) ? (1 << 5) : 0;
1221 l |= (orig_height != out_height) ? (1 << 6) : 0;
1222 l |= five_taps ? (1 << 21) : 0;
1110 1223
1111 l |= hscaleup ? 0 : (1 << 7); 1224 /* VRESIZECONF and HRESIZECONF */
1112 l |= vscaleup ? 0 : (1 << 8); 1225 if (dss_has_feature(FEAT_RESIZECONF)) {
1226 l &= ~(0x3 << 7);
1227 l |= (orig_width <= out_width) ? 0 : (1 << 7);
1228 l |= (orig_height <= out_height) ? 0 : (1 << 8);
1229 }
1113 1230
1114 l |= five_taps ? (1 << 21) : 0; 1231 /* LINEBUFFERSPLIT */
1115 l |= five_taps ? (1 << 22) : 0; 1232 if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
1233 l &= ~(0x1 << 22);
1234 l |= five_taps ? (1 << 22) : 0;
1235 }
1116 1236
1117 dispc_write_reg(dispc_reg_att[plane], l); 1237 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
1118 1238
1119 /* 1239 /*
1120 * field 0 = even field = bottom field 1240 * field 0 = even field = bottom field
@@ -1122,7 +1242,7 @@ static void _dispc_set_scaling(enum omap_plane plane,
1122 */ 1242 */
1123 if (ilace && !fieldmode) { 1243 if (ilace && !fieldmode) {
1124 accu1 = 0; 1244 accu1 = 0;
1125 accu0 = (fir_vinc / 2) & 0x3ff; 1245 accu0 = ((1024 * orig_height / out_height) / 2) & 0x3ff;
1126 if (accu0 >= 1024/2) { 1246 if (accu0 >= 1024/2) {
1127 accu1 = 1024/2; 1247 accu1 = 1024/2;
1128 accu0 -= accu1; 1248 accu0 -= accu1;
@@ -1133,12 +1253,101 @@ static void _dispc_set_scaling(enum omap_plane plane,
1133 _dispc_set_vid_accu1(plane, 0, accu1); 1253 _dispc_set_vid_accu1(plane, 0, accu1);
1134} 1254}
1135 1255
1256static void _dispc_set_scaling_uv(enum omap_plane plane,
1257 u16 orig_width, u16 orig_height,
1258 u16 out_width, u16 out_height,
1259 bool ilace, bool five_taps,
1260 bool fieldmode, enum omap_color_mode color_mode,
1261 u8 rotation)
1262{
1263 int scale_x = out_width != orig_width;
1264 int scale_y = out_height != orig_height;
1265
1266 if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
1267 return;
1268 if ((color_mode != OMAP_DSS_COLOR_YUV2 &&
1269 color_mode != OMAP_DSS_COLOR_UYVY &&
1270 color_mode != OMAP_DSS_COLOR_NV12)) {
1271 /* reset chroma resampling for RGB formats */
1272 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
1273 return;
1274 }
1275 switch (color_mode) {
1276 case OMAP_DSS_COLOR_NV12:
1277 /* UV is subsampled by 2 vertically*/
1278 orig_height >>= 1;
1279 /* UV is subsampled by 2 horz.*/
1280 orig_width >>= 1;
1281 break;
1282 case OMAP_DSS_COLOR_YUV2:
1283 case OMAP_DSS_COLOR_UYVY:
1284 /*For YUV422 with 90/270 rotation,
1285 *we don't upsample chroma
1286 */
1287 if (rotation == OMAP_DSS_ROT_0 ||
1288 rotation == OMAP_DSS_ROT_180)
1289 /* UV is subsampled by 2 hrz*/
1290 orig_width >>= 1;
1291 /* must use FIR for YUV422 if rotated */
1292 if (rotation != OMAP_DSS_ROT_0)
1293 scale_x = scale_y = true;
1294 break;
1295 default:
1296 BUG();
1297 }
1298
1299 if (out_width != orig_width)
1300 scale_x = true;
1301 if (out_height != orig_height)
1302 scale_y = true;
1303
1304 _dispc_set_scale_param(plane, orig_width, orig_height,
1305 out_width, out_height, five_taps,
1306 rotation, DISPC_COLOR_COMPONENT_UV);
1307
1308 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
1309 (scale_x || scale_y) ? 1 : 0, 8, 8);
1310 /* set H scaling */
1311 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
1312 /* set V scaling */
1313 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6);
1314
1315 _dispc_set_vid_accu2_0(plane, 0x80, 0);
1316 _dispc_set_vid_accu2_1(plane, 0x80, 0);
1317}
1318
1319static void _dispc_set_scaling(enum omap_plane plane,
1320 u16 orig_width, u16 orig_height,
1321 u16 out_width, u16 out_height,
1322 bool ilace, bool five_taps,
1323 bool fieldmode, enum omap_color_mode color_mode,
1324 u8 rotation)
1325{
1326 BUG_ON(plane == OMAP_DSS_GFX);
1327
1328 _dispc_set_scaling_common(plane,
1329 orig_width, orig_height,
1330 out_width, out_height,
1331 ilace, five_taps,
1332 fieldmode, color_mode,
1333 rotation);
1334
1335 _dispc_set_scaling_uv(plane,
1336 orig_width, orig_height,
1337 out_width, out_height,
1338 ilace, five_taps,
1339 fieldmode, color_mode,
1340 rotation);
1341}
1342
1136static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1343static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1137 bool mirroring, enum omap_color_mode color_mode) 1344 bool mirroring, enum omap_color_mode color_mode)
1138{ 1345{
1346 bool row_repeat = false;
1347 int vidrot = 0;
1348
1139 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1349 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1140 color_mode == OMAP_DSS_COLOR_UYVY) { 1350 color_mode == OMAP_DSS_COLOR_UYVY) {
1141 int vidrot = 0;
1142 1351
1143 if (mirroring) { 1352 if (mirroring) {
1144 switch (rotation) { 1353 switch (rotation) {
@@ -1172,16 +1381,16 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1172 } 1381 }
1173 } 1382 }
1174 1383
1175 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
1176
1177 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) 1384 if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270)
1178 REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); 1385 row_repeat = true;
1179 else 1386 else
1180 REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); 1387 row_repeat = false;
1181 } else {
1182 REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
1183 REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
1184 } 1388 }
1389
1390 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12);
1391 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1392 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
1393 row_repeat ? 1 : 0, 18, 18);
1185} 1394}
1186 1395
1187static int color_mode_to_bpp(enum omap_color_mode color_mode) 1396static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -1194,12 +1403,17 @@ static int color_mode_to_bpp(enum omap_color_mode color_mode)
1194 case OMAP_DSS_COLOR_CLUT4: 1403 case OMAP_DSS_COLOR_CLUT4:
1195 return 4; 1404 return 4;
1196 case OMAP_DSS_COLOR_CLUT8: 1405 case OMAP_DSS_COLOR_CLUT8:
1406 case OMAP_DSS_COLOR_NV12:
1197 return 8; 1407 return 8;
1198 case OMAP_DSS_COLOR_RGB12U: 1408 case OMAP_DSS_COLOR_RGB12U:
1199 case OMAP_DSS_COLOR_RGB16: 1409 case OMAP_DSS_COLOR_RGB16:
1200 case OMAP_DSS_COLOR_ARGB16: 1410 case OMAP_DSS_COLOR_ARGB16:
1201 case OMAP_DSS_COLOR_YUV2: 1411 case OMAP_DSS_COLOR_YUV2:
1202 case OMAP_DSS_COLOR_UYVY: 1412 case OMAP_DSS_COLOR_UYVY:
1413 case OMAP_DSS_COLOR_RGBA16:
1414 case OMAP_DSS_COLOR_RGBX16:
1415 case OMAP_DSS_COLOR_ARGB16_1555:
1416 case OMAP_DSS_COLOR_XRGB16_1555:
1203 return 16; 1417 return 16;
1204 case OMAP_DSS_COLOR_RGB24P: 1418 case OMAP_DSS_COLOR_RGB24P:
1205 return 24; 1419 return 24;
@@ -1449,12 +1663,13 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
1449 } 1663 }
1450} 1664}
1451 1665
1452static unsigned long calc_fclk_five_taps(u16 width, u16 height, 1666static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1453 u16 out_width, u16 out_height, enum omap_color_mode color_mode) 1667 u16 height, u16 out_width, u16 out_height,
1668 enum omap_color_mode color_mode)
1454{ 1669{
1455 u32 fclk = 0; 1670 u32 fclk = 0;
1456 /* FIXME venc pclk? */ 1671 /* FIXME venc pclk? */
1457 u64 tmp, pclk = dispc_pclk_rate(); 1672 u64 tmp, pclk = dispc_pclk_rate(channel);
1458 1673
1459 if (height > out_height) { 1674 if (height > out_height) {
1460 /* FIXME get real display PPL */ 1675 /* FIXME get real display PPL */
@@ -1486,8 +1701,8 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height,
1486 return fclk; 1701 return fclk;
1487} 1702}
1488 1703
1489static unsigned long calc_fclk(u16 width, u16 height, 1704static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1490 u16 out_width, u16 out_height) 1705 u16 height, u16 out_width, u16 out_height)
1491{ 1706{
1492 unsigned int hf, vf; 1707 unsigned int hf, vf;
1493 1708
@@ -1511,7 +1726,7 @@ static unsigned long calc_fclk(u16 width, u16 height,
1511 vf = 1; 1726 vf = 1;
1512 1727
1513 /* FIXME venc pclk? */ 1728 /* FIXME venc pclk? */
1514 return dispc_pclk_rate() * vf * hf; 1729 return dispc_pclk_rate(channel) * vf * hf;
1515} 1730}
1516 1731
1517void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) 1732void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out)
@@ -1530,7 +1745,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1530 bool ilace, 1745 bool ilace,
1531 enum omap_dss_rotation_type rotation_type, 1746 enum omap_dss_rotation_type rotation_type,
1532 u8 rotation, int mirror, 1747 u8 rotation, int mirror,
1533 u8 global_alpha) 1748 u8 global_alpha, u8 pre_mult_alpha,
1749 enum omap_channel channel, u32 puv_addr)
1534{ 1750{
1535 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; 1751 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
1536 bool five_taps = 0; 1752 bool five_taps = 0;
@@ -1559,27 +1775,12 @@ static int _dispc_setup_plane(enum omap_plane plane,
1559 height, pos_y, out_height); 1775 height, pos_y, out_height);
1560 } 1776 }
1561 1777
1778 if (!dss_feat_color_mode_supported(plane, color_mode))
1779 return -EINVAL;
1780
1562 if (plane == OMAP_DSS_GFX) { 1781 if (plane == OMAP_DSS_GFX) {
1563 if (width != out_width || height != out_height) 1782 if (width != out_width || height != out_height)
1564 return -EINVAL; 1783 return -EINVAL;
1565
1566 switch (color_mode) {
1567 case OMAP_DSS_COLOR_ARGB16:
1568 case OMAP_DSS_COLOR_ARGB32:
1569 case OMAP_DSS_COLOR_RGBA32:
1570 case OMAP_DSS_COLOR_RGBX32:
1571 if (cpu_is_omap24xx())
1572 return -EINVAL;
1573 /* fall through */
1574 case OMAP_DSS_COLOR_RGB12U:
1575 case OMAP_DSS_COLOR_RGB16:
1576 case OMAP_DSS_COLOR_RGB24P:
1577 case OMAP_DSS_COLOR_RGB24U:
1578 break;
1579
1580 default:
1581 return -EINVAL;
1582 }
1583 } else { 1784 } else {
1584 /* video plane */ 1785 /* video plane */
1585 1786
@@ -1593,41 +1794,17 @@ static int _dispc_setup_plane(enum omap_plane plane,
1593 out_height > height * 8) 1794 out_height > height * 8)
1594 return -EINVAL; 1795 return -EINVAL;
1595 1796
1596 switch (color_mode) { 1797 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1597 case OMAP_DSS_COLOR_RGBX32: 1798 color_mode == OMAP_DSS_COLOR_UYVY ||
1598 case OMAP_DSS_COLOR_RGB12U: 1799 color_mode == OMAP_DSS_COLOR_NV12)
1599 if (cpu_is_omap24xx())
1600 return -EINVAL;
1601 /* fall through */
1602 case OMAP_DSS_COLOR_RGB16:
1603 case OMAP_DSS_COLOR_RGB24P:
1604 case OMAP_DSS_COLOR_RGB24U:
1605 break;
1606
1607 case OMAP_DSS_COLOR_ARGB16:
1608 case OMAP_DSS_COLOR_ARGB32:
1609 case OMAP_DSS_COLOR_RGBA32:
1610 if (cpu_is_omap24xx())
1611 return -EINVAL;
1612 if (plane == OMAP_DSS_VIDEO1)
1613 return -EINVAL;
1614 break;
1615
1616 case OMAP_DSS_COLOR_YUV2:
1617 case OMAP_DSS_COLOR_UYVY:
1618 cconv = 1; 1800 cconv = 1;
1619 break;
1620
1621 default:
1622 return -EINVAL;
1623 }
1624 1801
1625 /* Must use 5-tap filter? */ 1802 /* Must use 5-tap filter? */
1626 five_taps = height > out_height * 2; 1803 five_taps = height > out_height * 2;
1627 1804
1628 if (!five_taps) { 1805 if (!five_taps) {
1629 fclk = calc_fclk(width, height, 1806 fclk = calc_fclk(channel, width, height, out_width,
1630 out_width, out_height); 1807 out_height);
1631 1808
1632 /* Try 5-tap filter if 3-tap fclk is too high */ 1809 /* Try 5-tap filter if 3-tap fclk is too high */
1633 if (cpu_is_omap34xx() && height > out_height && 1810 if (cpu_is_omap34xx() && height > out_height &&
@@ -1641,7 +1818,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
1641 } 1818 }
1642 1819
1643 if (five_taps) 1820 if (five_taps)
1644 fclk = calc_fclk_five_taps(width, height, 1821 fclk = calc_fclk_five_taps(channel, width, height,
1645 out_width, out_height, color_mode); 1822 out_width, out_height, color_mode);
1646 1823
1647 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1824 DSSDBG("required fclk rate = %lu Hz\n", fclk);
@@ -1693,6 +1870,12 @@ static int _dispc_setup_plane(enum omap_plane plane,
1693 _dispc_set_plane_ba0(plane, paddr + offset0); 1870 _dispc_set_plane_ba0(plane, paddr + offset0);
1694 _dispc_set_plane_ba1(plane, paddr + offset1); 1871 _dispc_set_plane_ba1(plane, paddr + offset1);
1695 1872
1873 if (OMAP_DSS_COLOR_NV12 == color_mode) {
1874 _dispc_set_plane_ba0_uv(plane, puv_addr + offset0);
1875 _dispc_set_plane_ba1_uv(plane, puv_addr + offset1);
1876 }
1877
1878
1696 _dispc_set_row_inc(plane, row_inc); 1879 _dispc_set_row_inc(plane, row_inc);
1697 _dispc_set_pix_inc(plane, pix_inc); 1880 _dispc_set_pix_inc(plane, pix_inc);
1698 1881
@@ -1706,22 +1889,23 @@ static int _dispc_setup_plane(enum omap_plane plane,
1706 if (plane != OMAP_DSS_GFX) { 1889 if (plane != OMAP_DSS_GFX) {
1707 _dispc_set_scaling(plane, width, height, 1890 _dispc_set_scaling(plane, width, height,
1708 out_width, out_height, 1891 out_width, out_height,
1709 ilace, five_taps, fieldmode); 1892 ilace, five_taps, fieldmode,
1893 color_mode, rotation);
1710 _dispc_set_vid_size(plane, out_width, out_height); 1894 _dispc_set_vid_size(plane, out_width, out_height);
1711 _dispc_set_vid_color_conv(plane, cconv); 1895 _dispc_set_vid_color_conv(plane, cconv);
1712 } 1896 }
1713 1897
1714 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode); 1898 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode);
1715 1899
1716 if (plane != OMAP_DSS_VIDEO1) 1900 _dispc_set_pre_mult_alpha(plane, pre_mult_alpha);
1717 _dispc_setup_global_alpha(plane, global_alpha); 1901 _dispc_setup_global_alpha(plane, global_alpha);
1718 1902
1719 return 0; 1903 return 0;
1720} 1904}
1721 1905
1722static void _dispc_enable_plane(enum omap_plane plane, bool enable) 1906static void _dispc_enable_plane(enum omap_plane plane, bool enable)
1723{ 1907{
1724 REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 0, 0); 1908 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
1725} 1909}
1726 1910
1727static void dispc_disable_isr(void *data, u32 mask) 1911static void dispc_disable_isr(void *data, u32 mask)
@@ -1730,36 +1914,44 @@ static void dispc_disable_isr(void *data, u32 mask)
1730 complete(compl); 1914 complete(compl);
1731} 1915}
1732 1916
1733static void _enable_lcd_out(bool enable) 1917static void _enable_lcd_out(enum omap_channel channel, bool enable)
1734{ 1918{
1735 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1919 if (channel == OMAP_DSS_CHANNEL_LCD2)
1920 REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
1921 else
1922 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
1736} 1923}
1737 1924
1738static void dispc_enable_lcd_out(bool enable) 1925static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
1739{ 1926{
1740 struct completion frame_done_completion; 1927 struct completion frame_done_completion;
1741 bool is_on; 1928 bool is_on;
1742 int r; 1929 int r;
1930 u32 irq;
1743 1931
1744 enable_clocks(1); 1932 enable_clocks(1);
1745 1933
1746 /* When we disable LCD output, we need to wait until frame is done. 1934 /* When we disable LCD output, we need to wait until frame is done.
1747 * Otherwise the DSS is still working, and turning off the clocks 1935 * Otherwise the DSS is still working, and turning off the clocks
1748 * prevents DSS from going to OFF mode */ 1936 * prevents DSS from going to OFF mode */
1749 is_on = REG_GET(DISPC_CONTROL, 0, 0); 1937 is_on = channel == OMAP_DSS_CHANNEL_LCD2 ?
1938 REG_GET(DISPC_CONTROL2, 0, 0) :
1939 REG_GET(DISPC_CONTROL, 0, 0);
1940
1941 irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 :
1942 DISPC_IRQ_FRAMEDONE;
1750 1943
1751 if (!enable && is_on) { 1944 if (!enable && is_on) {
1752 init_completion(&frame_done_completion); 1945 init_completion(&frame_done_completion);
1753 1946
1754 r = omap_dispc_register_isr(dispc_disable_isr, 1947 r = omap_dispc_register_isr(dispc_disable_isr,
1755 &frame_done_completion, 1948 &frame_done_completion, irq);
1756 DISPC_IRQ_FRAMEDONE);
1757 1949
1758 if (r) 1950 if (r)
1759 DSSERR("failed to register FRAMEDONE isr\n"); 1951 DSSERR("failed to register FRAMEDONE isr\n");
1760 } 1952 }
1761 1953
1762 _enable_lcd_out(enable); 1954 _enable_lcd_out(channel, enable);
1763 1955
1764 if (!enable && is_on) { 1956 if (!enable && is_on) {
1765 if (!wait_for_completion_timeout(&frame_done_completion, 1957 if (!wait_for_completion_timeout(&frame_done_completion,
@@ -1767,8 +1959,7 @@ static void dispc_enable_lcd_out(bool enable)
1767 DSSERR("timeout waiting for FRAME DONE\n"); 1959 DSSERR("timeout waiting for FRAME DONE\n");
1768 1960
1769 r = omap_dispc_unregister_isr(dispc_disable_isr, 1961 r = omap_dispc_unregister_isr(dispc_disable_isr,
1770 &frame_done_completion, 1962 &frame_done_completion, irq);
1771 DISPC_IRQ_FRAMEDONE);
1772 1963
1773 if (r) 1964 if (r)
1774 DSSERR("failed to unregister FRAMEDONE isr\n"); 1965 DSSERR("failed to unregister FRAMEDONE isr\n");
@@ -1838,6 +2029,8 @@ static void dispc_enable_digit_out(bool enable)
1838 unsigned long flags; 2029 unsigned long flags;
1839 spin_lock_irqsave(&dispc.irq_lock, flags); 2030 spin_lock_irqsave(&dispc.irq_lock, flags);
1840 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 2031 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
2032 if (dss_has_feature(FEAT_MGR_LCD2))
2033 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
1841 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 2034 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
1842 _omap_dispc_set_irqs(); 2035 _omap_dispc_set_irqs();
1843 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2036 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -1852,14 +2045,17 @@ bool dispc_is_channel_enabled(enum omap_channel channel)
1852 return !!REG_GET(DISPC_CONTROL, 0, 0); 2045 return !!REG_GET(DISPC_CONTROL, 0, 0);
1853 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 2046 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1854 return !!REG_GET(DISPC_CONTROL, 1, 1); 2047 return !!REG_GET(DISPC_CONTROL, 1, 1);
2048 else if (channel == OMAP_DSS_CHANNEL_LCD2)
2049 return !!REG_GET(DISPC_CONTROL2, 0, 0);
1855 else 2050 else
1856 BUG(); 2051 BUG();
1857} 2052}
1858 2053
1859void dispc_enable_channel(enum omap_channel channel, bool enable) 2054void dispc_enable_channel(enum omap_channel channel, bool enable)
1860{ 2055{
1861 if (channel == OMAP_DSS_CHANNEL_LCD) 2056 if (channel == OMAP_DSS_CHANNEL_LCD ||
1862 dispc_enable_lcd_out(enable); 2057 channel == OMAP_DSS_CHANNEL_LCD2)
2058 dispc_enable_lcd_out(channel, enable);
1863 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 2059 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1864 dispc_enable_digit_out(enable); 2060 dispc_enable_digit_out(enable);
1865 else 2061 else
@@ -1868,6 +2064,9 @@ void dispc_enable_channel(enum omap_channel channel, bool enable)
1868 2064
1869void dispc_lcd_enable_signal_polarity(bool act_high) 2065void dispc_lcd_enable_signal_polarity(bool act_high)
1870{ 2066{
2067 if (!dss_has_feature(FEAT_LCDENABLEPOL))
2068 return;
2069
1871 enable_clocks(1); 2070 enable_clocks(1);
1872 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29); 2071 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
1873 enable_clocks(0); 2072 enable_clocks(0);
@@ -1875,6 +2074,9 @@ void dispc_lcd_enable_signal_polarity(bool act_high)
1875 2074
1876void dispc_lcd_enable_signal(bool enable) 2075void dispc_lcd_enable_signal(bool enable)
1877{ 2076{
2077 if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
2078 return;
2079
1878 enable_clocks(1); 2080 enable_clocks(1);
1879 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28); 2081 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
1880 enable_clocks(0); 2082 enable_clocks(0);
@@ -1882,20 +2084,27 @@ void dispc_lcd_enable_signal(bool enable)
1882 2084
1883void dispc_pck_free_enable(bool enable) 2085void dispc_pck_free_enable(bool enable)
1884{ 2086{
2087 if (!dss_has_feature(FEAT_PCKFREEENABLE))
2088 return;
2089
1885 enable_clocks(1); 2090 enable_clocks(1);
1886 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 2091 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
1887 enable_clocks(0); 2092 enable_clocks(0);
1888} 2093}
1889 2094
1890void dispc_enable_fifohandcheck(bool enable) 2095void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
1891{ 2096{
1892 enable_clocks(1); 2097 enable_clocks(1);
1893 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); 2098 if (channel == OMAP_DSS_CHANNEL_LCD2)
2099 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
2100 else
2101 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
1894 enable_clocks(0); 2102 enable_clocks(0);
1895} 2103}
1896 2104
1897 2105
1898void dispc_set_lcd_display_type(enum omap_lcd_display_type type) 2106void dispc_set_lcd_display_type(enum omap_channel channel,
2107 enum omap_lcd_display_type type)
1899{ 2108{
1900 int mode; 2109 int mode;
1901 2110
@@ -1914,7 +2123,10 @@ void dispc_set_lcd_display_type(enum omap_lcd_display_type type)
1914 } 2123 }
1915 2124
1916 enable_clocks(1); 2125 enable_clocks(1);
1917 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); 2126 if (channel == OMAP_DSS_CHANNEL_LCD2)
2127 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
2128 else
2129 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
1918 enable_clocks(0); 2130 enable_clocks(0);
1919} 2131}
1920 2132
@@ -1928,25 +2140,21 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
1928 2140
1929void dispc_set_default_color(enum omap_channel channel, u32 color) 2141void dispc_set_default_color(enum omap_channel channel, u32 color)
1930{ 2142{
1931 const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
1932 DISPC_DEFAULT_COLOR1 };
1933
1934 enable_clocks(1); 2143 enable_clocks(1);
1935 dispc_write_reg(def_reg[channel], color); 2144 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
1936 enable_clocks(0); 2145 enable_clocks(0);
1937} 2146}
1938 2147
1939u32 dispc_get_default_color(enum omap_channel channel) 2148u32 dispc_get_default_color(enum omap_channel channel)
1940{ 2149{
1941 const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
1942 DISPC_DEFAULT_COLOR1 };
1943 u32 l; 2150 u32 l;
1944 2151
1945 BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && 2152 BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
1946 channel != OMAP_DSS_CHANNEL_LCD); 2153 channel != OMAP_DSS_CHANNEL_LCD &&
2154 channel != OMAP_DSS_CHANNEL_LCD2);
1947 2155
1948 enable_clocks(1); 2156 enable_clocks(1);
1949 l = dispc_read_reg(def_reg[channel]); 2157 l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
1950 enable_clocks(0); 2158 enable_clocks(0);
1951 2159
1952 return l; 2160 return l;
@@ -1956,16 +2164,15 @@ void dispc_set_trans_key(enum omap_channel ch,
1956 enum omap_dss_trans_key_type type, 2164 enum omap_dss_trans_key_type type,
1957 u32 trans_key) 2165 u32 trans_key)
1958{ 2166{
1959 const struct dispc_reg tr_reg[] = {
1960 DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
1961
1962 enable_clocks(1); 2167 enable_clocks(1);
1963 if (ch == OMAP_DSS_CHANNEL_LCD) 2168 if (ch == OMAP_DSS_CHANNEL_LCD)
1964 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); 2169 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
1965 else /* OMAP_DSS_CHANNEL_DIGIT */ 2170 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1966 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); 2171 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
2172 else /* OMAP_DSS_CHANNEL_LCD2 */
2173 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
1967 2174
1968 dispc_write_reg(tr_reg[ch], trans_key); 2175 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
1969 enable_clocks(0); 2176 enable_clocks(0);
1970} 2177}
1971 2178
@@ -1973,21 +2180,20 @@ void dispc_get_trans_key(enum omap_channel ch,
1973 enum omap_dss_trans_key_type *type, 2180 enum omap_dss_trans_key_type *type,
1974 u32 *trans_key) 2181 u32 *trans_key)
1975{ 2182{
1976 const struct dispc_reg tr_reg[] = {
1977 DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
1978
1979 enable_clocks(1); 2183 enable_clocks(1);
1980 if (type) { 2184 if (type) {
1981 if (ch == OMAP_DSS_CHANNEL_LCD) 2185 if (ch == OMAP_DSS_CHANNEL_LCD)
1982 *type = REG_GET(DISPC_CONFIG, 11, 11); 2186 *type = REG_GET(DISPC_CONFIG, 11, 11);
1983 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2187 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1984 *type = REG_GET(DISPC_CONFIG, 13, 13); 2188 *type = REG_GET(DISPC_CONFIG, 13, 13);
2189 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2190 *type = REG_GET(DISPC_CONFIG2, 11, 11);
1985 else 2191 else
1986 BUG(); 2192 BUG();
1987 } 2193 }
1988 2194
1989 if (trans_key) 2195 if (trans_key)
1990 *trans_key = dispc_read_reg(tr_reg[ch]); 2196 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
1991 enable_clocks(0); 2197 enable_clocks(0);
1992} 2198}
1993 2199
@@ -1996,40 +2202,45 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable)
1996 enable_clocks(1); 2202 enable_clocks(1);
1997 if (ch == OMAP_DSS_CHANNEL_LCD) 2203 if (ch == OMAP_DSS_CHANNEL_LCD)
1998 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); 2204 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
1999 else /* OMAP_DSS_CHANNEL_DIGIT */ 2205 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2000 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); 2206 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
2207 else /* OMAP_DSS_CHANNEL_LCD2 */
2208 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
2001 enable_clocks(0); 2209 enable_clocks(0);
2002} 2210}
2003void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2211void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
2004{ 2212{
2005 if (cpu_is_omap24xx()) 2213 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
2006 return; 2214 return;
2007 2215
2008 enable_clocks(1); 2216 enable_clocks(1);
2009 if (ch == OMAP_DSS_CHANNEL_LCD) 2217 if (ch == OMAP_DSS_CHANNEL_LCD)
2010 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); 2218 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
2011 else /* OMAP_DSS_CHANNEL_DIGIT */ 2219 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2012 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 2220 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
2221 else /* OMAP_DSS_CHANNEL_LCD2 */
2222 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
2013 enable_clocks(0); 2223 enable_clocks(0);
2014} 2224}
2015bool dispc_alpha_blending_enabled(enum omap_channel ch) 2225bool dispc_alpha_blending_enabled(enum omap_channel ch)
2016{ 2226{
2017 bool enabled; 2227 bool enabled;
2018 2228
2019 if (cpu_is_omap24xx()) 2229 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
2020 return false; 2230 return false;
2021 2231
2022 enable_clocks(1); 2232 enable_clocks(1);
2023 if (ch == OMAP_DSS_CHANNEL_LCD) 2233 if (ch == OMAP_DSS_CHANNEL_LCD)
2024 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2234 enabled = REG_GET(DISPC_CONFIG, 18, 18);
2025 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2235 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2026 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2236 enabled = REG_GET(DISPC_CONFIG, 19, 19);
2237 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2238 enabled = REG_GET(DISPC_CONFIG2, 18, 18);
2027 else 2239 else
2028 BUG(); 2240 BUG();
2029 enable_clocks(0); 2241 enable_clocks(0);
2030 2242
2031 return enabled; 2243 return enabled;
2032
2033} 2244}
2034 2245
2035 2246
@@ -2042,6 +2253,8 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2042 enabled = REG_GET(DISPC_CONFIG, 10, 10); 2253 enabled = REG_GET(DISPC_CONFIG, 10, 10);
2043 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2254 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2044 enabled = REG_GET(DISPC_CONFIG, 12, 12); 2255 enabled = REG_GET(DISPC_CONFIG, 12, 12);
2256 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2257 enabled = REG_GET(DISPC_CONFIG2, 10, 10);
2045 else 2258 else
2046 BUG(); 2259 BUG();
2047 enable_clocks(0); 2260 enable_clocks(0);
@@ -2050,7 +2263,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2050} 2263}
2051 2264
2052 2265
2053void dispc_set_tft_data_lines(u8 data_lines) 2266void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2054{ 2267{
2055 int code; 2268 int code;
2056 2269
@@ -2073,11 +2286,15 @@ void dispc_set_tft_data_lines(u8 data_lines)
2073 } 2286 }
2074 2287
2075 enable_clocks(1); 2288 enable_clocks(1);
2076 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); 2289 if (channel == OMAP_DSS_CHANNEL_LCD2)
2290 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
2291 else
2292 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2077 enable_clocks(0); 2293 enable_clocks(0);
2078} 2294}
2079 2295
2080void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode) 2296void dispc_set_parallel_interface_mode(enum omap_channel channel,
2297 enum omap_parallel_interface_mode mode)
2081{ 2298{
2082 u32 l; 2299 u32 l;
2083 int stallmode; 2300 int stallmode;
@@ -2107,13 +2324,17 @@ void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode)
2107 2324
2108 enable_clocks(1); 2325 enable_clocks(1);
2109 2326
2110 l = dispc_read_reg(DISPC_CONTROL); 2327 if (channel == OMAP_DSS_CHANNEL_LCD2) {
2111 2328 l = dispc_read_reg(DISPC_CONTROL2);
2112 l = FLD_MOD(l, stallmode, 11, 11); 2329 l = FLD_MOD(l, stallmode, 11, 11);
2113 l = FLD_MOD(l, gpout0, 15, 15); 2330 dispc_write_reg(DISPC_CONTROL2, l);
2114 l = FLD_MOD(l, gpout1, 16, 16); 2331 } else {
2115 2332 l = dispc_read_reg(DISPC_CONTROL);
2116 dispc_write_reg(DISPC_CONTROL, l); 2333 l = FLD_MOD(l, stallmode, 11, 11);
2334 l = FLD_MOD(l, gpout0, 15, 15);
2335 l = FLD_MOD(l, gpout1, 16, 16);
2336 dispc_write_reg(DISPC_CONTROL, l);
2337 }
2117 2338
2118 enable_clocks(0); 2339 enable_clocks(0);
2119} 2340}
@@ -2149,8 +2370,8 @@ bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
2149 timings->vfp, timings->vbp); 2370 timings->vfp, timings->vbp);
2150} 2371}
2151 2372
2152static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp, 2373static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
2153 int vsw, int vfp, int vbp) 2374 int hfp, int hbp, int vsw, int vfp, int vbp)
2154{ 2375{
2155 u32 timing_h, timing_v; 2376 u32 timing_h, timing_v;
2156 2377
@@ -2169,13 +2390,14 @@ static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp,
2169 } 2390 }
2170 2391
2171 enable_clocks(1); 2392 enable_clocks(1);
2172 dispc_write_reg(DISPC_TIMING_H, timing_h); 2393 dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
2173 dispc_write_reg(DISPC_TIMING_V, timing_v); 2394 dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
2174 enable_clocks(0); 2395 enable_clocks(0);
2175} 2396}
2176 2397
2177/* change name to mode? */ 2398/* change name to mode? */
2178void dispc_set_lcd_timings(struct omap_video_timings *timings) 2399void dispc_set_lcd_timings(enum omap_channel channel,
2400 struct omap_video_timings *timings)
2179{ 2401{
2180 unsigned xtot, ytot; 2402 unsigned xtot, ytot;
2181 unsigned long ht, vt; 2403 unsigned long ht, vt;
@@ -2185,10 +2407,11 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2185 timings->vfp, timings->vbp)) 2407 timings->vfp, timings->vbp))
2186 BUG(); 2408 BUG();
2187 2409
2188 _dispc_set_lcd_timings(timings->hsw, timings->hfp, timings->hbp, 2410 _dispc_set_lcd_timings(channel, timings->hsw, timings->hfp,
2189 timings->vsw, timings->vfp, timings->vbp); 2411 timings->hbp, timings->vsw, timings->vfp,
2412 timings->vbp);
2190 2413
2191 dispc_set_lcd_size(timings->x_res, timings->y_res); 2414 dispc_set_lcd_size(channel, timings->x_res, timings->y_res);
2192 2415
2193 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; 2416 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
2194 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; 2417 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
@@ -2196,7 +2419,8 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2196 ht = (timings->pixel_clock * 1000) / xtot; 2419 ht = (timings->pixel_clock * 1000) / xtot;
2197 vt = (timings->pixel_clock * 1000) / xtot / ytot; 2420 vt = (timings->pixel_clock * 1000) / xtot / ytot;
2198 2421
2199 DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res); 2422 DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res,
2423 timings->y_res);
2200 DSSDBG("pck %u\n", timings->pixel_clock); 2424 DSSDBG("pck %u\n", timings->pixel_clock);
2201 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2425 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2202 timings->hsw, timings->hfp, timings->hbp, 2426 timings->hsw, timings->hfp, timings->hbp,
@@ -2205,89 +2429,151 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2205 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2429 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2206} 2430}
2207 2431
2208static void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div) 2432static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2433 u16 pck_div)
2209{ 2434{
2210 BUG_ON(lck_div < 1); 2435 BUG_ON(lck_div < 1);
2211 BUG_ON(pck_div < 2); 2436 BUG_ON(pck_div < 2);
2212 2437
2213 enable_clocks(1); 2438 enable_clocks(1);
2214 dispc_write_reg(DISPC_DIVISOR, 2439 dispc_write_reg(DISPC_DIVISORo(channel),
2215 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2440 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2216 enable_clocks(0); 2441 enable_clocks(0);
2217} 2442}
2218 2443
2219static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) 2444static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2445 int *pck_div)
2220{ 2446{
2221 u32 l; 2447 u32 l;
2222 l = dispc_read_reg(DISPC_DIVISOR); 2448 l = dispc_read_reg(DISPC_DIVISORo(channel));
2223 *lck_div = FLD_GET(l, 23, 16); 2449 *lck_div = FLD_GET(l, 23, 16);
2224 *pck_div = FLD_GET(l, 7, 0); 2450 *pck_div = FLD_GET(l, 7, 0);
2225} 2451}
2226 2452
2227unsigned long dispc_fclk_rate(void) 2453unsigned long dispc_fclk_rate(void)
2228{ 2454{
2455 struct platform_device *dsidev;
2229 unsigned long r = 0; 2456 unsigned long r = 0;
2230 2457
2231 if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) 2458 switch (dss_get_dispc_clk_source()) {
2232 r = dss_clk_get_rate(DSS_CLK_FCK1); 2459 case OMAP_DSS_CLK_SRC_FCK:
2233 else 2460 r = dss_clk_get_rate(DSS_CLK_FCK);
2234#ifdef CONFIG_OMAP2_DSS_DSI 2461 break;
2235 r = dsi_get_dsi1_pll_rate(); 2462 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2236#else 2463 dsidev = dsi_get_dsidev_from_id(0);
2237 BUG(); 2464 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2238#endif 2465 break;
2466 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
2467 dsidev = dsi_get_dsidev_from_id(1);
2468 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2469 break;
2470 default:
2471 BUG();
2472 }
2473
2239 return r; 2474 return r;
2240} 2475}
2241 2476
2242unsigned long dispc_lclk_rate(void) 2477unsigned long dispc_lclk_rate(enum omap_channel channel)
2243{ 2478{
2479 struct platform_device *dsidev;
2244 int lcd; 2480 int lcd;
2245 unsigned long r; 2481 unsigned long r;
2246 u32 l; 2482 u32 l;
2247 2483
2248 l = dispc_read_reg(DISPC_DIVISOR); 2484 l = dispc_read_reg(DISPC_DIVISORo(channel));
2249 2485
2250 lcd = FLD_GET(l, 23, 16); 2486 lcd = FLD_GET(l, 23, 16);
2251 2487
2252 r = dispc_fclk_rate(); 2488 switch (dss_get_lcd_clk_source(channel)) {
2489 case OMAP_DSS_CLK_SRC_FCK:
2490 r = dss_clk_get_rate(DSS_CLK_FCK);
2491 break;
2492 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2493 dsidev = dsi_get_dsidev_from_id(0);
2494 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2495 break;
2496 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
2497 dsidev = dsi_get_dsidev_from_id(1);
2498 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2499 break;
2500 default:
2501 BUG();
2502 }
2253 2503
2254 return r / lcd; 2504 return r / lcd;
2255} 2505}
2256 2506
2257unsigned long dispc_pclk_rate(void) 2507unsigned long dispc_pclk_rate(enum omap_channel channel)
2258{ 2508{
2259 int lcd, pcd; 2509 int pcd;
2260 unsigned long r; 2510 unsigned long r;
2261 u32 l; 2511 u32 l;
2262 2512
2263 l = dispc_read_reg(DISPC_DIVISOR); 2513 l = dispc_read_reg(DISPC_DIVISORo(channel));
2264 2514
2265 lcd = FLD_GET(l, 23, 16);
2266 pcd = FLD_GET(l, 7, 0); 2515 pcd = FLD_GET(l, 7, 0);
2267 2516
2268 r = dispc_fclk_rate(); 2517 r = dispc_lclk_rate(channel);
2269 2518
2270 return r / lcd / pcd; 2519 return r / pcd;
2271} 2520}
2272 2521
2273void dispc_dump_clocks(struct seq_file *s) 2522void dispc_dump_clocks(struct seq_file *s)
2274{ 2523{
2275 int lcd, pcd; 2524 int lcd, pcd;
2525 u32 l;
2526 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2527 enum omap_dss_clk_source lcd_clk_src;
2276 2528
2277 enable_clocks(1); 2529 enable_clocks(1);
2278 2530
2279 dispc_get_lcd_divisor(&lcd, &pcd);
2280
2281 seq_printf(s, "- DISPC -\n"); 2531 seq_printf(s, "- DISPC -\n");
2282 2532
2283 seq_printf(s, "dispc fclk source = %s\n", 2533 seq_printf(s, "dispc fclk source = %s (%s)\n",
2284 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 2534 dss_get_generic_clk_source_name(dispc_clk_src),
2285 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2535 dss_feat_get_clk_source_name(dispc_clk_src));
2286 2536
2287 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2537 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2288 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", dispc_lclk_rate(), lcd);
2289 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", dispc_pclk_rate(), pcd);
2290 2538
2539 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
2540 seq_printf(s, "- DISPC-CORE-CLK -\n");
2541 l = dispc_read_reg(DISPC_DIVISOR);
2542 lcd = FLD_GET(l, 23, 16);
2543
2544 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2545 (dispc_fclk_rate()/lcd), lcd);
2546 }
2547 seq_printf(s, "- LCD1 -\n");
2548
2549 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD);
2550
2551 seq_printf(s, "lcd1_clk source = %s (%s)\n",
2552 dss_get_generic_clk_source_name(lcd_clk_src),
2553 dss_feat_get_clk_source_name(lcd_clk_src));
2554
2555 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2556
2557 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2558 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
2559 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2560 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
2561 if (dss_has_feature(FEAT_MGR_LCD2)) {
2562 seq_printf(s, "- LCD2 -\n");
2563
2564 lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2);
2565
2566 seq_printf(s, "lcd2_clk source = %s (%s)\n",
2567 dss_get_generic_clk_source_name(lcd_clk_src),
2568 dss_feat_get_clk_source_name(lcd_clk_src));
2569
2570 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2571
2572 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2573 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd);
2574 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2575 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2576 }
2291 enable_clocks(0); 2577 enable_clocks(0);
2292} 2578}
2293 2579
@@ -2329,15 +2615,21 @@ void dispc_dump_irqs(struct seq_file *s)
2329 PIS(SYNC_LOST); 2615 PIS(SYNC_LOST);
2330 PIS(SYNC_LOST_DIGIT); 2616 PIS(SYNC_LOST_DIGIT);
2331 PIS(WAKEUP); 2617 PIS(WAKEUP);
2618 if (dss_has_feature(FEAT_MGR_LCD2)) {
2619 PIS(FRAMEDONE2);
2620 PIS(VSYNC2);
2621 PIS(ACBIAS_COUNT_STAT2);
2622 PIS(SYNC_LOST2);
2623 }
2332#undef PIS 2624#undef PIS
2333} 2625}
2334#endif 2626#endif
2335 2627
2336void dispc_dump_regs(struct seq_file *s) 2628void dispc_dump_regs(struct seq_file *s)
2337{ 2629{
2338#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) 2630#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
2339 2631
2340 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 2632 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
2341 2633
2342 DUMPREG(DISPC_REVISION); 2634 DUMPREG(DISPC_REVISION);
2343 DUMPREG(DISPC_SYSCONFIG); 2635 DUMPREG(DISPC_SYSCONFIG);
@@ -2347,139 +2639,234 @@ void dispc_dump_regs(struct seq_file *s)
2347 DUMPREG(DISPC_CONTROL); 2639 DUMPREG(DISPC_CONTROL);
2348 DUMPREG(DISPC_CONFIG); 2640 DUMPREG(DISPC_CONFIG);
2349 DUMPREG(DISPC_CAPABLE); 2641 DUMPREG(DISPC_CAPABLE);
2350 DUMPREG(DISPC_DEFAULT_COLOR0); 2642 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
2351 DUMPREG(DISPC_DEFAULT_COLOR1); 2643 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
2352 DUMPREG(DISPC_TRANS_COLOR0); 2644 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
2353 DUMPREG(DISPC_TRANS_COLOR1); 2645 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
2354 DUMPREG(DISPC_LINE_STATUS); 2646 DUMPREG(DISPC_LINE_STATUS);
2355 DUMPREG(DISPC_LINE_NUMBER); 2647 DUMPREG(DISPC_LINE_NUMBER);
2356 DUMPREG(DISPC_TIMING_H); 2648 DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD));
2357 DUMPREG(DISPC_TIMING_V); 2649 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD));
2358 DUMPREG(DISPC_POL_FREQ); 2650 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD));
2359 DUMPREG(DISPC_DIVISOR); 2651 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD));
2360 DUMPREG(DISPC_GLOBAL_ALPHA); 2652 DUMPREG(DISPC_GLOBAL_ALPHA);
2361 DUMPREG(DISPC_SIZE_DIG); 2653 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
2362 DUMPREG(DISPC_SIZE_LCD); 2654 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
2363 2655 if (dss_has_feature(FEAT_MGR_LCD2)) {
2364 DUMPREG(DISPC_GFX_BA0); 2656 DUMPREG(DISPC_CONTROL2);
2365 DUMPREG(DISPC_GFX_BA1); 2657 DUMPREG(DISPC_CONFIG2);
2366 DUMPREG(DISPC_GFX_POSITION); 2658 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
2367 DUMPREG(DISPC_GFX_SIZE); 2659 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
2368 DUMPREG(DISPC_GFX_ATTRIBUTES); 2660 DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD2));
2369 DUMPREG(DISPC_GFX_FIFO_THRESHOLD); 2661 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD2));
2370 DUMPREG(DISPC_GFX_FIFO_SIZE_STATUS); 2662 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
2371 DUMPREG(DISPC_GFX_ROW_INC); 2663 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD2));
2372 DUMPREG(DISPC_GFX_PIXEL_INC); 2664 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
2373 DUMPREG(DISPC_GFX_WINDOW_SKIP); 2665 }
2374 DUMPREG(DISPC_GFX_TABLE_BA); 2666
2375 2667 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_GFX));
2376 DUMPREG(DISPC_DATA_CYCLE1); 2668 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_GFX));
2377 DUMPREG(DISPC_DATA_CYCLE2); 2669 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_GFX));
2378 DUMPREG(DISPC_DATA_CYCLE3); 2670 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_GFX));
2379 2671 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_GFX));
2380 DUMPREG(DISPC_CPR_COEF_R); 2672 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
2381 DUMPREG(DISPC_CPR_COEF_G); 2673 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_GFX));
2382 DUMPREG(DISPC_CPR_COEF_B); 2674 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_GFX));
2383 2675 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_GFX));
2384 DUMPREG(DISPC_GFX_PRELOAD); 2676 DUMPREG(DISPC_OVL_WINDOW_SKIP(OMAP_DSS_GFX));
2385 2677 DUMPREG(DISPC_OVL_TABLE_BA(OMAP_DSS_GFX));
2386 DUMPREG(DISPC_VID_BA0(0)); 2678
2387 DUMPREG(DISPC_VID_BA1(0)); 2679 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
2388 DUMPREG(DISPC_VID_POSITION(0)); 2680 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
2389 DUMPREG(DISPC_VID_SIZE(0)); 2681 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
2390 DUMPREG(DISPC_VID_ATTRIBUTES(0)); 2682
2391 DUMPREG(DISPC_VID_FIFO_THRESHOLD(0)); 2683 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
2392 DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(0)); 2684 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
2393 DUMPREG(DISPC_VID_ROW_INC(0)); 2685 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
2394 DUMPREG(DISPC_VID_PIXEL_INC(0)); 2686 if (dss_has_feature(FEAT_MGR_LCD2)) {
2395 DUMPREG(DISPC_VID_FIR(0)); 2687 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
2396 DUMPREG(DISPC_VID_PICTURE_SIZE(0)); 2688 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
2397 DUMPREG(DISPC_VID_ACCU0(0)); 2689 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
2398 DUMPREG(DISPC_VID_ACCU1(0)); 2690
2399 2691 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
2400 DUMPREG(DISPC_VID_BA0(1)); 2692 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
2401 DUMPREG(DISPC_VID_BA1(1)); 2693 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
2402 DUMPREG(DISPC_VID_POSITION(1)); 2694 }
2403 DUMPREG(DISPC_VID_SIZE(1)); 2695
2404 DUMPREG(DISPC_VID_ATTRIBUTES(1)); 2696 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX));
2405 DUMPREG(DISPC_VID_FIFO_THRESHOLD(1)); 2697
2406 DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1)); 2698 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1));
2407 DUMPREG(DISPC_VID_ROW_INC(1)); 2699 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1));
2408 DUMPREG(DISPC_VID_PIXEL_INC(1)); 2700 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO1));
2409 DUMPREG(DISPC_VID_FIR(1)); 2701 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO1));
2410 DUMPREG(DISPC_VID_PICTURE_SIZE(1)); 2702 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
2411 DUMPREG(DISPC_VID_ACCU0(1)); 2703 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
2412 DUMPREG(DISPC_VID_ACCU1(1)); 2704 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO1));
2413 2705 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO1));
2414 DUMPREG(DISPC_VID_FIR_COEF_H(0, 0)); 2706 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
2415 DUMPREG(DISPC_VID_FIR_COEF_H(0, 1)); 2707 DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO1));
2416 DUMPREG(DISPC_VID_FIR_COEF_H(0, 2)); 2708 DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
2417 DUMPREG(DISPC_VID_FIR_COEF_H(0, 3)); 2709 DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO1));
2418 DUMPREG(DISPC_VID_FIR_COEF_H(0, 4)); 2710 DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO1));
2419 DUMPREG(DISPC_VID_FIR_COEF_H(0, 5)); 2711
2420 DUMPREG(DISPC_VID_FIR_COEF_H(0, 6)); 2712 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO2));
2421 DUMPREG(DISPC_VID_FIR_COEF_H(0, 7)); 2713 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO2));
2422 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 0)); 2714 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO2));
2423 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 1)); 2715 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO2));
2424 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 2)); 2716 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
2425 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 3)); 2717 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
2426 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 4)); 2718 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO2));
2427 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 5)); 2719 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO2));
2428 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 6)); 2720 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
2429 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 7)); 2721 DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO2));
2430 DUMPREG(DISPC_VID_CONV_COEF(0, 0)); 2722 DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
2431 DUMPREG(DISPC_VID_CONV_COEF(0, 1)); 2723 DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO2));
2432 DUMPREG(DISPC_VID_CONV_COEF(0, 2)); 2724 DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO2));
2433 DUMPREG(DISPC_VID_CONV_COEF(0, 3)); 2725
2434 DUMPREG(DISPC_VID_CONV_COEF(0, 4)); 2726 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 0));
2435 DUMPREG(DISPC_VID_FIR_COEF_V(0, 0)); 2727 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 1));
2436 DUMPREG(DISPC_VID_FIR_COEF_V(0, 1)); 2728 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 2));
2437 DUMPREG(DISPC_VID_FIR_COEF_V(0, 2)); 2729 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 3));
2438 DUMPREG(DISPC_VID_FIR_COEF_V(0, 3)); 2730 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 4));
2439 DUMPREG(DISPC_VID_FIR_COEF_V(0, 4)); 2731 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 5));
2440 DUMPREG(DISPC_VID_FIR_COEF_V(0, 5)); 2732 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 6));
2441 DUMPREG(DISPC_VID_FIR_COEF_V(0, 6)); 2733 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 7));
2442 DUMPREG(DISPC_VID_FIR_COEF_V(0, 7)); 2734 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 0));
2443 2735 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 1));
2444 DUMPREG(DISPC_VID_FIR_COEF_H(1, 0)); 2736 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 2));
2445 DUMPREG(DISPC_VID_FIR_COEF_H(1, 1)); 2737 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 3));
2446 DUMPREG(DISPC_VID_FIR_COEF_H(1, 2)); 2738 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 4));
2447 DUMPREG(DISPC_VID_FIR_COEF_H(1, 3)); 2739 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 5));
2448 DUMPREG(DISPC_VID_FIR_COEF_H(1, 4)); 2740 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 6));
2449 DUMPREG(DISPC_VID_FIR_COEF_H(1, 5)); 2741 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 7));
2450 DUMPREG(DISPC_VID_FIR_COEF_H(1, 6)); 2742 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0));
2451 DUMPREG(DISPC_VID_FIR_COEF_H(1, 7)); 2743 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1));
2452 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 0)); 2744 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2));
2453 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 1)); 2745 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3));
2454 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 2)); 2746 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4));
2455 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 3)); 2747 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0));
2456 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 4)); 2748 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1));
2457 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 5)); 2749 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2));
2458 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 6)); 2750 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3));
2459 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 7)); 2751 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4));
2460 DUMPREG(DISPC_VID_CONV_COEF(1, 0)); 2752 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5));
2461 DUMPREG(DISPC_VID_CONV_COEF(1, 1)); 2753 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6));
2462 DUMPREG(DISPC_VID_CONV_COEF(1, 2)); 2754 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7));
2463 DUMPREG(DISPC_VID_CONV_COEF(1, 3)); 2755
2464 DUMPREG(DISPC_VID_CONV_COEF(1, 4)); 2756 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2465 DUMPREG(DISPC_VID_FIR_COEF_V(1, 0)); 2757 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1));
2466 DUMPREG(DISPC_VID_FIR_COEF_V(1, 1)); 2758 DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO1));
2467 DUMPREG(DISPC_VID_FIR_COEF_V(1, 2)); 2759 DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO1));
2468 DUMPREG(DISPC_VID_FIR_COEF_V(1, 3)); 2760 DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO1));
2469 DUMPREG(DISPC_VID_FIR_COEF_V(1, 4)); 2761 DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO1));
2470 DUMPREG(DISPC_VID_FIR_COEF_V(1, 5)); 2762
2471 DUMPREG(DISPC_VID_FIR_COEF_V(1, 6)); 2763 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 0));
2472 DUMPREG(DISPC_VID_FIR_COEF_V(1, 7)); 2764 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 1));
2473 2765 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 2));
2474 DUMPREG(DISPC_VID_PRELOAD(0)); 2766 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 3));
2475 DUMPREG(DISPC_VID_PRELOAD(1)); 2767 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 4));
2476 2768 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 5));
2477 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 2769 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 6));
2770 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 7));
2771
2772 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 0));
2773 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 1));
2774 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 2));
2775 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 3));
2776 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 4));
2777 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 5));
2778 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 6));
2779 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 7));
2780
2781 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 0));
2782 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 1));
2783 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 2));
2784 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 3));
2785 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 4));
2786 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 5));
2787 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 6));
2788 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 7));
2789 }
2790 if (dss_has_feature(FEAT_ATTR2))
2791 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
2792
2793
2794 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 0));
2795 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 1));
2796 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 2));
2797 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 3));
2798 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 4));
2799 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 5));
2800 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 6));
2801 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 7));
2802 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 0));
2803 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 1));
2804 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 2));
2805 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 3));
2806 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 4));
2807 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 5));
2808 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 6));
2809 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 7));
2810 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0));
2811 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1));
2812 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2));
2813 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3));
2814 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4));
2815 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0));
2816 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1));
2817 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2));
2818 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3));
2819 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4));
2820 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5));
2821 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6));
2822 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7));
2823
2824 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2825 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2));
2826 DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO2));
2827 DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO2));
2828 DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO2));
2829 DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO2));
2830
2831 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 0));
2832 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 1));
2833 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 2));
2834 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 3));
2835 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 4));
2836 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 5));
2837 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 6));
2838 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 7));
2839
2840 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 0));
2841 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 1));
2842 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 2));
2843 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 3));
2844 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 4));
2845 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 5));
2846 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 6));
2847 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 7));
2848
2849 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 0));
2850 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 1));
2851 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 2));
2852 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 3));
2853 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 4));
2854 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 5));
2855 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 6));
2856 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 7));
2857 }
2858 if (dss_has_feature(FEAT_ATTR2))
2859 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
2860
2861 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1));
2862 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
2863
2864 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
2478#undef DUMPREG 2865#undef DUMPREG
2479} 2866}
2480 2867
2481static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc, 2868static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
2482 bool ihs, bool ivs, u8 acbi, u8 acb) 2869 bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi, u8 acb)
2483{ 2870{
2484 u32 l = 0; 2871 u32 l = 0;
2485 2872
@@ -2496,13 +2883,14 @@ static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc,
2496 l |= FLD_VAL(acb, 7, 0); 2883 l |= FLD_VAL(acb, 7, 0);
2497 2884
2498 enable_clocks(1); 2885 enable_clocks(1);
2499 dispc_write_reg(DISPC_POL_FREQ, l); 2886 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2500 enable_clocks(0); 2887 enable_clocks(0);
2501} 2888}
2502 2889
2503void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb) 2890void dispc_set_pol_freq(enum omap_channel channel,
2891 enum omap_panel_config config, u8 acbi, u8 acb)
2504{ 2892{
2505 _dispc_set_pol_freq((config & OMAP_DSS_LCD_ONOFF) != 0, 2893 _dispc_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
2506 (config & OMAP_DSS_LCD_RF) != 0, 2894 (config & OMAP_DSS_LCD_RF) != 0,
2507 (config & OMAP_DSS_LCD_IEO) != 0, 2895 (config & OMAP_DSS_LCD_IEO) != 0,
2508 (config & OMAP_DSS_LCD_IPC) != 0, 2896 (config & OMAP_DSS_LCD_IPC) != 0,
@@ -2571,24 +2959,26 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
2571 return 0; 2959 return 0;
2572} 2960}
2573 2961
2574int dispc_set_clock_div(struct dispc_clock_info *cinfo) 2962int dispc_set_clock_div(enum omap_channel channel,
2963 struct dispc_clock_info *cinfo)
2575{ 2964{
2576 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 2965 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
2577 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 2966 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
2578 2967
2579 dispc_set_lcd_divisor(cinfo->lck_div, cinfo->pck_div); 2968 dispc_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
2580 2969
2581 return 0; 2970 return 0;
2582} 2971}
2583 2972
2584int dispc_get_clock_div(struct dispc_clock_info *cinfo) 2973int dispc_get_clock_div(enum omap_channel channel,
2974 struct dispc_clock_info *cinfo)
2585{ 2975{
2586 unsigned long fck; 2976 unsigned long fck;
2587 2977
2588 fck = dispc_fclk_rate(); 2978 fck = dispc_fclk_rate();
2589 2979
2590 cinfo->lck_div = REG_GET(DISPC_DIVISOR, 23, 16); 2980 cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
2591 cinfo->pck_div = REG_GET(DISPC_DIVISOR, 7, 0); 2981 cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
2592 2982
2593 cinfo->lck = fck / cinfo->lck_div; 2983 cinfo->lck = fck / cinfo->lck_div;
2594 cinfo->pck = cinfo->lck / cinfo->pck_div; 2984 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2665,6 +3055,9 @@ int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
2665 break; 3055 break;
2666 } 3056 }
2667 3057
3058 if (ret)
3059 goto err;
3060
2668 _omap_dispc_set_irqs(); 3061 _omap_dispc_set_irqs();
2669 3062
2670 spin_unlock_irqrestore(&dispc.irq_lock, flags); 3063 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -2728,6 +3121,8 @@ static void print_irq_status(u32 status)
2728 PIS(VID2_FIFO_UNDERFLOW); 3121 PIS(VID2_FIFO_UNDERFLOW);
2729 PIS(SYNC_LOST); 3122 PIS(SYNC_LOST);
2730 PIS(SYNC_LOST_DIGIT); 3123 PIS(SYNC_LOST_DIGIT);
3124 if (dss_has_feature(FEAT_MGR_LCD2))
3125 PIS(SYNC_LOST2);
2731#undef PIS 3126#undef PIS
2732 3127
2733 printk("\n"); 3128 printk("\n");
@@ -2738,10 +3133,10 @@ static void print_irq_status(u32 status)
2738 * but we presume they are on because we got an IRQ. However, 3133 * but we presume they are on because we got an IRQ. However,
2739 * an irq handler may turn the clocks off, so we may not have 3134 * an irq handler may turn the clocks off, so we may not have
2740 * clock later in the function. */ 3135 * clock later in the function. */
2741void dispc_irq_handler(void) 3136static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
2742{ 3137{
2743 int i; 3138 int i;
2744 u32 irqstatus; 3139 u32 irqstatus, irqenable;
2745 u32 handledirqs = 0; 3140 u32 handledirqs = 0;
2746 u32 unhandled_errors; 3141 u32 unhandled_errors;
2747 struct omap_dispc_isr_data *isr_data; 3142 struct omap_dispc_isr_data *isr_data;
@@ -2750,6 +3145,13 @@ void dispc_irq_handler(void)
2750 spin_lock(&dispc.irq_lock); 3145 spin_lock(&dispc.irq_lock);
2751 3146
2752 irqstatus = dispc_read_reg(DISPC_IRQSTATUS); 3147 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
3148 irqenable = dispc_read_reg(DISPC_IRQENABLE);
3149
3150 /* IRQ is not for us */
3151 if (!(irqstatus & irqenable)) {
3152 spin_unlock(&dispc.irq_lock);
3153 return IRQ_NONE;
3154 }
2753 3155
2754#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 3156#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2755 spin_lock(&dispc.irq_stats_lock); 3157 spin_lock(&dispc.irq_stats_lock);
@@ -2801,6 +3203,8 @@ void dispc_irq_handler(void)
2801 } 3203 }
2802 3204
2803 spin_unlock(&dispc.irq_lock); 3205 spin_unlock(&dispc.irq_lock);
3206
3207 return IRQ_HANDLED;
2804} 3208}
2805 3209
2806static void dispc_error_worker(struct work_struct *work) 3210static void dispc_error_worker(struct work_struct *work)
@@ -2946,6 +3350,45 @@ static void dispc_error_worker(struct work_struct *work)
2946 } 3350 }
2947 } 3351 }
2948 3352
3353 if (errors & DISPC_IRQ_SYNC_LOST2) {
3354 struct omap_overlay_manager *manager = NULL;
3355 bool enable = false;
3356
3357 DSSERR("SYNC_LOST for LCD2, disabling LCD2\n");
3358
3359 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3360 struct omap_overlay_manager *mgr;
3361 mgr = omap_dss_get_overlay_manager(i);
3362
3363 if (mgr->id == OMAP_DSS_CHANNEL_LCD2) {
3364 manager = mgr;
3365 enable = mgr->device->state ==
3366 OMAP_DSS_DISPLAY_ACTIVE;
3367 mgr->device->driver->disable(mgr->device);
3368 break;
3369 }
3370 }
3371
3372 if (manager) {
3373 struct omap_dss_device *dssdev = manager->device;
3374 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3375 struct omap_overlay *ovl;
3376 ovl = omap_dss_get_overlay(i);
3377
3378 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3379 continue;
3380
3381 if (ovl->id != 0 && ovl->manager == manager)
3382 dispc_enable_plane(ovl->id, 0);
3383 }
3384
3385 dispc_go(manager->id);
3386 mdelay(50);
3387 if (enable)
3388 dssdev->driver->enable(dssdev);
3389 }
3390 }
3391
2949 if (errors & DISPC_IRQ_OCP_ERR) { 3392 if (errors & DISPC_IRQ_OCP_ERR) {
2950 DSSERR("OCP_ERR\n"); 3393 DSSERR("OCP_ERR\n");
2951 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3394 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
@@ -3053,6 +3496,8 @@ static void _omap_dispc_initialize_irq(void)
3053 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr)); 3496 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
3054 3497
3055 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3498 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3499 if (dss_has_feature(FEAT_MGR_LCD2))
3500 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3056 3501
3057 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, 3502 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
3058 * so clear it */ 3503 * so clear it */
@@ -3084,8 +3529,18 @@ static void _omap_dispc_initial_config(void)
3084 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ 3529 l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
3085 dispc_write_reg(DISPC_SYSCONFIG, l); 3530 dispc_write_reg(DISPC_SYSCONFIG, l);
3086 3531
3532 /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
3533 if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
3534 l = dispc_read_reg(DISPC_DIVISOR);
3535 /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
3536 l = FLD_MOD(l, 1, 0, 0);
3537 l = FLD_MOD(l, 1, 23, 16);
3538 dispc_write_reg(DISPC_DIVISOR, l);
3539 }
3540
3087 /* FUNCGATED */ 3541 /* FUNCGATED */
3088 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3542 if (dss_has_feature(FEAT_FUNCGATED))
3543 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
3089 3544
3090 /* L3 firewall setting: enable access to OCM RAM */ 3545 /* L3 firewall setting: enable access to OCM RAM */
3091 /* XXX this should be somewhere in plat-omap */ 3546 /* XXX this should be somewhere in plat-omap */
@@ -3099,47 +3554,6 @@ static void _omap_dispc_initial_config(void)
3099 dispc_read_plane_fifo_sizes(); 3554 dispc_read_plane_fifo_sizes();
3100} 3555}
3101 3556
3102int dispc_init(void)
3103{
3104 u32 rev;
3105
3106 spin_lock_init(&dispc.irq_lock);
3107
3108#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3109 spin_lock_init(&dispc.irq_stats_lock);
3110 dispc.irq_stats.last_reset = jiffies;
3111#endif
3112
3113 INIT_WORK(&dispc.error_work, dispc_error_worker);
3114
3115 dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
3116 if (!dispc.base) {
3117 DSSERR("can't ioremap DISPC\n");
3118 return -ENOMEM;
3119 }
3120
3121 enable_clocks(1);
3122
3123 _omap_dispc_initial_config();
3124
3125 _omap_dispc_initialize_irq();
3126
3127 dispc_save_context();
3128
3129 rev = dispc_read_reg(DISPC_REVISION);
3130 printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
3131 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3132
3133 enable_clocks(0);
3134
3135 return 0;
3136}
3137
3138void dispc_exit(void)
3139{
3140 iounmap(dispc.base);
3141}
3142
3143int dispc_enable_plane(enum omap_plane plane, bool enable) 3557int dispc_enable_plane(enum omap_plane plane, bool enable)
3144{ 3558{
3145 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 3559 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -3159,17 +3573,19 @@ int dispc_setup_plane(enum omap_plane plane,
3159 enum omap_color_mode color_mode, 3573 enum omap_color_mode color_mode,
3160 bool ilace, 3574 bool ilace,
3161 enum omap_dss_rotation_type rotation_type, 3575 enum omap_dss_rotation_type rotation_type,
3162 u8 rotation, bool mirror, u8 global_alpha) 3576 u8 rotation, bool mirror, u8 global_alpha,
3577 u8 pre_mult_alpha, enum omap_channel channel,
3578 u32 puv_addr)
3163{ 3579{
3164 int r = 0; 3580 int r = 0;
3165 3581
3166 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 3582 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d, %d, %dx%d -> "
3167 "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n", 3583 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
3168 plane, paddr, screen_width, pos_x, pos_y, 3584 plane, paddr, screen_width, pos_x, pos_y,
3169 width, height, 3585 width, height,
3170 out_width, out_height, 3586 out_width, out_height,
3171 ilace, color_mode, 3587 ilace, color_mode,
3172 rotation, mirror); 3588 rotation, mirror, channel);
3173 3589
3174 enable_clocks(1); 3590 enable_clocks(1);
3175 3591
@@ -3181,9 +3597,102 @@ int dispc_setup_plane(enum omap_plane plane,
3181 color_mode, ilace, 3597 color_mode, ilace,
3182 rotation_type, 3598 rotation_type,
3183 rotation, mirror, 3599 rotation, mirror,
3184 global_alpha); 3600 global_alpha,
3601 pre_mult_alpha,
3602 channel, puv_addr);
3185 3603
3186 enable_clocks(0); 3604 enable_clocks(0);
3187 3605
3188 return r; 3606 return r;
3189} 3607}
3608
3609/* DISPC HW IP initialisation */
3610static int omap_dispchw_probe(struct platform_device *pdev)
3611{
3612 u32 rev;
3613 int r = 0;
3614 struct resource *dispc_mem;
3615
3616 dispc.pdev = pdev;
3617
3618 spin_lock_init(&dispc.irq_lock);
3619
3620#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3621 spin_lock_init(&dispc.irq_stats_lock);
3622 dispc.irq_stats.last_reset = jiffies;
3623#endif
3624
3625 INIT_WORK(&dispc.error_work, dispc_error_worker);
3626
3627 dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
3628 if (!dispc_mem) {
3629 DSSERR("can't get IORESOURCE_MEM DISPC\n");
3630 r = -EINVAL;
3631 goto fail0;
3632 }
3633 dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
3634 if (!dispc.base) {
3635 DSSERR("can't ioremap DISPC\n");
3636 r = -ENOMEM;
3637 goto fail0;
3638 }
3639 dispc.irq = platform_get_irq(dispc.pdev, 0);
3640 if (dispc.irq < 0) {
3641 DSSERR("platform_get_irq failed\n");
3642 r = -ENODEV;
3643 goto fail1;
3644 }
3645
3646 r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED,
3647 "OMAP DISPC", dispc.pdev);
3648 if (r < 0) {
3649 DSSERR("request_irq failed\n");
3650 goto fail1;
3651 }
3652
3653 enable_clocks(1);
3654
3655 _omap_dispc_initial_config();
3656
3657 _omap_dispc_initialize_irq();
3658
3659 dispc_save_context();
3660
3661 rev = dispc_read_reg(DISPC_REVISION);
3662 dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
3663 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3664
3665 enable_clocks(0);
3666
3667 return 0;
3668fail1:
3669 iounmap(dispc.base);
3670fail0:
3671 return r;
3672}
3673
3674static int omap_dispchw_remove(struct platform_device *pdev)
3675{
3676 free_irq(dispc.irq, dispc.pdev);
3677 iounmap(dispc.base);
3678 return 0;
3679}
3680
3681static struct platform_driver omap_dispchw_driver = {
3682 .probe = omap_dispchw_probe,
3683 .remove = omap_dispchw_remove,
3684 .driver = {
3685 .name = "omapdss_dispc",
3686 .owner = THIS_MODULE,
3687 },
3688};
3689
3690int dispc_init_platform_driver(void)
3691{
3692 return platform_driver_register(&omap_dispchw_driver);
3693}
3694
3695void dispc_uninit_platform_driver(void)
3696{
3697 return platform_driver_unregister(&omap_dispchw_driver);
3698}
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
new file mode 100644
index 000000000000..6c9ee0a0efb3
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc.h
@@ -0,0 +1,691 @@
1/*
2 * linux/drivers/video/omap2/dss/dispc.h
3 *
4 * Copyright (C) 2011 Texas Instruments
5 * Author: Archit Taneja <archit@ti.com>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef __OMAP2_DISPC_REG_H
22#define __OMAP2_DISPC_REG_H
23
24/* DISPC common registers */
25#define DISPC_REVISION 0x0000
26#define DISPC_SYSCONFIG 0x0010
27#define DISPC_SYSSTATUS 0x0014
28#define DISPC_IRQSTATUS 0x0018
29#define DISPC_IRQENABLE 0x001C
30#define DISPC_CONTROL 0x0040
31#define DISPC_CONFIG 0x0044
32#define DISPC_CAPABLE 0x0048
33#define DISPC_LINE_STATUS 0x005C
34#define DISPC_LINE_NUMBER 0x0060
35#define DISPC_GLOBAL_ALPHA 0x0074
36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804
39
40/* DISPC overlay registers */
41#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
42 DISPC_BA0_OFFSET(n))
43#define DISPC_OVL_BA1(n) (DISPC_OVL_BASE(n) + \
44 DISPC_BA1_OFFSET(n))
45#define DISPC_OVL_BA0_UV(n) (DISPC_OVL_BASE(n) + \
46 DISPC_BA0_UV_OFFSET(n))
47#define DISPC_OVL_BA1_UV(n) (DISPC_OVL_BASE(n) + \
48 DISPC_BA1_UV_OFFSET(n))
49#define DISPC_OVL_POSITION(n) (DISPC_OVL_BASE(n) + \
50 DISPC_POS_OFFSET(n))
51#define DISPC_OVL_SIZE(n) (DISPC_OVL_BASE(n) + \
52 DISPC_SIZE_OFFSET(n))
53#define DISPC_OVL_ATTRIBUTES(n) (DISPC_OVL_BASE(n) + \
54 DISPC_ATTR_OFFSET(n))
55#define DISPC_OVL_ATTRIBUTES2(n) (DISPC_OVL_BASE(n) + \
56 DISPC_ATTR2_OFFSET(n))
57#define DISPC_OVL_FIFO_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
58 DISPC_FIFO_THRESH_OFFSET(n))
59#define DISPC_OVL_FIFO_SIZE_STATUS(n) (DISPC_OVL_BASE(n) + \
60 DISPC_FIFO_SIZE_STATUS_OFFSET(n))
61#define DISPC_OVL_ROW_INC(n) (DISPC_OVL_BASE(n) + \
62 DISPC_ROW_INC_OFFSET(n))
63#define DISPC_OVL_PIXEL_INC(n) (DISPC_OVL_BASE(n) + \
64 DISPC_PIX_INC_OFFSET(n))
65#define DISPC_OVL_WINDOW_SKIP(n) (DISPC_OVL_BASE(n) + \
66 DISPC_WINDOW_SKIP_OFFSET(n))
67#define DISPC_OVL_TABLE_BA(n) (DISPC_OVL_BASE(n) + \
68 DISPC_TABLE_BA_OFFSET(n))
69#define DISPC_OVL_FIR(n) (DISPC_OVL_BASE(n) + \
70 DISPC_FIR_OFFSET(n))
71#define DISPC_OVL_FIR2(n) (DISPC_OVL_BASE(n) + \
72 DISPC_FIR2_OFFSET(n))
73#define DISPC_OVL_PICTURE_SIZE(n) (DISPC_OVL_BASE(n) + \
74 DISPC_PIC_SIZE_OFFSET(n))
75#define DISPC_OVL_ACCU0(n) (DISPC_OVL_BASE(n) + \
76 DISPC_ACCU0_OFFSET(n))
77#define DISPC_OVL_ACCU1(n) (DISPC_OVL_BASE(n) + \
78 DISPC_ACCU1_OFFSET(n))
79#define DISPC_OVL_ACCU2_0(n) (DISPC_OVL_BASE(n) + \
80 DISPC_ACCU2_0_OFFSET(n))
81#define DISPC_OVL_ACCU2_1(n) (DISPC_OVL_BASE(n) + \
82 DISPC_ACCU2_1_OFFSET(n))
83#define DISPC_OVL_FIR_COEF_H(n, i) (DISPC_OVL_BASE(n) + \
84 DISPC_FIR_COEF_H_OFFSET(n, i))
85#define DISPC_OVL_FIR_COEF_HV(n, i) (DISPC_OVL_BASE(n) + \
86 DISPC_FIR_COEF_HV_OFFSET(n, i))
87#define DISPC_OVL_FIR_COEF_H2(n, i) (DISPC_OVL_BASE(n) + \
88 DISPC_FIR_COEF_H2_OFFSET(n, i))
89#define DISPC_OVL_FIR_COEF_HV2(n, i) (DISPC_OVL_BASE(n) + \
90 DISPC_FIR_COEF_HV2_OFFSET(n, i))
91#define DISPC_OVL_CONV_COEF(n, i) (DISPC_OVL_BASE(n) + \
92 DISPC_CONV_COEF_OFFSET(n, i))
93#define DISPC_OVL_FIR_COEF_V(n, i) (DISPC_OVL_BASE(n) + \
94 DISPC_FIR_COEF_V_OFFSET(n, i))
95#define DISPC_OVL_FIR_COEF_V2(n, i) (DISPC_OVL_BASE(n) + \
96 DISPC_FIR_COEF_V2_OFFSET(n, i))
97#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
98 DISPC_PRELOAD_OFFSET(n))
99
100/* DISPC manager/channel specific registers */
101static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
102{
103 switch (channel) {
104 case OMAP_DSS_CHANNEL_LCD:
105 return 0x004C;
106 case OMAP_DSS_CHANNEL_DIGIT:
107 return 0x0050;
108 case OMAP_DSS_CHANNEL_LCD2:
109 return 0x03AC;
110 default:
111 BUG();
112 }
113}
114
115static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel)
116{
117 switch (channel) {
118 case OMAP_DSS_CHANNEL_LCD:
119 return 0x0054;
120 case OMAP_DSS_CHANNEL_DIGIT:
121 return 0x0058;
122 case OMAP_DSS_CHANNEL_LCD2:
123 return 0x03B0;
124 default:
125 BUG();
126 }
127}
128
129static inline u16 DISPC_TIMING_H(enum omap_channel channel)
130{
131 switch (channel) {
132 case OMAP_DSS_CHANNEL_LCD:
133 return 0x0064;
134 case OMAP_DSS_CHANNEL_DIGIT:
135 BUG();
136 case OMAP_DSS_CHANNEL_LCD2:
137 return 0x0400;
138 default:
139 BUG();
140 }
141}
142
143static inline u16 DISPC_TIMING_V(enum omap_channel channel)
144{
145 switch (channel) {
146 case OMAP_DSS_CHANNEL_LCD:
147 return 0x0068;
148 case OMAP_DSS_CHANNEL_DIGIT:
149 BUG();
150 case OMAP_DSS_CHANNEL_LCD2:
151 return 0x0404;
152 default:
153 BUG();
154 }
155}
156
157static inline u16 DISPC_POL_FREQ(enum omap_channel channel)
158{
159 switch (channel) {
160 case OMAP_DSS_CHANNEL_LCD:
161 return 0x006C;
162 case OMAP_DSS_CHANNEL_DIGIT:
163 BUG();
164 case OMAP_DSS_CHANNEL_LCD2:
165 return 0x0408;
166 default:
167 BUG();
168 }
169}
170
171static inline u16 DISPC_DIVISORo(enum omap_channel channel)
172{
173 switch (channel) {
174 case OMAP_DSS_CHANNEL_LCD:
175 return 0x0070;
176 case OMAP_DSS_CHANNEL_DIGIT:
177 BUG();
178 case OMAP_DSS_CHANNEL_LCD2:
179 return 0x040C;
180 default:
181 BUG();
182 }
183}
184
185/* Named as DISPC_SIZE_LCD, DISPC_SIZE_DIGIT and DISPC_SIZE_LCD2 in TRM */
186static inline u16 DISPC_SIZE_MGR(enum omap_channel channel)
187{
188 switch (channel) {
189 case OMAP_DSS_CHANNEL_LCD:
190 return 0x007C;
191 case OMAP_DSS_CHANNEL_DIGIT:
192 return 0x0078;
193 case OMAP_DSS_CHANNEL_LCD2:
194 return 0x03CC;
195 default:
196 BUG();
197 }
198}
199
200static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel)
201{
202 switch (channel) {
203 case OMAP_DSS_CHANNEL_LCD:
204 return 0x01D4;
205 case OMAP_DSS_CHANNEL_DIGIT:
206 BUG();
207 case OMAP_DSS_CHANNEL_LCD2:
208 return 0x03C0;
209 default:
210 BUG();
211 }
212}
213
214static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel)
215{
216 switch (channel) {
217 case OMAP_DSS_CHANNEL_LCD:
218 return 0x01D8;
219 case OMAP_DSS_CHANNEL_DIGIT:
220 BUG();
221 case OMAP_DSS_CHANNEL_LCD2:
222 return 0x03C4;
223 default:
224 BUG();
225 }
226}
227
228static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel)
229{
230 switch (channel) {
231 case OMAP_DSS_CHANNEL_LCD:
232 return 0x01DC;
233 case OMAP_DSS_CHANNEL_DIGIT:
234 BUG();
235 case OMAP_DSS_CHANNEL_LCD2:
236 return 0x03C8;
237 default:
238 BUG();
239 }
240}
241
242static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel)
243{
244 switch (channel) {
245 case OMAP_DSS_CHANNEL_LCD:
246 return 0x0220;
247 case OMAP_DSS_CHANNEL_DIGIT:
248 BUG();
249 case OMAP_DSS_CHANNEL_LCD2:
250 return 0x03BC;
251 default:
252 BUG();
253 }
254}
255
256static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel)
257{
258 switch (channel) {
259 case OMAP_DSS_CHANNEL_LCD:
260 return 0x0224;
261 case OMAP_DSS_CHANNEL_DIGIT:
262 BUG();
263 case OMAP_DSS_CHANNEL_LCD2:
264 return 0x03B8;
265 default:
266 BUG();
267 }
268}
269
270static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel)
271{
272 switch (channel) {
273 case OMAP_DSS_CHANNEL_LCD:
274 return 0x0228;
275 case OMAP_DSS_CHANNEL_DIGIT:
276 BUG();
277 case OMAP_DSS_CHANNEL_LCD2:
278 return 0x03B4;
279 default:
280 BUG();
281 }
282}
283
284/* DISPC overlay register base addresses */
285static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
286{
287 switch (plane) {
288 case OMAP_DSS_GFX:
289 return 0x0080;
290 case OMAP_DSS_VIDEO1:
291 return 0x00BC;
292 case OMAP_DSS_VIDEO2:
293 return 0x014C;
294 default:
295 BUG();
296 }
297}
298
299/* DISPC overlay register offsets */
300static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
301{
302 switch (plane) {
303 case OMAP_DSS_GFX:
304 case OMAP_DSS_VIDEO1:
305 case OMAP_DSS_VIDEO2:
306 return 0x0000;
307 default:
308 BUG();
309 }
310}
311
312static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
313{
314 switch (plane) {
315 case OMAP_DSS_GFX:
316 case OMAP_DSS_VIDEO1:
317 case OMAP_DSS_VIDEO2:
318 return 0x0004;
319 default:
320 BUG();
321 }
322}
323
324static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
325{
326 switch (plane) {
327 case OMAP_DSS_GFX:
328 BUG();
329 case OMAP_DSS_VIDEO1:
330 return 0x0544;
331 case OMAP_DSS_VIDEO2:
332 return 0x04BC;
333 default:
334 BUG();
335 }
336}
337
338static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
339{
340 switch (plane) {
341 case OMAP_DSS_GFX:
342 BUG();
343 case OMAP_DSS_VIDEO1:
344 return 0x0548;
345 case OMAP_DSS_VIDEO2:
346 return 0x04C0;
347 default:
348 BUG();
349 }
350}
351
352static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
353{
354 switch (plane) {
355 case OMAP_DSS_GFX:
356 case OMAP_DSS_VIDEO1:
357 case OMAP_DSS_VIDEO2:
358 return 0x0008;
359 default:
360 BUG();
361 }
362}
363
364static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
365{
366 switch (plane) {
367 case OMAP_DSS_GFX:
368 case OMAP_DSS_VIDEO1:
369 case OMAP_DSS_VIDEO2:
370 return 0x000C;
371 default:
372 BUG();
373 }
374}
375
376static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
377{
378 switch (plane) {
379 case OMAP_DSS_GFX:
380 return 0x0020;
381 case OMAP_DSS_VIDEO1:
382 case OMAP_DSS_VIDEO2:
383 return 0x0010;
384 default:
385 BUG();
386 }
387}
388
389static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
390{
391 switch (plane) {
392 case OMAP_DSS_GFX:
393 BUG();
394 case OMAP_DSS_VIDEO1:
395 return 0x0568;
396 case OMAP_DSS_VIDEO2:
397 return 0x04DC;
398 default:
399 BUG();
400 }
401}
402
403static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
404{
405 switch (plane) {
406 case OMAP_DSS_GFX:
407 return 0x0024;
408 case OMAP_DSS_VIDEO1:
409 case OMAP_DSS_VIDEO2:
410 return 0x0014;
411 default:
412 BUG();
413 }
414}
415
416static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
417{
418 switch (plane) {
419 case OMAP_DSS_GFX:
420 return 0x0028;
421 case OMAP_DSS_VIDEO1:
422 case OMAP_DSS_VIDEO2:
423 return 0x0018;
424 default:
425 BUG();
426 }
427}
428
429static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
430{
431 switch (plane) {
432 case OMAP_DSS_GFX:
433 return 0x002C;
434 case OMAP_DSS_VIDEO1:
435 case OMAP_DSS_VIDEO2:
436 return 0x001C;
437 default:
438 BUG();
439 }
440}
441
442static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
443{
444 switch (plane) {
445 case OMAP_DSS_GFX:
446 return 0x0030;
447 case OMAP_DSS_VIDEO1:
448 case OMAP_DSS_VIDEO2:
449 return 0x0020;
450 default:
451 BUG();
452 }
453}
454
455static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
456{
457 switch (plane) {
458 case OMAP_DSS_GFX:
459 return 0x0034;
460 case OMAP_DSS_VIDEO1:
461 case OMAP_DSS_VIDEO2:
462 BUG();
463 default:
464 BUG();
465 }
466}
467
468static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
469{
470 switch (plane) {
471 case OMAP_DSS_GFX:
472 return 0x0038;
473 case OMAP_DSS_VIDEO1:
474 case OMAP_DSS_VIDEO2:
475 BUG();
476 default:
477 BUG();
478 }
479}
480
481static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
482{
483 switch (plane) {
484 case OMAP_DSS_GFX:
485 BUG();
486 case OMAP_DSS_VIDEO1:
487 case OMAP_DSS_VIDEO2:
488 return 0x0024;
489 default:
490 BUG();
491 }
492}
493
494static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
495{
496 switch (plane) {
497 case OMAP_DSS_GFX:
498 BUG();
499 case OMAP_DSS_VIDEO1:
500 return 0x0580;
501 case OMAP_DSS_VIDEO2:
502 return 0x055C;
503 default:
504 BUG();
505 }
506}
507
508static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
509{
510 switch (plane) {
511 case OMAP_DSS_GFX:
512 BUG();
513 case OMAP_DSS_VIDEO1:
514 case OMAP_DSS_VIDEO2:
515 return 0x0028;
516 default:
517 BUG();
518 }
519}
520
521
522static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
523{
524 switch (plane) {
525 case OMAP_DSS_GFX:
526 BUG();
527 case OMAP_DSS_VIDEO1:
528 case OMAP_DSS_VIDEO2:
529 return 0x002C;
530 default:
531 BUG();
532 }
533}
534
535static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
536{
537 switch (plane) {
538 case OMAP_DSS_GFX:
539 BUG();
540 case OMAP_DSS_VIDEO1:
541 return 0x0584;
542 case OMAP_DSS_VIDEO2:
543 return 0x0560;
544 default:
545 BUG();
546 }
547}
548
549static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
550{
551 switch (plane) {
552 case OMAP_DSS_GFX:
553 BUG();
554 case OMAP_DSS_VIDEO1:
555 case OMAP_DSS_VIDEO2:
556 return 0x0030;
557 default:
558 BUG();
559 }
560}
561
562static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
563{
564 switch (plane) {
565 case OMAP_DSS_GFX:
566 BUG();
567 case OMAP_DSS_VIDEO1:
568 return 0x0588;
569 case OMAP_DSS_VIDEO2:
570 return 0x0564;
571 default:
572 BUG();
573 }
574}
575
576/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
577static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
578{
579 switch (plane) {
580 case OMAP_DSS_GFX:
581 BUG();
582 case OMAP_DSS_VIDEO1:
583 case OMAP_DSS_VIDEO2:
584 return 0x0034 + i * 0x8;
585 default:
586 BUG();
587 }
588}
589
590/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
591static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
592{
593 switch (plane) {
594 case OMAP_DSS_GFX:
595 BUG();
596 case OMAP_DSS_VIDEO1:
597 return 0x058C + i * 0x8;
598 case OMAP_DSS_VIDEO2:
599 return 0x0568 + i * 0x8;
600 default:
601 BUG();
602 }
603}
604
605/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
606static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
607{
608 switch (plane) {
609 case OMAP_DSS_GFX:
610 BUG();
611 case OMAP_DSS_VIDEO1:
612 case OMAP_DSS_VIDEO2:
613 return 0x0038 + i * 0x8;
614 default:
615 BUG();
616 }
617}
618
619/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
620static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
621{
622 switch (plane) {
623 case OMAP_DSS_GFX:
624 BUG();
625 case OMAP_DSS_VIDEO1:
626 return 0x0590 + i * 8;
627 case OMAP_DSS_VIDEO2:
628 return 0x056C + i * 0x8;
629 default:
630 BUG();
631 }
632}
633
634/* coef index i = {0, 1, 2, 3, 4,} */
635static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
636{
637 switch (plane) {
638 case OMAP_DSS_GFX:
639 BUG();
640 case OMAP_DSS_VIDEO1:
641 case OMAP_DSS_VIDEO2:
642 return 0x0074 + i * 0x4;
643 default:
644 BUG();
645 }
646}
647
648/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
649static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
650{
651 switch (plane) {
652 case OMAP_DSS_GFX:
653 BUG();
654 case OMAP_DSS_VIDEO1:
655 return 0x0124 + i * 0x4;
656 case OMAP_DSS_VIDEO2:
657 return 0x00B4 + i * 0x4;
658 default:
659 BUG();
660 }
661}
662
663/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
664static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
665{
666 switch (plane) {
667 case OMAP_DSS_GFX:
668 BUG();
669 case OMAP_DSS_VIDEO1:
670 return 0x05CC + i * 0x4;
671 case OMAP_DSS_VIDEO2:
672 return 0x05A8 + i * 0x4;
673 default:
674 BUG();
675 }
676}
677
678static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
679{
680 switch (plane) {
681 case OMAP_DSS_GFX:
682 return 0x01AC;
683 case OMAP_DSS_VIDEO1:
684 return 0x0174;
685 case OMAP_DSS_VIDEO2:
686 return 0x00E8;
687 default:
688 BUG();
689 }
690}
691#endif
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 22dd7a474f79..c2dfc8c50057 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -25,14 +25,11 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/list.h>
29#include <linux/platform_device.h> 28#include <linux/platform_device.h>
30 29
31#include <plat/display.h> 30#include <video/omapdss.h>
32#include "dss.h" 31#include "dss.h"
33 32
34static LIST_HEAD(display_list);
35
36static ssize_t display_enabled_show(struct device *dev, 33static ssize_t display_enabled_show(struct device *dev,
37 struct device_attribute *attr, char *buf) 34 struct device_attribute *attr, char *buf)
38{ 35{
@@ -47,9 +44,13 @@ static ssize_t display_enabled_store(struct device *dev,
47 const char *buf, size_t size) 44 const char *buf, size_t size)
48{ 45{
49 struct omap_dss_device *dssdev = to_dss_device(dev); 46 struct omap_dss_device *dssdev = to_dss_device(dev);
50 bool enabled, r; 47 int r, enabled;
48
49 r = kstrtoint(buf, 0, &enabled);
50 if (r)
51 return r;
51 52
52 enabled = simple_strtoul(buf, NULL, 10); 53 enabled = !!enabled;
53 54
54 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 55 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
55 if (enabled) { 56 if (enabled) {
@@ -85,7 +86,9 @@ static ssize_t display_upd_mode_store(struct device *dev,
85 if (!dssdev->driver->set_update_mode) 86 if (!dssdev->driver->set_update_mode)
86 return -EINVAL; 87 return -EINVAL;
87 88
88 val = simple_strtoul(buf, NULL, 10); 89 r = kstrtoint(buf, 0, &val);
90 if (r)
91 return r;
89 92
90 switch (val) { 93 switch (val) {
91 case OMAP_DSS_UPDATE_DISABLED: 94 case OMAP_DSS_UPDATE_DISABLED:
@@ -117,13 +120,16 @@ static ssize_t display_tear_store(struct device *dev,
117 struct device_attribute *attr, const char *buf, size_t size) 120 struct device_attribute *attr, const char *buf, size_t size)
118{ 121{
119 struct omap_dss_device *dssdev = to_dss_device(dev); 122 struct omap_dss_device *dssdev = to_dss_device(dev);
120 unsigned long te; 123 int te, r;
121 int r;
122 124
123 if (!dssdev->driver->enable_te || !dssdev->driver->get_te) 125 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
124 return -ENOENT; 126 return -ENOENT;
125 127
126 te = simple_strtoul(buf, NULL, 0); 128 r = kstrtoint(buf, 0, &te);
129 if (r)
130 return r;
131
132 te = !!te;
127 133
128 r = dssdev->driver->enable_te(dssdev, te); 134 r = dssdev->driver->enable_te(dssdev, te);
129 if (r) 135 if (r)
@@ -199,13 +205,14 @@ static ssize_t display_rotate_store(struct device *dev,
199 struct device_attribute *attr, const char *buf, size_t size) 205 struct device_attribute *attr, const char *buf, size_t size)
200{ 206{
201 struct omap_dss_device *dssdev = to_dss_device(dev); 207 struct omap_dss_device *dssdev = to_dss_device(dev);
202 unsigned long rot; 208 int rot, r;
203 int r;
204 209
205 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) 210 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
206 return -ENOENT; 211 return -ENOENT;
207 212
208 rot = simple_strtoul(buf, NULL, 0); 213 r = kstrtoint(buf, 0, &rot);
214 if (r)
215 return r;
209 216
210 r = dssdev->driver->set_rotate(dssdev, rot); 217 r = dssdev->driver->set_rotate(dssdev, rot);
211 if (r) 218 if (r)
@@ -229,13 +236,16 @@ static ssize_t display_mirror_store(struct device *dev,
229 struct device_attribute *attr, const char *buf, size_t size) 236 struct device_attribute *attr, const char *buf, size_t size)
230{ 237{
231 struct omap_dss_device *dssdev = to_dss_device(dev); 238 struct omap_dss_device *dssdev = to_dss_device(dev);
232 unsigned long mirror; 239 int mirror, r;
233 int r;
234 240
235 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) 241 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
236 return -ENOENT; 242 return -ENOENT;
237 243
238 mirror = simple_strtoul(buf, NULL, 0); 244 r = kstrtoint(buf, 0, &mirror);
245 if (r)
246 return r;
247
248 mirror = !!mirror;
239 249
240 r = dssdev->driver->set_mirror(dssdev, mirror); 250 r = dssdev->driver->set_mirror(dssdev, mirror);
241 if (r) 251 if (r)
@@ -262,14 +272,15 @@ static ssize_t display_wss_store(struct device *dev,
262 struct device_attribute *attr, const char *buf, size_t size) 272 struct device_attribute *attr, const char *buf, size_t size)
263{ 273{
264 struct omap_dss_device *dssdev = to_dss_device(dev); 274 struct omap_dss_device *dssdev = to_dss_device(dev);
265 unsigned long wss; 275 u32 wss;
266 int r; 276 int r;
267 277
268 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss) 278 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
269 return -ENOENT; 279 return -ENOENT;
270 280
271 if (strict_strtoul(buf, 0, &wss)) 281 r = kstrtou32(buf, 0, &wss);
272 return -EINVAL; 282 if (r)
283 return r;
273 284
274 if (wss > 0xfffff) 285 if (wss > 0xfffff)
275 return -EINVAL; 286 return -EINVAL;
@@ -345,6 +356,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
345 return 16; 356 return 16;
346 case OMAP_DISPLAY_TYPE_VENC: 357 case OMAP_DISPLAY_TYPE_VENC:
347 case OMAP_DISPLAY_TYPE_SDI: 358 case OMAP_DISPLAY_TYPE_SDI:
359 case OMAP_DISPLAY_TYPE_HDMI:
348 return 24; 360 return 24;
349 default: 361 default:
350 BUG(); 362 BUG();
@@ -371,6 +383,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
371 case OMAP_DISPLAY_TYPE_DPI: 383 case OMAP_DISPLAY_TYPE_DPI:
372 bpp = dssdev->phy.dpi.data_lines; 384 bpp = dssdev->phy.dpi.data_lines;
373 break; 385 break;
386 case OMAP_DISPLAY_TYPE_HDMI:
374 case OMAP_DISPLAY_TYPE_VENC: 387 case OMAP_DISPLAY_TYPE_VENC:
375 case OMAP_DISPLAY_TYPE_SDI: 388 case OMAP_DISPLAY_TYPE_SDI:
376 bpp = 24; 389 bpp = 24;
@@ -396,29 +409,6 @@ void dss_init_device(struct platform_device *pdev,
396 switch (dssdev->type) { 409 switch (dssdev->type) {
397#ifdef CONFIG_OMAP2_DSS_DPI 410#ifdef CONFIG_OMAP2_DSS_DPI
398 case OMAP_DISPLAY_TYPE_DPI: 411 case OMAP_DISPLAY_TYPE_DPI:
399#endif
400#ifdef CONFIG_OMAP2_DSS_RFBI
401 case OMAP_DISPLAY_TYPE_DBI:
402#endif
403#ifdef CONFIG_OMAP2_DSS_SDI
404 case OMAP_DISPLAY_TYPE_SDI:
405#endif
406#ifdef CONFIG_OMAP2_DSS_DSI
407 case OMAP_DISPLAY_TYPE_DSI:
408#endif
409#ifdef CONFIG_OMAP2_DSS_VENC
410 case OMAP_DISPLAY_TYPE_VENC:
411#endif
412 break;
413 default:
414 DSSERR("Support for display '%s' not compiled in.\n",
415 dssdev->name);
416 return;
417 }
418
419 switch (dssdev->type) {
420#ifdef CONFIG_OMAP2_DSS_DPI
421 case OMAP_DISPLAY_TYPE_DPI:
422 r = dpi_init_display(dssdev); 412 r = dpi_init_display(dssdev);
423 break; 413 break;
424#endif 414#endif
@@ -442,8 +432,13 @@ void dss_init_device(struct platform_device *pdev,
442 r = dsi_init_display(dssdev); 432 r = dsi_init_display(dssdev);
443 break; 433 break;
444#endif 434#endif
435 case OMAP_DISPLAY_TYPE_HDMI:
436 r = hdmi_init_display(dssdev);
437 break;
445 default: 438 default:
446 BUG(); 439 DSSERR("Support for display '%s' not compiled in.\n",
440 dssdev->name);
441 return;
447 } 442 }
448 443
449 if (r) { 444 if (r) {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 960e977a8bf0..ff6bd30132df 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -30,47 +30,73 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32 32
33#include <plat/display.h> 33#include <video/omapdss.h>
34#include <plat/cpu.h> 34#include <plat/cpu.h>
35 35
36#include "dss.h" 36#include "dss.h"
37 37
38static struct { 38static struct {
39 struct regulator *vdds_dsi_reg; 39 struct regulator *vdds_dsi_reg;
40 struct platform_device *dsidev;
40} dpi; 41} dpi;
41 42
42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 43static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
43static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, 44{
44 unsigned long *fck, int *lck_div, int *pck_div) 45 int dsi_module;
46
47 dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
48
49 return dsi_get_dsidev_from_id(dsi_module);
50}
51
52static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
53{
54 if (dssdev->clocks.dispc.dispc_fclk_src ==
55 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
56 dssdev->clocks.dispc.dispc_fclk_src ==
57 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
58 dssdev->clocks.dispc.channel.lcd_clk_src ==
59 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
60 dssdev->clocks.dispc.channel.lcd_clk_src ==
61 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
62 return true;
63 else
64 return false;
65}
66
67static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
68 unsigned long pck_req, unsigned long *fck, int *lck_div,
69 int *pck_div)
45{ 70{
46 struct dsi_clock_info dsi_cinfo; 71 struct dsi_clock_info dsi_cinfo;
47 struct dispc_clock_info dispc_cinfo; 72 struct dispc_clock_info dispc_cinfo;
48 int r; 73 int r;
49 74
50 r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo, 75 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req,
51 &dispc_cinfo); 76 &dsi_cinfo, &dispc_cinfo);
52 if (r) 77 if (r)
53 return r; 78 return r;
54 79
55 r = dsi_pll_set_clock_div(&dsi_cinfo); 80 r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
56 if (r) 81 if (r)
57 return r; 82 return r;
58 83
59 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 84 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
60 85
61 r = dispc_set_clock_div(&dispc_cinfo); 86 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
62 if (r) 87 if (r)
63 return r; 88 return r;
64 89
65 *fck = dsi_cinfo.dsi1_pll_fclk; 90 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
66 *lck_div = dispc_cinfo.lck_div; 91 *lck_div = dispc_cinfo.lck_div;
67 *pck_div = dispc_cinfo.pck_div; 92 *pck_div = dispc_cinfo.pck_div;
68 93
69 return 0; 94 return 0;
70} 95}
71#else 96
72static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req, 97static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
73 unsigned long *fck, int *lck_div, int *pck_div) 98 unsigned long pck_req, unsigned long *fck, int *lck_div,
99 int *pck_div)
74{ 100{
75 struct dss_clock_info dss_cinfo; 101 struct dss_clock_info dss_cinfo;
76 struct dispc_clock_info dispc_cinfo; 102 struct dispc_clock_info dispc_cinfo;
@@ -84,7 +110,7 @@ static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
84 if (r) 110 if (r)
85 return r; 111 return r;
86 112
87 r = dispc_set_clock_div(&dispc_cinfo); 113 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
88 if (r) 114 if (r)
89 return r; 115 return r;
90 116
@@ -94,31 +120,29 @@ static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
94 120
95 return 0; 121 return 0;
96} 122}
97#endif
98 123
99static int dpi_set_mode(struct omap_dss_device *dssdev) 124static int dpi_set_mode(struct omap_dss_device *dssdev)
100{ 125{
101 struct omap_video_timings *t = &dssdev->panel.timings; 126 struct omap_video_timings *t = &dssdev->panel.timings;
102 int lck_div, pck_div; 127 int lck_div = 0, pck_div = 0;
103 unsigned long fck; 128 unsigned long fck = 0;
104 unsigned long pck; 129 unsigned long pck;
105 bool is_tft; 130 bool is_tft;
106 int r = 0; 131 int r = 0;
107 132
108 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 133 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
109 134
110 dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, 135 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
111 dssdev->panel.acb); 136 dssdev->panel.acbi, dssdev->panel.acb);
112 137
113 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 138 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
114 139
115#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 140 if (dpi_use_dsi_pll(dssdev))
116 r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000, 141 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000,
117 &fck, &lck_div, &pck_div); 142 &fck, &lck_div, &pck_div);
118#else 143 else
119 r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000, 144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
120 &fck, &lck_div, &pck_div); 145 &fck, &lck_div, &pck_div);
121#endif
122 if (r) 146 if (r)
123 goto err0; 147 goto err0;
124 148
@@ -132,10 +156,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
132 t->pixel_clock = pck; 156 t->pixel_clock = pck;
133 } 157 }
134 158
135 dispc_set_lcd_timings(t); 159 dispc_set_lcd_timings(dssdev->manager->id, t);
136 160
137err0: 161err0:
138 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 162 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
139 return r; 163 return r;
140} 164}
141 165
@@ -145,10 +169,12 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
145 169
146 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 170 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
147 171
148 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); 172 dispc_set_parallel_interface_mode(dssdev->manager->id,
149 dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT : 173 OMAP_DSS_PARALLELMODE_BYPASS);
150 OMAP_DSS_LCD_DISPLAY_STN); 174 dispc_set_lcd_display_type(dssdev->manager->id, is_tft ?
151 dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines); 175 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
176 dispc_set_tft_data_lines(dssdev->manager->id,
177 dssdev->phy.dpi.data_lines);
152 178
153 return 0; 179 return 0;
154} 180}
@@ -169,18 +195,19 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
169 goto err1; 195 goto err1;
170 } 196 }
171 197
172 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 198 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
173 199
174 r = dpi_basic_init(dssdev); 200 r = dpi_basic_init(dssdev);
175 if (r) 201 if (r)
176 goto err2; 202 goto err2;
177 203
178#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 204 if (dpi_use_dsi_pll(dssdev)) {
179 dss_clk_enable(DSS_CLK_FCK2); 205 dss_clk_enable(DSS_CLK_SYSCK);
180 r = dsi_pll_init(dssdev, 0, 1); 206 r = dsi_pll_init(dpi.dsidev, 0, 1);
181 if (r) 207 if (r)
182 goto err3; 208 goto err3;
183#endif 209 }
210
184 r = dpi_set_mode(dssdev); 211 r = dpi_set_mode(dssdev);
185 if (r) 212 if (r)
186 goto err4; 213 goto err4;
@@ -192,13 +219,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
192 return 0; 219 return 0;
193 220
194err4: 221err4:
195#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 222 if (dpi_use_dsi_pll(dssdev))
196 dsi_pll_uninit(); 223 dsi_pll_uninit(dpi.dsidev, true);
197err3: 224err3:
198 dss_clk_disable(DSS_CLK_FCK2); 225 if (dpi_use_dsi_pll(dssdev))
199#endif 226 dss_clk_disable(DSS_CLK_SYSCK);
200err2: 227err2:
201 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 228 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
202 if (cpu_is_omap34xx()) 229 if (cpu_is_omap34xx())
203 regulator_disable(dpi.vdds_dsi_reg); 230 regulator_disable(dpi.vdds_dsi_reg);
204err1: 231err1:
@@ -212,13 +239,13 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
212{ 239{
213 dssdev->manager->disable(dssdev->manager); 240 dssdev->manager->disable(dssdev->manager);
214 241
215#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 242 if (dpi_use_dsi_pll(dssdev)) {
216 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 243 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
217 dsi_pll_uninit(); 244 dsi_pll_uninit(dpi.dsidev, true);
218 dss_clk_disable(DSS_CLK_FCK2); 245 dss_clk_disable(DSS_CLK_SYSCK);
219#endif 246 }
220 247
221 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 248 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
222 249
223 if (cpu_is_omap34xx()) 250 if (cpu_is_omap34xx())
224 regulator_disable(dpi.vdds_dsi_reg); 251 regulator_disable(dpi.vdds_dsi_reg);
@@ -234,7 +261,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
234 dssdev->panel.timings = *timings; 261 dssdev->panel.timings = *timings;
235 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 262 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
236 dpi_set_mode(dssdev); 263 dpi_set_mode(dssdev);
237 dispc_go(OMAP_DSS_CHANNEL_LCD); 264 dispc_go(dssdev->manager->id);
238 } 265 }
239} 266}
240EXPORT_SYMBOL(dpi_set_timings); 267EXPORT_SYMBOL(dpi_set_timings);
@@ -247,6 +274,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
247 int lck_div, pck_div; 274 int lck_div, pck_div;
248 unsigned long fck; 275 unsigned long fck;
249 unsigned long pck; 276 unsigned long pck;
277 struct dispc_clock_info dispc_cinfo;
250 278
251 if (!dispc_lcd_timings_ok(timings)) 279 if (!dispc_lcd_timings_ok(timings))
252 return -EINVAL; 280 return -EINVAL;
@@ -256,25 +284,18 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
256 284
257 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 285 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
258 286
259#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 287 if (dpi_use_dsi_pll(dssdev)) {
260 {
261 struct dsi_clock_info dsi_cinfo; 288 struct dsi_clock_info dsi_cinfo;
262 struct dispc_clock_info dispc_cinfo; 289 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft,
263 r = dsi_pll_calc_clock_div_pck(is_tft,
264 timings->pixel_clock * 1000, 290 timings->pixel_clock * 1000,
265 &dsi_cinfo, &dispc_cinfo); 291 &dsi_cinfo, &dispc_cinfo);
266 292
267 if (r) 293 if (r)
268 return r; 294 return r;
269 295
270 fck = dsi_cinfo.dsi1_pll_fclk; 296 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
271 lck_div = dispc_cinfo.lck_div; 297 } else {
272 pck_div = dispc_cinfo.pck_div;
273 }
274#else
275 {
276 struct dss_clock_info dss_cinfo; 298 struct dss_clock_info dss_cinfo;
277 struct dispc_clock_info dispc_cinfo;
278 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000, 299 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000,
279 &dss_cinfo, &dispc_cinfo); 300 &dss_cinfo, &dispc_cinfo);
280 301
@@ -282,10 +303,10 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
282 return r; 303 return r;
283 304
284 fck = dss_cinfo.fck; 305 fck = dss_cinfo.fck;
285 lck_div = dispc_cinfo.lck_div;
286 pck_div = dispc_cinfo.pck_div;
287 } 306 }
288#endif 307
308 lck_div = dispc_cinfo.lck_div;
309 pck_div = dispc_cinfo.pck_div;
289 310
290 pck = fck / lck_div / pck_div / 1000; 311 pck = fck / lck_div / pck_div / 1000;
291 312
@@ -299,22 +320,33 @@ int dpi_init_display(struct omap_dss_device *dssdev)
299{ 320{
300 DSSDBG("init_display\n"); 321 DSSDBG("init_display\n");
301 322
302 return 0; 323 if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
303} 324 struct regulator *vdds_dsi;
304 325
305int dpi_init(struct platform_device *pdev) 326 vdds_dsi = dss_get_vdds_dsi();
306{ 327
307 if (cpu_is_omap34xx()) { 328 if (IS_ERR(vdds_dsi)) {
308 dpi.vdds_dsi_reg = dss_get_vdds_dsi();
309 if (IS_ERR(dpi.vdds_dsi_reg)) {
310 DSSERR("can't get VDDS_DSI regulator\n"); 329 DSSERR("can't get VDDS_DSI regulator\n");
311 return PTR_ERR(dpi.vdds_dsi_reg); 330 return PTR_ERR(vdds_dsi);
312 } 331 }
332
333 dpi.vdds_dsi_reg = vdds_dsi;
334 }
335
336 if (dpi_use_dsi_pll(dssdev)) {
337 enum omap_dss_clk_source dispc_fclk_src =
338 dssdev->clocks.dispc.dispc_fclk_src;
339 dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
313 } 340 }
314 341
315 return 0; 342 return 0;
316} 343}
317 344
345int dpi_init(void)
346{
347 return 0;
348}
349
318void dpi_exit(void) 350void dpi_exit(void)
319{ 351{
320} 352}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index b3fa3a7db911..345757cfcbee 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -33,17 +33,19 @@
33#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <linux/sched.h>
37#include <linux/slab.h>
38#include <linux/debugfs.h>
36 39
37#include <plat/display.h> 40#include <video/omapdss.h>
38#include <plat/clock.h> 41#include <plat/clock.h>
39 42
40#include "dss.h" 43#include "dss.h"
44#include "dss_features.h"
41 45
42/*#define VERBOSE_IRQ*/ 46/*#define VERBOSE_IRQ*/
43#define DSI_CATCH_MISSING_TE 47#define DSI_CATCH_MISSING_TE
44 48
45#define DSI_BASE 0x4804FC00
46
47struct dsi_reg { u16 idx; }; 49struct dsi_reg { u16 idx; };
48 50
49#define DSI_REG(idx) ((const struct dsi_reg) { idx }) 51#define DSI_REG(idx) ((const struct dsi_reg) { idx })
@@ -57,6 +59,7 @@ struct dsi_reg { u16 idx; };
57#define DSI_IRQSTATUS DSI_REG(0x0018) 59#define DSI_IRQSTATUS DSI_REG(0x0018)
58#define DSI_IRQENABLE DSI_REG(0x001C) 60#define DSI_IRQENABLE DSI_REG(0x001C)
59#define DSI_CTRL DSI_REG(0x0040) 61#define DSI_CTRL DSI_REG(0x0040)
62#define DSI_GNQ DSI_REG(0x0044)
60#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048) 63#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
61#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C) 64#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
62#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050) 65#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
@@ -91,6 +94,7 @@ struct dsi_reg { u16 idx; };
91#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) 94#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004)
92#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) 95#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008)
93#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) 96#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014)
97#define DSI_DSIPHY_CFG10 DSI_REG(0x200 + 0x0028)
94 98
95/* DSI_PLL_CTRL_SCP */ 99/* DSI_PLL_CTRL_SCP */
96 100
@@ -100,11 +104,11 @@ struct dsi_reg { u16 idx; };
100#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C) 104#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C)
101#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010) 105#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010)
102 106
103#define REG_GET(idx, start, end) \ 107#define REG_GET(dsidev, idx, start, end) \
104 FLD_GET(dsi_read_reg(idx), start, end) 108 FLD_GET(dsi_read_reg(dsidev, idx), start, end)
105 109
106#define REG_FLD_MOD(idx, val, start, end) \ 110#define REG_FLD_MOD(dsidev, idx, val, start, end) \
107 dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end)) 111 dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, start, end))
108 112
109/* Global interrupts */ 113/* Global interrupts */
110#define DSI_IRQ_VC0 (1 << 0) 114#define DSI_IRQ_VC0 (1 << 0)
@@ -148,31 +152,50 @@ struct dsi_reg { u16 idx; };
148#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0) 152#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0)
149#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1) 153#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1)
150#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2) 154#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2)
155#define DSI_CIO_IRQ_ERRSYNCESC4 (1 << 3)
156#define DSI_CIO_IRQ_ERRSYNCESC5 (1 << 4)
151#define DSI_CIO_IRQ_ERRESC1 (1 << 5) 157#define DSI_CIO_IRQ_ERRESC1 (1 << 5)
152#define DSI_CIO_IRQ_ERRESC2 (1 << 6) 158#define DSI_CIO_IRQ_ERRESC2 (1 << 6)
153#define DSI_CIO_IRQ_ERRESC3 (1 << 7) 159#define DSI_CIO_IRQ_ERRESC3 (1 << 7)
160#define DSI_CIO_IRQ_ERRESC4 (1 << 8)
161#define DSI_CIO_IRQ_ERRESC5 (1 << 9)
154#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10) 162#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10)
155#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11) 163#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11)
156#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12) 164#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12)
165#define DSI_CIO_IRQ_ERRCONTROL4 (1 << 13)
166#define DSI_CIO_IRQ_ERRCONTROL5 (1 << 14)
157#define DSI_CIO_IRQ_STATEULPS1 (1 << 15) 167#define DSI_CIO_IRQ_STATEULPS1 (1 << 15)
158#define DSI_CIO_IRQ_STATEULPS2 (1 << 16) 168#define DSI_CIO_IRQ_STATEULPS2 (1 << 16)
159#define DSI_CIO_IRQ_STATEULPS3 (1 << 17) 169#define DSI_CIO_IRQ_STATEULPS3 (1 << 17)
170#define DSI_CIO_IRQ_STATEULPS4 (1 << 18)
171#define DSI_CIO_IRQ_STATEULPS5 (1 << 19)
160#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20) 172#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20)
161#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21) 173#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21)
162#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22) 174#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22)
163#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23) 175#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23)
164#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24) 176#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24)
165#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) 177#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25)
178#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4 (1 << 26)
179#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4 (1 << 27)
180#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5 (1 << 28)
181#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5 (1 << 29)
166#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) 182#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30)
167#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) 183#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31)
168#define DSI_CIO_IRQ_ERROR_MASK \ 184#define DSI_CIO_IRQ_ERROR_MASK \
169 (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \ 185 (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
170 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \ 186 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
171 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRCONTROL1 | \ 187 DSI_CIO_IRQ_ERRSYNCESC5 | \
172 DSI_CIO_IRQ_ERRCONTROL2 | DSI_CIO_IRQ_ERRCONTROL3 | \ 188 DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
189 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
190 DSI_CIO_IRQ_ERRESC5 | \
191 DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
192 DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
193 DSI_CIO_IRQ_ERRCONTROL5 | \
173 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \ 194 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
174 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \ 195 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
175 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3) 196 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
197 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
198 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
176 199
177#define DSI_DT_DCS_SHORT_WRITE_0 0x05 200#define DSI_DT_DCS_SHORT_WRITE_0 0x05
178#define DSI_DT_DCS_SHORT_WRITE_1 0x15 201#define DSI_DT_DCS_SHORT_WRITE_1 0x15
@@ -186,13 +209,15 @@ struct dsi_reg { u16 idx; };
186#define DSI_DT_RX_SHORT_READ_1 0x21 209#define DSI_DT_RX_SHORT_READ_1 0x21
187#define DSI_DT_RX_SHORT_READ_2 0x22 210#define DSI_DT_RX_SHORT_READ_2 0x22
188 211
189#define FINT_MAX 2100000 212typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
190#define FINT_MIN 750000 213
191#define REGN_MAX (1 << 7) 214#define DSI_MAX_NR_ISRS 2
192#define REGM_MAX ((1 << 11) - 1) 215
193#define REGM3_MAX (1 << 4) 216struct dsi_isr_data {
194#define REGM4_MAX (1 << 4) 217 omap_dsi_isr_t isr;
195#define LP_DIV_MAX ((1 << 13) - 1) 218 void *arg;
219 u32 mask;
220};
196 221
197enum fifo_size { 222enum fifo_size {
198 DSI_FIFO_SIZE_0 = 0, 223 DSI_FIFO_SIZE_0 = 0,
@@ -207,6 +232,19 @@ enum dsi_vc_mode {
207 DSI_VC_MODE_VP, 232 DSI_VC_MODE_VP,
208}; 233};
209 234
235enum dsi_lane {
236 DSI_CLK_P = 1 << 0,
237 DSI_CLK_N = 1 << 1,
238 DSI_DATA1_P = 1 << 2,
239 DSI_DATA1_N = 1 << 3,
240 DSI_DATA2_P = 1 << 4,
241 DSI_DATA2_N = 1 << 5,
242 DSI_DATA3_P = 1 << 6,
243 DSI_DATA3_N = 1 << 7,
244 DSI_DATA4_P = 1 << 8,
245 DSI_DATA4_N = 1 << 9,
246};
247
210struct dsi_update_region { 248struct dsi_update_region {
211 u16 x, y, w, h; 249 u16 x, y, w, h;
212 struct omap_dss_device *device; 250 struct omap_dss_device *device;
@@ -220,18 +258,29 @@ struct dsi_irq_stats {
220 unsigned cio_irqs[32]; 258 unsigned cio_irqs[32];
221}; 259};
222 260
223static struct 261struct dsi_isr_tables {
224{ 262 struct dsi_isr_data isr_table[DSI_MAX_NR_ISRS];
263 struct dsi_isr_data isr_table_vc[4][DSI_MAX_NR_ISRS];
264 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
265};
266
267struct dsi_data {
268 struct platform_device *pdev;
225 void __iomem *base; 269 void __iomem *base;
270 int irq;
271
272 void (*dsi_mux_pads)(bool enable);
226 273
227 struct dsi_clock_info current_cinfo; 274 struct dsi_clock_info current_cinfo;
228 275
276 bool vdds_dsi_enabled;
229 struct regulator *vdds_dsi_reg; 277 struct regulator *vdds_dsi_reg;
230 278
231 struct { 279 struct {
232 enum dsi_vc_mode mode; 280 enum dsi_vc_mode mode;
233 struct omap_dss_device *dssdev; 281 struct omap_dss_device *dssdev;
234 enum fifo_size fifo_size; 282 enum fifo_size fifo_size;
283 int vc_id;
235 } vc[4]; 284 } vc[4];
236 285
237 struct mutex lock; 286 struct mutex lock;
@@ -239,15 +288,16 @@ static struct
239 288
240 unsigned pll_locked; 289 unsigned pll_locked;
241 290
242 struct completion bta_completion; 291 spinlock_t irq_lock;
243 void (*bta_callback)(void); 292 struct dsi_isr_tables isr_tables;
293 /* space for a copy used by the interrupt handler */
294 struct dsi_isr_tables isr_tables_copy;
244 295
245 int update_channel; 296 int update_channel;
246 struct dsi_update_region update_region; 297 struct dsi_update_region update_region;
247 298
248 bool te_enabled; 299 bool te_enabled;
249 300 bool ulps_enabled;
250 struct workqueue_struct *workqueue;
251 301
252 void (*framedone_callback)(int, void *); 302 void (*framedone_callback)(int, void *);
253 void *framedone_data; 303 void *framedone_data;
@@ -275,21 +325,68 @@ static struct
275 spinlock_t irq_stats_lock; 325 spinlock_t irq_stats_lock;
276 struct dsi_irq_stats irq_stats; 326 struct dsi_irq_stats irq_stats;
277#endif 327#endif
278} dsi; 328 /* DSI PLL Parameter Ranges */
329 unsigned long regm_max, regn_max;
330 unsigned long regm_dispc_max, regm_dsi_max;
331 unsigned long fint_min, fint_max;
332 unsigned long lpdiv_max;
333
334 int num_data_lanes;
335
336 unsigned scp_clk_refcount;
337};
338
339struct dsi_packet_sent_handler_data {
340 struct platform_device *dsidev;
341 struct completion *completion;
342};
343
344static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
279 345
280#ifdef DEBUG 346#ifdef DEBUG
281static unsigned int dsi_perf; 347static unsigned int dsi_perf;
282module_param_named(dsi_perf, dsi_perf, bool, 0644); 348module_param_named(dsi_perf, dsi_perf, bool, 0644);
283#endif 349#endif
284 350
285static inline void dsi_write_reg(const struct dsi_reg idx, u32 val) 351static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dsidev)
352{
353 return dev_get_drvdata(&dsidev->dev);
354}
355
356static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
286{ 357{
287 __raw_writel(val, dsi.base + idx.idx); 358 return dsi_pdev_map[dssdev->phy.dsi.module];
288} 359}
289 360
290static inline u32 dsi_read_reg(const struct dsi_reg idx) 361struct platform_device *dsi_get_dsidev_from_id(int module)
291{ 362{
292 return __raw_readl(dsi.base + idx.idx); 363 return dsi_pdev_map[module];
364}
365
366static int dsi_get_dsidev_id(struct platform_device *dsidev)
367{
368 /* TEMP: Pass 0 as the dsi module index till the time the dsi platform
369 * device names aren't changed to the form "omapdss_dsi.0",
370 * "omapdss_dsi.1" and so on */
371 BUG_ON(dsidev->id != -1);
372
373 return 0;
374}
375
376static inline void dsi_write_reg(struct platform_device *dsidev,
377 const struct dsi_reg idx, u32 val)
378{
379 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
380
381 __raw_writel(val, dsi->base + idx.idx);
382}
383
384static inline u32 dsi_read_reg(struct platform_device *dsidev,
385 const struct dsi_reg idx)
386{
387 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
388
389 return __raw_readl(dsi->base + idx.idx);
293} 390}
294 391
295 392
@@ -301,29 +398,42 @@ void dsi_restore_context(void)
301{ 398{
302} 399}
303 400
304void dsi_bus_lock(void) 401void dsi_bus_lock(struct omap_dss_device *dssdev)
305{ 402{
306 down(&dsi.bus_lock); 403 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
404 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
405
406 down(&dsi->bus_lock);
307} 407}
308EXPORT_SYMBOL(dsi_bus_lock); 408EXPORT_SYMBOL(dsi_bus_lock);
309 409
310void dsi_bus_unlock(void) 410void dsi_bus_unlock(struct omap_dss_device *dssdev)
311{ 411{
312 up(&dsi.bus_lock); 412 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
413 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
414
415 up(&dsi->bus_lock);
313} 416}
314EXPORT_SYMBOL(dsi_bus_unlock); 417EXPORT_SYMBOL(dsi_bus_unlock);
315 418
316static bool dsi_bus_is_locked(void) 419static bool dsi_bus_is_locked(struct platform_device *dsidev)
317{ 420{
318 return dsi.bus_lock.count == 0; 421 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
422
423 return dsi->bus_lock.count == 0;
319} 424}
320 425
321static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 426static void dsi_completion_handler(void *data, u32 mask)
322 int value) 427{
428 complete((struct completion *)data);
429}
430
431static inline int wait_for_bit_change(struct platform_device *dsidev,
432 const struct dsi_reg idx, int bitnum, int value)
323{ 433{
324 int t = 100000; 434 int t = 100000;
325 435
326 while (REG_GET(idx, bitnum, bitnum) != value) { 436 while (REG_GET(dsidev, idx, bitnum, bitnum) != value) {
327 if (--t == 0) 437 if (--t == 0)
328 return !value; 438 return !value;
329 } 439 }
@@ -332,18 +442,21 @@ static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
332} 442}
333 443
334#ifdef DEBUG 444#ifdef DEBUG
335static void dsi_perf_mark_setup(void) 445static void dsi_perf_mark_setup(struct platform_device *dsidev)
336{ 446{
337 dsi.perf_setup_time = ktime_get(); 447 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
448 dsi->perf_setup_time = ktime_get();
338} 449}
339 450
340static void dsi_perf_mark_start(void) 451static void dsi_perf_mark_start(struct platform_device *dsidev)
341{ 452{
342 dsi.perf_start_time = ktime_get(); 453 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
454 dsi->perf_start_time = ktime_get();
343} 455}
344 456
345static void dsi_perf_show(const char *name) 457static void dsi_perf_show(struct platform_device *dsidev, const char *name)
346{ 458{
459 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
347 ktime_t t, setup_time, trans_time; 460 ktime_t t, setup_time, trans_time;
348 u32 total_bytes; 461 u32 total_bytes;
349 u32 setup_us, trans_us, total_us; 462 u32 setup_us, trans_us, total_us;
@@ -353,21 +466,21 @@ static void dsi_perf_show(const char *name)
353 466
354 t = ktime_get(); 467 t = ktime_get();
355 468
356 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); 469 setup_time = ktime_sub(dsi->perf_start_time, dsi->perf_setup_time);
357 setup_us = (u32)ktime_to_us(setup_time); 470 setup_us = (u32)ktime_to_us(setup_time);
358 if (setup_us == 0) 471 if (setup_us == 0)
359 setup_us = 1; 472 setup_us = 1;
360 473
361 trans_time = ktime_sub(t, dsi.perf_start_time); 474 trans_time = ktime_sub(t, dsi->perf_start_time);
362 trans_us = (u32)ktime_to_us(trans_time); 475 trans_us = (u32)ktime_to_us(trans_time);
363 if (trans_us == 0) 476 if (trans_us == 0)
364 trans_us = 1; 477 trans_us = 1;
365 478
366 total_us = setup_us + trans_us; 479 total_us = setup_us + trans_us;
367 480
368 total_bytes = dsi.update_region.w * 481 total_bytes = dsi->update_region.w *
369 dsi.update_region.h * 482 dsi->update_region.h *
370 dsi.update_region.device->ctrl.pixel_size / 8; 483 dsi->update_region.device->ctrl.pixel_size / 8;
371 484
372 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " 485 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
373 "%u bytes, %u kbytes/sec\n", 486 "%u bytes, %u kbytes/sec\n",
@@ -380,13 +493,16 @@ static void dsi_perf_show(const char *name)
380 total_bytes * 1000 / total_us); 493 total_bytes * 1000 / total_us);
381} 494}
382#else 495#else
383#define dsi_perf_mark_setup() 496#define dsi_perf_mark_setup(x)
384#define dsi_perf_mark_start() 497#define dsi_perf_mark_start(x)
385#define dsi_perf_show(x) 498#define dsi_perf_show(x, y)
386#endif 499#endif
387 500
388static void print_irq_status(u32 status) 501static void print_irq_status(u32 status)
389{ 502{
503 if (status == 0)
504 return;
505
390#ifndef VERBOSE_IRQ 506#ifndef VERBOSE_IRQ
391 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) 507 if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
392 return; 508 return;
@@ -422,6 +538,9 @@ static void print_irq_status(u32 status)
422 538
423static void print_irq_status_vc(int channel, u32 status) 539static void print_irq_status_vc(int channel, u32 status)
424{ 540{
541 if (status == 0)
542 return;
543
425#ifndef VERBOSE_IRQ 544#ifndef VERBOSE_IRQ
426 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) 545 if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
427 return; 546 return;
@@ -448,6 +567,9 @@ static void print_irq_status_vc(int channel, u32 status)
448 567
449static void print_irq_status_cio(u32 status) 568static void print_irq_status_cio(u32 status)
450{ 569{
570 if (status == 0)
571 return;
572
451 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); 573 printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
452 574
453#define PIS(x) \ 575#define PIS(x) \
@@ -478,192 +600,476 @@ static void print_irq_status_cio(u32 status)
478 printk("\n"); 600 printk("\n");
479} 601}
480 602
481static int debug_irq; 603#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
482 604static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus,
483/* called from dss */ 605 u32 *vcstatus, u32 ciostatus)
484void dsi_irq_handler(void)
485{ 606{
486 u32 irqstatus, vcstatus, ciostatus; 607 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
487 int i; 608 int i;
488 609
489 irqstatus = dsi_read_reg(DSI_IRQSTATUS); 610 spin_lock(&dsi->irq_stats_lock);
490 611
491#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 612 dsi->irq_stats.irq_count++;
492 spin_lock(&dsi.irq_stats_lock); 613 dss_collect_irq_stats(irqstatus, dsi->irq_stats.dsi_irqs);
493 dsi.irq_stats.irq_count++; 614
494 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); 615 for (i = 0; i < 4; ++i)
616 dss_collect_irq_stats(vcstatus[i], dsi->irq_stats.vc_irqs[i]);
617
618 dss_collect_irq_stats(ciostatus, dsi->irq_stats.cio_irqs);
619
620 spin_unlock(&dsi->irq_stats_lock);
621}
622#else
623#define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus)
495#endif 624#endif
496 625
626static int debug_irq;
627
628static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus,
629 u32 *vcstatus, u32 ciostatus)
630{
631 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
632 int i;
633
497 if (irqstatus & DSI_IRQ_ERROR_MASK) { 634 if (irqstatus & DSI_IRQ_ERROR_MASK) {
498 DSSERR("DSI error, irqstatus %x\n", irqstatus); 635 DSSERR("DSI error, irqstatus %x\n", irqstatus);
499 print_irq_status(irqstatus); 636 print_irq_status(irqstatus);
500 spin_lock(&dsi.errors_lock); 637 spin_lock(&dsi->errors_lock);
501 dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK; 638 dsi->errors |= irqstatus & DSI_IRQ_ERROR_MASK;
502 spin_unlock(&dsi.errors_lock); 639 spin_unlock(&dsi->errors_lock);
503 } else if (debug_irq) { 640 } else if (debug_irq) {
504 print_irq_status(irqstatus); 641 print_irq_status(irqstatus);
505 } 642 }
506 643
507#ifdef DSI_CATCH_MISSING_TE 644 for (i = 0; i < 4; ++i) {
508 if (irqstatus & DSI_IRQ_TE_TRIGGER) 645 if (vcstatus[i] & DSI_VC_IRQ_ERROR_MASK) {
509 del_timer(&dsi.te_timer); 646 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
510#endif 647 i, vcstatus[i]);
648 print_irq_status_vc(i, vcstatus[i]);
649 } else if (debug_irq) {
650 print_irq_status_vc(i, vcstatus[i]);
651 }
652 }
653
654 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
655 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
656 print_irq_status_cio(ciostatus);
657 } else if (debug_irq) {
658 print_irq_status_cio(ciostatus);
659 }
660}
661
662static void dsi_call_isrs(struct dsi_isr_data *isr_array,
663 unsigned isr_array_size, u32 irqstatus)
664{
665 struct dsi_isr_data *isr_data;
666 int i;
667
668 for (i = 0; i < isr_array_size; i++) {
669 isr_data = &isr_array[i];
670 if (isr_data->isr && isr_data->mask & irqstatus)
671 isr_data->isr(isr_data->arg, irqstatus);
672 }
673}
674
675static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
676 u32 irqstatus, u32 *vcstatus, u32 ciostatus)
677{
678 int i;
679
680 dsi_call_isrs(isr_tables->isr_table,
681 ARRAY_SIZE(isr_tables->isr_table),
682 irqstatus);
511 683
512 for (i = 0; i < 4; ++i) { 684 for (i = 0; i < 4; ++i) {
513 if ((irqstatus & (1<<i)) == 0) 685 if (vcstatus[i] == 0)
514 continue; 686 continue;
687 dsi_call_isrs(isr_tables->isr_table_vc[i],
688 ARRAY_SIZE(isr_tables->isr_table_vc[i]),
689 vcstatus[i]);
690 }
515 691
516 vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 692 if (ciostatus != 0)
693 dsi_call_isrs(isr_tables->isr_table_cio,
694 ARRAY_SIZE(isr_tables->isr_table_cio),
695 ciostatus);
696}
517 697
518#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 698static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 699{
520#endif 700 struct platform_device *dsidev;
701 struct dsi_data *dsi;
702 u32 irqstatus, vcstatus[4], ciostatus;
703 int i;
521 704
522 if (vcstatus & DSI_VC_IRQ_BTA) { 705 dsidev = (struct platform_device *) arg;
523 complete(&dsi.bta_completion); 706 dsi = dsi_get_dsidrv_data(dsidev);
524 707
525 if (dsi.bta_callback) 708 spin_lock(&dsi->irq_lock);
526 dsi.bta_callback();
527 }
528 709
529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 710 irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 711
531 i, vcstatus); 712 /* IRQ is not for us */
532 print_irq_status_vc(i, vcstatus); 713 if (!irqstatus) {
533 } else if (debug_irq) { 714 spin_unlock(&dsi->irq_lock);
534 print_irq_status_vc(i, vcstatus); 715 return IRQ_NONE;
716 }
717
718 dsi_write_reg(dsidev, DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
719 /* flush posted write */
720 dsi_read_reg(dsidev, DSI_IRQSTATUS);
721
722 for (i = 0; i < 4; ++i) {
723 if ((irqstatus & (1 << i)) == 0) {
724 vcstatus[i] = 0;
725 continue;
535 } 726 }
536 727
537 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); 728 vcstatus[i] = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
729
730 dsi_write_reg(dsidev, DSI_VC_IRQSTATUS(i), vcstatus[i]);
538 /* flush posted write */ 731 /* flush posted write */
539 dsi_read_reg(DSI_VC_IRQSTATUS(i)); 732 dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
540 } 733 }
541 734
542 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { 735 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
543 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 736 ciostatus = dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS);
544 737
545#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 738 dsi_write_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
546 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); 739 /* flush posted write */
740 dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS);
741 } else {
742 ciostatus = 0;
743 }
744
745#ifdef DSI_CATCH_MISSING_TE
746 if (irqstatus & DSI_IRQ_TE_TRIGGER)
747 del_timer(&dsi->te_timer);
547#endif 748#endif
548 749
549 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); 750 /* make a copy and unlock, so that isrs can unregister
550 /* flush posted write */ 751 * themselves */
551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 752 memcpy(&dsi->isr_tables_copy, &dsi->isr_tables,
753 sizeof(dsi->isr_tables));
552 754
553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) { 755 spin_unlock(&dsi->irq_lock);
554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 756
555 print_irq_status_cio(ciostatus); 757 dsi_handle_isrs(&dsi->isr_tables_copy, irqstatus, vcstatus, ciostatus);
556 } else if (debug_irq) { 758
557 print_irq_status_cio(ciostatus); 759 dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus);
558 } 760
761 dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus);
762
763 return IRQ_HANDLED;
764}
765
766/* dsi->irq_lock has to be locked by the caller */
767static void _omap_dsi_configure_irqs(struct platform_device *dsidev,
768 struct dsi_isr_data *isr_array,
769 unsigned isr_array_size, u32 default_mask,
770 const struct dsi_reg enable_reg,
771 const struct dsi_reg status_reg)
772{
773 struct dsi_isr_data *isr_data;
774 u32 mask;
775 u32 old_mask;
776 int i;
777
778 mask = default_mask;
779
780 for (i = 0; i < isr_array_size; i++) {
781 isr_data = &isr_array[i];
782
783 if (isr_data->isr == NULL)
784 continue;
785
786 mask |= isr_data->mask;
559 } 787 }
560 788
561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 789 old_mask = dsi_read_reg(dsidev, enable_reg);
562 /* flush posted write */ 790 /* clear the irqstatus for newly enabled irqs */
563 dsi_read_reg(DSI_IRQSTATUS); 791 dsi_write_reg(dsidev, status_reg, (mask ^ old_mask) & mask);
792 dsi_write_reg(dsidev, enable_reg, mask);
564 793
565#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 794 /* flush posted writes */
566 spin_unlock(&dsi.irq_stats_lock); 795 dsi_read_reg(dsidev, enable_reg);
796 dsi_read_reg(dsidev, status_reg);
797}
798
799/* dsi->irq_lock has to be locked by the caller */
800static void _omap_dsi_set_irqs(struct platform_device *dsidev)
801{
802 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
803 u32 mask = DSI_IRQ_ERROR_MASK;
804#ifdef DSI_CATCH_MISSING_TE
805 mask |= DSI_IRQ_TE_TRIGGER;
567#endif 806#endif
807 _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table,
808 ARRAY_SIZE(dsi->isr_tables.isr_table), mask,
809 DSI_IRQENABLE, DSI_IRQSTATUS);
810}
811
812/* dsi->irq_lock has to be locked by the caller */
813static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc)
814{
815 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
816
817 _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_vc[vc],
818 ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]),
819 DSI_VC_IRQ_ERROR_MASK,
820 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
568} 821}
569 822
823/* dsi->irq_lock has to be locked by the caller */
824static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev)
825{
826 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
827
828 _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_cio,
829 ARRAY_SIZE(dsi->isr_tables.isr_table_cio),
830 DSI_CIO_IRQ_ERROR_MASK,
831 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
832}
570 833
571static void _dsi_initialize_irq(void) 834static void _dsi_initialize_irq(struct platform_device *dsidev)
572{ 835{
573 u32 l; 836 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
837 unsigned long flags;
838 int vc;
839
840 spin_lock_irqsave(&dsi->irq_lock, flags);
841
842 memset(&dsi->isr_tables, 0, sizeof(dsi->isr_tables));
843
844 _omap_dsi_set_irqs(dsidev);
845 for (vc = 0; vc < 4; ++vc)
846 _omap_dsi_set_irqs_vc(dsidev, vc);
847 _omap_dsi_set_irqs_cio(dsidev);
848
849 spin_unlock_irqrestore(&dsi->irq_lock, flags);
850}
851
852static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
853 struct dsi_isr_data *isr_array, unsigned isr_array_size)
854{
855 struct dsi_isr_data *isr_data;
856 int free_idx;
574 int i; 857 int i;
575 858
576 /* disable all interrupts */ 859 BUG_ON(isr == NULL);
577 dsi_write_reg(DSI_IRQENABLE, 0);
578 for (i = 0; i < 4; ++i)
579 dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
580 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
581 860
582 /* clear interrupt status */ 861 /* check for duplicate entry and find a free slot */
583 l = dsi_read_reg(DSI_IRQSTATUS); 862 free_idx = -1;
584 dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK); 863 for (i = 0; i < isr_array_size; i++) {
864 isr_data = &isr_array[i];
585 865
586 for (i = 0; i < 4; ++i) { 866 if (isr_data->isr == isr && isr_data->arg == arg &&
587 l = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 867 isr_data->mask == mask) {
588 dsi_write_reg(DSI_VC_IRQSTATUS(i), l); 868 return -EINVAL;
869 }
870
871 if (isr_data->isr == NULL && free_idx == -1)
872 free_idx = i;
589 } 873 }
590 874
591 l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 875 if (free_idx == -1)
592 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l); 876 return -EBUSY;
593 877
594 /* enable error irqs */ 878 isr_data = &isr_array[free_idx];
595 l = DSI_IRQ_ERROR_MASK; 879 isr_data->isr = isr;
596#ifdef DSI_CATCH_MISSING_TE 880 isr_data->arg = arg;
597 l |= DSI_IRQ_TE_TRIGGER; 881 isr_data->mask = mask;
598#endif
599 dsi_write_reg(DSI_IRQENABLE, l);
600 882
601 l = DSI_VC_IRQ_ERROR_MASK; 883 return 0;
602 for (i = 0; i < 4; ++i) 884}
603 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 885
886static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
887 struct dsi_isr_data *isr_array, unsigned isr_array_size)
888{
889 struct dsi_isr_data *isr_data;
890 int i;
891
892 for (i = 0; i < isr_array_size; i++) {
893 isr_data = &isr_array[i];
894 if (isr_data->isr != isr || isr_data->arg != arg ||
895 isr_data->mask != mask)
896 continue;
897
898 isr_data->isr = NULL;
899 isr_data->arg = NULL;
900 isr_data->mask = 0;
604 901
605 l = DSI_CIO_IRQ_ERROR_MASK; 902 return 0;
606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l); 903 }
904
905 return -EINVAL;
607} 906}
608 907
609static u32 dsi_get_errors(void) 908static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr,
909 void *arg, u32 mask)
610{ 910{
911 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
611 unsigned long flags; 912 unsigned long flags;
612 u32 e; 913 int r;
613 spin_lock_irqsave(&dsi.errors_lock, flags); 914
614 e = dsi.errors; 915 spin_lock_irqsave(&dsi->irq_lock, flags);
615 dsi.errors = 0; 916
616 spin_unlock_irqrestore(&dsi.errors_lock, flags); 917 r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table,
617 return e; 918 ARRAY_SIZE(dsi->isr_tables.isr_table));
919
920 if (r == 0)
921 _omap_dsi_set_irqs(dsidev);
922
923 spin_unlock_irqrestore(&dsi->irq_lock, flags);
924
925 return r;
618} 926}
619 927
620static void dsi_vc_enable_bta_irq(int channel) 928static int dsi_unregister_isr(struct platform_device *dsidev,
929 omap_dsi_isr_t isr, void *arg, u32 mask)
621{ 930{
622 u32 l; 931 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
932 unsigned long flags;
933 int r;
623 934
624 dsi_write_reg(DSI_VC_IRQSTATUS(channel), DSI_VC_IRQ_BTA); 935 spin_lock_irqsave(&dsi->irq_lock, flags);
625 936
626 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 937 r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table,
627 l |= DSI_VC_IRQ_BTA; 938 ARRAY_SIZE(dsi->isr_tables.isr_table));
628 dsi_write_reg(DSI_VC_IRQENABLE(channel), l); 939
940 if (r == 0)
941 _omap_dsi_set_irqs(dsidev);
942
943 spin_unlock_irqrestore(&dsi->irq_lock, flags);
944
945 return r;
629} 946}
630 947
631static void dsi_vc_disable_bta_irq(int channel) 948static int dsi_register_isr_vc(struct platform_device *dsidev, int channel,
949 omap_dsi_isr_t isr, void *arg, u32 mask)
632{ 950{
633 u32 l; 951 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
952 unsigned long flags;
953 int r;
954
955 spin_lock_irqsave(&dsi->irq_lock, flags);
956
957 r = _dsi_register_isr(isr, arg, mask,
958 dsi->isr_tables.isr_table_vc[channel],
959 ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
960
961 if (r == 0)
962 _omap_dsi_set_irqs_vc(dsidev, channel);
963
964 spin_unlock_irqrestore(&dsi->irq_lock, flags);
965
966 return r;
967}
968
969static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel,
970 omap_dsi_isr_t isr, void *arg, u32 mask)
971{
972 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
973 unsigned long flags;
974 int r;
975
976 spin_lock_irqsave(&dsi->irq_lock, flags);
977
978 r = _dsi_unregister_isr(isr, arg, mask,
979 dsi->isr_tables.isr_table_vc[channel],
980 ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
981
982 if (r == 0)
983 _omap_dsi_set_irqs_vc(dsidev, channel);
984
985 spin_unlock_irqrestore(&dsi->irq_lock, flags);
986
987 return r;
988}
634 989
635 l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); 990static int dsi_register_isr_cio(struct platform_device *dsidev,
636 l &= ~DSI_VC_IRQ_BTA; 991 omap_dsi_isr_t isr, void *arg, u32 mask)
637 dsi_write_reg(DSI_VC_IRQENABLE(channel), l); 992{
993 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
994 unsigned long flags;
995 int r;
996
997 spin_lock_irqsave(&dsi->irq_lock, flags);
998
999 r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
1000 ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
1001
1002 if (r == 0)
1003 _omap_dsi_set_irqs_cio(dsidev);
1004
1005 spin_unlock_irqrestore(&dsi->irq_lock, flags);
1006
1007 return r;
1008}
1009
1010static int dsi_unregister_isr_cio(struct platform_device *dsidev,
1011 omap_dsi_isr_t isr, void *arg, u32 mask)
1012{
1013 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1014 unsigned long flags;
1015 int r;
1016
1017 spin_lock_irqsave(&dsi->irq_lock, flags);
1018
1019 r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
1020 ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
1021
1022 if (r == 0)
1023 _omap_dsi_set_irqs_cio(dsidev);
1024
1025 spin_unlock_irqrestore(&dsi->irq_lock, flags);
1026
1027 return r;
638} 1028}
639 1029
640/* DSI func clock. this could also be DSI2_PLL_FCLK */ 1030static u32 dsi_get_errors(struct platform_device *dsidev)
1031{
1032 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1033 unsigned long flags;
1034 u32 e;
1035 spin_lock_irqsave(&dsi->errors_lock, flags);
1036 e = dsi->errors;
1037 dsi->errors = 0;
1038 spin_unlock_irqrestore(&dsi->errors_lock, flags);
1039 return e;
1040}
1041
1042/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */
641static inline void enable_clocks(bool enable) 1043static inline void enable_clocks(bool enable)
642{ 1044{
643 if (enable) 1045 if (enable)
644 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1046 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
645 else 1047 else
646 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1048 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
647} 1049}
648 1050
649/* source clock for DSI PLL. this could also be PCLKFREE */ 1051/* source clock for DSI PLL. this could also be PCLKFREE */
650static inline void dsi_enable_pll_clock(bool enable) 1052static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1053 bool enable)
651{ 1054{
1055 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1056
652 if (enable) 1057 if (enable)
653 dss_clk_enable(DSS_CLK_FCK2); 1058 dss_clk_enable(DSS_CLK_SYSCK);
654 else 1059 else
655 dss_clk_disable(DSS_CLK_FCK2); 1060 dss_clk_disable(DSS_CLK_SYSCK);
656 1061
657 if (enable && dsi.pll_locked) { 1062 if (enable && dsi->pll_locked) {
658 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) 1063 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
659 DSSERR("cannot lock PLL when enabling clocks\n"); 1064 DSSERR("cannot lock PLL when enabling clocks\n");
660 } 1065 }
661} 1066}
662 1067
663#ifdef DEBUG 1068#ifdef DEBUG
664static void _dsi_print_reset_status(void) 1069static void _dsi_print_reset_status(struct platform_device *dsidev)
665{ 1070{
666 u32 l; 1071 u32 l;
1072 int b0, b1, b2;
667 1073
668 if (!dss_debug) 1074 if (!dss_debug)
669 return; 1075 return;
@@ -671,35 +1077,47 @@ static void _dsi_print_reset_status(void)
671 /* A dummy read using the SCP interface to any DSIPHY register is 1077 /* A dummy read using the SCP interface to any DSIPHY register is
672 * required after DSIPHY reset to complete the reset of the DSI complex 1078 * required after DSIPHY reset to complete the reset of the DSI complex
673 * I/O. */ 1079 * I/O. */
674 l = dsi_read_reg(DSI_DSIPHY_CFG5); 1080 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
675 1081
676 printk(KERN_DEBUG "DSI resets: "); 1082 printk(KERN_DEBUG "DSI resets: ");
677 1083
678 l = dsi_read_reg(DSI_PLL_STATUS); 1084 l = dsi_read_reg(dsidev, DSI_PLL_STATUS);
679 printk("PLL (%d) ", FLD_GET(l, 0, 0)); 1085 printk("PLL (%d) ", FLD_GET(l, 0, 0));
680 1086
681 l = dsi_read_reg(DSI_COMPLEXIO_CFG1); 1087 l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
682 printk("CIO (%d) ", FLD_GET(l, 29, 29)); 1088 printk("CIO (%d) ", FLD_GET(l, 29, 29));
683 1089
684 l = dsi_read_reg(DSI_DSIPHY_CFG5); 1090 if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
685 printk("PHY (%x, %d, %d, %d)\n", 1091 b0 = 28;
686 FLD_GET(l, 28, 26), 1092 b1 = 27;
1093 b2 = 26;
1094 } else {
1095 b0 = 24;
1096 b1 = 25;
1097 b2 = 26;
1098 }
1099
1100 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
1101 printk("PHY (%x%x%x, %d, %d, %d)\n",
1102 FLD_GET(l, b0, b0),
1103 FLD_GET(l, b1, b1),
1104 FLD_GET(l, b2, b2),
687 FLD_GET(l, 29, 29), 1105 FLD_GET(l, 29, 29),
688 FLD_GET(l, 30, 30), 1106 FLD_GET(l, 30, 30),
689 FLD_GET(l, 31, 31)); 1107 FLD_GET(l, 31, 31));
690} 1108}
691#else 1109#else
692#define _dsi_print_reset_status() 1110#define _dsi_print_reset_status(x)
693#endif 1111#endif
694 1112
695static inline int dsi_if_enable(bool enable) 1113static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
696{ 1114{
697 DSSDBG("dsi_if_enable(%d)\n", enable); 1115 DSSDBG("dsi_if_enable(%d)\n", enable);
698 1116
699 enable = enable ? 1 : 0; 1117 enable = enable ? 1 : 0;
700 REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */ 1118 REG_FLD_MOD(dsidev, DSI_CTRL, enable, 0, 0); /* IF_EN */
701 1119
702 if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) { 1120 if (wait_for_bit_change(dsidev, DSI_CTRL, 0, enable) != enable) {
703 DSSERR("Failed to set dsi_if_enable to %d\n", enable); 1121 DSSERR("Failed to set dsi_if_enable to %d\n", enable);
704 return -EIO; 1122 return -EIO;
705 } 1123 }
@@ -707,31 +1125,38 @@ static inline int dsi_if_enable(bool enable)
707 return 0; 1125 return 0;
708} 1126}
709 1127
710unsigned long dsi_get_dsi1_pll_rate(void) 1128unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
711{ 1129{
712 return dsi.current_cinfo.dsi1_pll_fclk; 1130 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1131
1132 return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk;
713} 1133}
714 1134
715static unsigned long dsi_get_dsi2_pll_rate(void) 1135static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
716{ 1136{
717 return dsi.current_cinfo.dsi2_pll_fclk; 1137 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1138
1139 return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk;
718} 1140}
719 1141
720static unsigned long dsi_get_txbyteclkhs(void) 1142static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
721{ 1143{
722 return dsi.current_cinfo.clkin4ddr / 16; 1144 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1145
1146 return dsi->current_cinfo.clkin4ddr / 16;
723} 1147}
724 1148
725static unsigned long dsi_fclk_rate(void) 1149static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
726{ 1150{
727 unsigned long r; 1151 unsigned long r;
1152 int dsi_module = dsi_get_dsidev_id(dsidev);
728 1153
729 if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { 1154 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) {
730 /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ 1155 /* DSI FCLK source is DSS_CLK_FCK */
731 r = dss_clk_get_rate(DSS_CLK_FCK1); 1156 r = dss_clk_get_rate(DSS_CLK_FCK);
732 } else { 1157 } else {
733 /* DSI FCLK source is DSI2_PLL_FCLK */ 1158 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
734 r = dsi_get_dsi2_pll_rate(); 1159 r = dsi_get_pll_hsdiv_dsi_rate(dsidev);
735 } 1160 }
736 1161
737 return r; 1162 return r;
@@ -739,31 +1164,50 @@ static unsigned long dsi_fclk_rate(void)
739 1164
740static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) 1165static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
741{ 1166{
1167 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1168 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
742 unsigned long dsi_fclk; 1169 unsigned long dsi_fclk;
743 unsigned lp_clk_div; 1170 unsigned lp_clk_div;
744 unsigned long lp_clk; 1171 unsigned long lp_clk;
745 1172
746 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; 1173 lp_clk_div = dssdev->clocks.dsi.lp_clk_div;
747 1174
748 if (lp_clk_div == 0 || lp_clk_div > LP_DIV_MAX) 1175 if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max)
749 return -EINVAL; 1176 return -EINVAL;
750 1177
751 dsi_fclk = dsi_fclk_rate(); 1178 dsi_fclk = dsi_fclk_rate(dsidev);
752 1179
753 lp_clk = dsi_fclk / 2 / lp_clk_div; 1180 lp_clk = dsi_fclk / 2 / lp_clk_div;
754 1181
755 DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); 1182 DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
756 dsi.current_cinfo.lp_clk = lp_clk; 1183 dsi->current_cinfo.lp_clk = lp_clk;
757 dsi.current_cinfo.lp_clk_div = lp_clk_div; 1184 dsi->current_cinfo.lp_clk_div = lp_clk_div;
758 1185
759 REG_FLD_MOD(DSI_CLK_CTRL, lp_clk_div, 12, 0); /* LP_CLK_DIVISOR */ 1186 /* LP_CLK_DIVISOR */
1187 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
760 1188
761 REG_FLD_MOD(DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 1189 /* LP_RX_SYNCHRO_ENABLE */
762 21, 21); /* LP_RX_SYNCHRO_ENABLE */ 1190 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 21, 21);
763 1191
764 return 0; 1192 return 0;
765} 1193}
766 1194
1195static void dsi_enable_scp_clk(struct platform_device *dsidev)
1196{
1197 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1198
1199 if (dsi->scp_clk_refcount++ == 0)
1200 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */
1201}
1202
1203static void dsi_disable_scp_clk(struct platform_device *dsidev)
1204{
1205 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1206
1207 WARN_ON(dsi->scp_clk_refcount == 0);
1208 if (--dsi->scp_clk_refcount == 0)
1209 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */
1210}
767 1211
768enum dsi_pll_power_state { 1212enum dsi_pll_power_state {
769 DSI_PLL_POWER_OFF = 0x0, 1213 DSI_PLL_POWER_OFF = 0x0,
@@ -772,14 +1216,21 @@ enum dsi_pll_power_state {
772 DSI_PLL_POWER_ON_DIV = 0x3, 1216 DSI_PLL_POWER_ON_DIV = 0x3,
773}; 1217};
774 1218
775static int dsi_pll_power(enum dsi_pll_power_state state) 1219static int dsi_pll_power(struct platform_device *dsidev,
1220 enum dsi_pll_power_state state)
776{ 1221{
777 int t = 0; 1222 int t = 0;
778 1223
779 REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ 1224 /* DSI-PLL power command 0x3 is not working */
1225 if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) &&
1226 state == DSI_PLL_POWER_ON_DIV)
1227 state = DSI_PLL_POWER_ON_ALL;
1228
1229 /* PLL_PWR_CMD */
1230 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, state, 31, 30);
780 1231
781 /* PLL_PWR_STATUS */ 1232 /* PLL_PWR_STATUS */
782 while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { 1233 while (FLD_GET(dsi_read_reg(dsidev, DSI_CLK_CTRL), 29, 28) != state) {
783 if (++t > 1000) { 1234 if (++t > 1000) {
784 DSSERR("Failed to set DSI PLL power mode to %d\n", 1235 DSSERR("Failed to set DSI PLL power mode to %d\n",
785 state); 1236 state);
@@ -792,27 +1243,31 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
792} 1243}
793 1244
794/* calculate clock rates using dividers in cinfo */ 1245/* calculate clock rates using dividers in cinfo */
795static int dsi_calc_clock_rates(struct dsi_clock_info *cinfo) 1246static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1247 struct dsi_clock_info *cinfo)
796{ 1248{
797 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) 1249 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1250 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1251
1252 if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max)
798 return -EINVAL; 1253 return -EINVAL;
799 1254
800 if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) 1255 if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max)
801 return -EINVAL; 1256 return -EINVAL;
802 1257
803 if (cinfo->regm3 > REGM3_MAX) 1258 if (cinfo->regm_dispc > dsi->regm_dispc_max)
804 return -EINVAL; 1259 return -EINVAL;
805 1260
806 if (cinfo->regm4 > REGM4_MAX) 1261 if (cinfo->regm_dsi > dsi->regm_dsi_max)
807 return -EINVAL; 1262 return -EINVAL;
808 1263
809 if (cinfo->use_dss2_fck) { 1264 if (cinfo->use_sys_clk) {
810 cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); 1265 cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK);
811 /* XXX it is unclear if highfreq should be used 1266 /* XXX it is unclear if highfreq should be used
812 * with DSS2_FCK source also */ 1267 * with DSS_SYS_CLK source also */
813 cinfo->highfreq = 0; 1268 cinfo->highfreq = 0;
814 } else { 1269 } else {
815 cinfo->clkin = dispc_pclk_rate(); 1270 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id);
816 1271
817 if (cinfo->clkin < 32000000) 1272 if (cinfo->clkin < 32000000)
818 cinfo->highfreq = 0; 1273 cinfo->highfreq = 0;
@@ -822,7 +1277,7 @@ static int dsi_calc_clock_rates(struct dsi_clock_info *cinfo)
822 1277
823 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1278 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
824 1279
825 if (cinfo->fint > FINT_MAX || cinfo->fint < FINT_MIN) 1280 if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
826 return -EINVAL; 1281 return -EINVAL;
827 1282
828 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; 1283 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -830,44 +1285,49 @@ static int dsi_calc_clock_rates(struct dsi_clock_info *cinfo)
830 if (cinfo->clkin4ddr > 1800 * 1000 * 1000) 1285 if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
831 return -EINVAL; 1286 return -EINVAL;
832 1287
833 if (cinfo->regm3 > 0) 1288 if (cinfo->regm_dispc > 0)
834 cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; 1289 cinfo->dsi_pll_hsdiv_dispc_clk =
1290 cinfo->clkin4ddr / cinfo->regm_dispc;
835 else 1291 else
836 cinfo->dsi1_pll_fclk = 0; 1292 cinfo->dsi_pll_hsdiv_dispc_clk = 0;
837 1293
838 if (cinfo->regm4 > 0) 1294 if (cinfo->regm_dsi > 0)
839 cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; 1295 cinfo->dsi_pll_hsdiv_dsi_clk =
1296 cinfo->clkin4ddr / cinfo->regm_dsi;
840 else 1297 else
841 cinfo->dsi2_pll_fclk = 0; 1298 cinfo->dsi_pll_hsdiv_dsi_clk = 0;
842 1299
843 return 0; 1300 return 0;
844} 1301}
845 1302
846int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 1303int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
847 struct dsi_clock_info *dsi_cinfo, 1304 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
848 struct dispc_clock_info *dispc_cinfo) 1305 struct dispc_clock_info *dispc_cinfo)
849{ 1306{
1307 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
850 struct dsi_clock_info cur, best; 1308 struct dsi_clock_info cur, best;
851 struct dispc_clock_info best_dispc; 1309 struct dispc_clock_info best_dispc;
852 int min_fck_per_pck; 1310 int min_fck_per_pck;
853 int match = 0; 1311 int match = 0;
854 unsigned long dss_clk_fck2; 1312 unsigned long dss_sys_clk, max_dss_fck;
1313
1314 dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK);
855 1315
856 dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); 1316 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
857 1317
858 if (req_pck == dsi.cache_req_pck && 1318 if (req_pck == dsi->cache_req_pck &&
859 dsi.cache_cinfo.clkin == dss_clk_fck2) { 1319 dsi->cache_cinfo.clkin == dss_sys_clk) {
860 DSSDBG("DSI clock info found from cache\n"); 1320 DSSDBG("DSI clock info found from cache\n");
861 *dsi_cinfo = dsi.cache_cinfo; 1321 *dsi_cinfo = dsi->cache_cinfo;
862 dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, 1322 dispc_find_clk_divs(is_tft, req_pck,
863 dispc_cinfo); 1323 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
864 return 0; 1324 return 0;
865 } 1325 }
866 1326
867 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 1327 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
868 1328
869 if (min_fck_per_pck && 1329 if (min_fck_per_pck &&
870 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 1330 req_pck * min_fck_per_pck > max_dss_fck) {
871 DSSERR("Requested pixel clock not possible with the current " 1331 DSSERR("Requested pixel clock not possible with the current "
872 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 1332 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
873 "the constraint off.\n"); 1333 "the constraint off.\n");
@@ -881,24 +1341,24 @@ retry:
881 memset(&best_dispc, 0, sizeof(best_dispc)); 1341 memset(&best_dispc, 0, sizeof(best_dispc));
882 1342
883 memset(&cur, 0, sizeof(cur)); 1343 memset(&cur, 0, sizeof(cur));
884 cur.clkin = dss_clk_fck2; 1344 cur.clkin = dss_sys_clk;
885 cur.use_dss2_fck = 1; 1345 cur.use_sys_clk = 1;
886 cur.highfreq = 0; 1346 cur.highfreq = 0;
887 1347
888 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1348 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
889 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1349 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
890 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1350 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
891 for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { 1351 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
892 if (cur.highfreq == 0) 1352 if (cur.highfreq == 0)
893 cur.fint = cur.clkin / cur.regn; 1353 cur.fint = cur.clkin / cur.regn;
894 else 1354 else
895 cur.fint = cur.clkin / (2 * cur.regn); 1355 cur.fint = cur.clkin / (2 * cur.regn);
896 1356
897 if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) 1357 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
898 continue; 1358 continue;
899 1359
900 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1360 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
901 for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { 1361 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
902 unsigned long a, b; 1362 unsigned long a, b;
903 1363
904 a = 2 * cur.regm * (cur.clkin/1000); 1364 a = 2 * cur.regm * (cur.clkin/1000);
@@ -908,30 +1368,32 @@ retry:
908 if (cur.clkin4ddr > 1800 * 1000 * 1000) 1368 if (cur.clkin4ddr > 1800 * 1000 * 1000)
909 break; 1369 break;
910 1370
911 /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ 1371 /* dsi_pll_hsdiv_dispc_clk(MHz) =
912 for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; 1372 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
913 ++cur.regm3) { 1373 for (cur.regm_dispc = 1; cur.regm_dispc <
1374 dsi->regm_dispc_max; ++cur.regm_dispc) {
914 struct dispc_clock_info cur_dispc; 1375 struct dispc_clock_info cur_dispc;
915 cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; 1376 cur.dsi_pll_hsdiv_dispc_clk =
1377 cur.clkin4ddr / cur.regm_dispc;
916 1378
917 /* this will narrow down the search a bit, 1379 /* this will narrow down the search a bit,
918 * but still give pixclocks below what was 1380 * but still give pixclocks below what was
919 * requested */ 1381 * requested */
920 if (cur.dsi1_pll_fclk < req_pck) 1382 if (cur.dsi_pll_hsdiv_dispc_clk < req_pck)
921 break; 1383 break;
922 1384
923 if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) 1385 if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck)
924 continue; 1386 continue;
925 1387
926 if (min_fck_per_pck && 1388 if (min_fck_per_pck &&
927 cur.dsi1_pll_fclk < 1389 cur.dsi_pll_hsdiv_dispc_clk <
928 req_pck * min_fck_per_pck) 1390 req_pck * min_fck_per_pck)
929 continue; 1391 continue;
930 1392
931 match = 1; 1393 match = 1;
932 1394
933 dispc_find_clk_divs(is_tft, req_pck, 1395 dispc_find_clk_divs(is_tft, req_pck,
934 cur.dsi1_pll_fclk, 1396 cur.dsi_pll_hsdiv_dispc_clk,
935 &cur_dispc); 1397 &cur_dispc);
936 1398
937 if (abs(cur_dispc.pck - req_pck) < 1399 if (abs(cur_dispc.pck - req_pck) <
@@ -960,44 +1422,53 @@ found:
960 return -EINVAL; 1422 return -EINVAL;
961 } 1423 }
962 1424
963 /* DSI2_PLL_FCLK (regm4) is not used */ 1425 /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */
964 best.regm4 = 0; 1426 best.regm_dsi = 0;
965 best.dsi2_pll_fclk = 0; 1427 best.dsi_pll_hsdiv_dsi_clk = 0;
966 1428
967 if (dsi_cinfo) 1429 if (dsi_cinfo)
968 *dsi_cinfo = best; 1430 *dsi_cinfo = best;
969 if (dispc_cinfo) 1431 if (dispc_cinfo)
970 *dispc_cinfo = best_dispc; 1432 *dispc_cinfo = best_dispc;
971 1433
972 dsi.cache_req_pck = req_pck; 1434 dsi->cache_req_pck = req_pck;
973 dsi.cache_clk_freq = 0; 1435 dsi->cache_clk_freq = 0;
974 dsi.cache_cinfo = best; 1436 dsi->cache_cinfo = best;
975 1437
976 return 0; 1438 return 0;
977} 1439}
978 1440
979int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) 1441int dsi_pll_set_clock_div(struct platform_device *dsidev,
1442 struct dsi_clock_info *cinfo)
980{ 1443{
1444 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
981 int r = 0; 1445 int r = 0;
982 u32 l; 1446 u32 l;
983 int f; 1447 int f = 0;
1448 u8 regn_start, regn_end, regm_start, regm_end;
1449 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
984 1450
985 DSSDBGF(); 1451 DSSDBGF();
986 1452
987 dsi.current_cinfo.fint = cinfo->fint; 1453 dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk;
988 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1454 dsi->current_cinfo.highfreq = cinfo->highfreq;
989 dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk;
990 dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk;
991 1455
992 dsi.current_cinfo.regn = cinfo->regn; 1456 dsi->current_cinfo.fint = cinfo->fint;
993 dsi.current_cinfo.regm = cinfo->regm; 1457 dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
994 dsi.current_cinfo.regm3 = cinfo->regm3; 1458 dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk =
995 dsi.current_cinfo.regm4 = cinfo->regm4; 1459 cinfo->dsi_pll_hsdiv_dispc_clk;
1460 dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk =
1461 cinfo->dsi_pll_hsdiv_dsi_clk;
1462
1463 dsi->current_cinfo.regn = cinfo->regn;
1464 dsi->current_cinfo.regm = cinfo->regm;
1465 dsi->current_cinfo.regm_dispc = cinfo->regm_dispc;
1466 dsi->current_cinfo.regm_dsi = cinfo->regm_dsi;
996 1467
997 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1468 DSSDBG("DSI Fint %ld\n", cinfo->fint);
998 1469
999 DSSDBG("clkin (%s) rate %ld, highfreq %d\n", 1470 DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
1000 cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", 1471 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree",
1001 cinfo->clkin, 1472 cinfo->clkin,
1002 cinfo->highfreq); 1473 cinfo->highfreq);
1003 1474
@@ -1014,63 +1485,79 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1014 1485
1015 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); 1486 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1016 1487
1017 DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", 1488 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1018 cinfo->regm3, cinfo->dsi1_pll_fclk); 1489 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1019 DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", 1490 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1020 cinfo->regm4, cinfo->dsi2_pll_fclk); 1491 cinfo->dsi_pll_hsdiv_dispc_clk);
1021 1492 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1022 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ 1493 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1023 1494 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1024 l = dsi_read_reg(DSI_PLL_CONFIGURATION1); 1495 cinfo->dsi_pll_hsdiv_dsi_clk);
1496
1497 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
1498 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
1499 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
1500 &regm_dispc_end);
1501 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1502 &regm_dsi_end);
1503
1504 /* DSI_PLL_AUTOMODE = manual */
1505 REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0);
1506
1507 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1);
1025 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ 1508 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1026 l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ 1509 /* DSI_PLL_REGN */
1027 l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ 1510 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
1028 l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, 1511 /* DSI_PLL_REGM */
1029 22, 19); /* DSI_CLOCK_DIV */ 1512 l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
1030 l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, 1513 /* DSI_CLOCK_DIV */
1031 26, 23); /* DSIPROTO_CLOCK_DIV */ 1514 l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
1032 dsi_write_reg(DSI_PLL_CONFIGURATION1, l); 1515 regm_dispc_start, regm_dispc_end);
1033 1516 /* DSIPROTO_CLOCK_DIV */
1034 BUG_ON(cinfo->fint < 750000 || cinfo->fint > 2100000); 1517 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1035 if (cinfo->fint < 1000000) 1518 regm_dsi_start, regm_dsi_end);
1036 f = 0x3; 1519 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
1037 else if (cinfo->fint < 1250000) 1520
1038 f = 0x4; 1521 BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
1039 else if (cinfo->fint < 1500000) 1522
1040 f = 0x5; 1523 if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
1041 else if (cinfo->fint < 1750000) 1524 f = cinfo->fint < 1000000 ? 0x3 :
1042 f = 0x6; 1525 cinfo->fint < 1250000 ? 0x4 :
1043 else 1526 cinfo->fint < 1500000 ? 0x5 :
1044 f = 0x7; 1527 cinfo->fint < 1750000 ? 0x6 :
1528 0x7;
1529 }
1045 1530
1046 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1531 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
1047 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1532
1048 l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 1533 if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
1534 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1535 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
1049 11, 11); /* DSI_PLL_CLKSEL */ 1536 11, 11); /* DSI_PLL_CLKSEL */
1050 l = FLD_MOD(l, cinfo->highfreq, 1537 l = FLD_MOD(l, cinfo->highfreq,
1051 12, 12); /* DSI_PLL_HIGHFREQ */ 1538 12, 12); /* DSI_PLL_HIGHFREQ */
1052 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ 1539 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
1053 l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ 1540 l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
1054 l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ 1541 l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */
1055 dsi_write_reg(DSI_PLL_CONFIGURATION2, l); 1542 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
1056 1543
1057 REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ 1544 REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */
1058 1545
1059 if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) { 1546 if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) {
1060 DSSERR("dsi pll go bit not going down.\n"); 1547 DSSERR("dsi pll go bit not going down.\n");
1061 r = -EIO; 1548 r = -EIO;
1062 goto err; 1549 goto err;
1063 } 1550 }
1064 1551
1065 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) { 1552 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) {
1066 DSSERR("cannot lock PLL\n"); 1553 DSSERR("cannot lock PLL\n");
1067 r = -EIO; 1554 r = -EIO;
1068 goto err; 1555 goto err;
1069 } 1556 }
1070 1557
1071 dsi.pll_locked = 1; 1558 dsi->pll_locked = 1;
1072 1559
1073 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1560 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
1074 l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ 1561 l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */
1075 l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ 1562 l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */
1076 l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ 1563 l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */
@@ -1085,32 +1572,53 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1085 l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ 1572 l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */
1086 l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ 1573 l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */
1087 l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ 1574 l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */
1088 dsi_write_reg(DSI_PLL_CONFIGURATION2, l); 1575 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
1089 1576
1090 DSSDBG("PLL config done\n"); 1577 DSSDBG("PLL config done\n");
1091err: 1578err:
1092 return r; 1579 return r;
1093} 1580}
1094 1581
1095int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, 1582int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1096 bool enable_hsdiv) 1583 bool enable_hsdiv)
1097{ 1584{
1585 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1098 int r = 0; 1586 int r = 0;
1099 enum dsi_pll_power_state pwstate; 1587 enum dsi_pll_power_state pwstate;
1100 1588
1101 DSSDBG("PLL init\n"); 1589 DSSDBG("PLL init\n");
1102 1590
1591 if (dsi->vdds_dsi_reg == NULL) {
1592 struct regulator *vdds_dsi;
1593
1594 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
1595
1596 if (IS_ERR(vdds_dsi)) {
1597 DSSERR("can't get VDDS_DSI regulator\n");
1598 return PTR_ERR(vdds_dsi);
1599 }
1600
1601 dsi->vdds_dsi_reg = vdds_dsi;
1602 }
1603
1103 enable_clocks(1); 1604 enable_clocks(1);
1104 dsi_enable_pll_clock(1); 1605 dsi_enable_pll_clock(dsidev, 1);
1606 /*
1607 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
1608 */
1609 dsi_enable_scp_clk(dsidev);
1105 1610
1106 r = regulator_enable(dsi.vdds_dsi_reg); 1611 if (!dsi->vdds_dsi_enabled) {
1107 if (r) 1612 r = regulator_enable(dsi->vdds_dsi_reg);
1108 goto err0; 1613 if (r)
1614 goto err0;
1615 dsi->vdds_dsi_enabled = true;
1616 }
1109 1617
1110 /* XXX PLL does not come out of reset without this... */ 1618 /* XXX PLL does not come out of reset without this... */
1111 dispc_pck_free_enable(1); 1619 dispc_pck_free_enable(1);
1112 1620
1113 if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { 1621 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 0, 1) != 1) {
1114 DSSERR("PLL not coming out of reset.\n"); 1622 DSSERR("PLL not coming out of reset.\n");
1115 r = -ENODEV; 1623 r = -ENODEV;
1116 dispc_pck_free_enable(0); 1624 dispc_pck_free_enable(0);
@@ -1130,7 +1638,7 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1130 else 1638 else
1131 pwstate = DSI_PLL_POWER_OFF; 1639 pwstate = DSI_PLL_POWER_OFF;
1132 1640
1133 r = dsi_pll_power(pwstate); 1641 r = dsi_pll_power(dsidev, pwstate);
1134 1642
1135 if (r) 1643 if (r)
1136 goto err1; 1644 goto err1;
@@ -1139,92 +1647,121 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1139 1647
1140 return 0; 1648 return 0;
1141err1: 1649err1:
1142 regulator_disable(dsi.vdds_dsi_reg); 1650 if (dsi->vdds_dsi_enabled) {
1651 regulator_disable(dsi->vdds_dsi_reg);
1652 dsi->vdds_dsi_enabled = false;
1653 }
1143err0: 1654err0:
1655 dsi_disable_scp_clk(dsidev);
1144 enable_clocks(0); 1656 enable_clocks(0);
1145 dsi_enable_pll_clock(0); 1657 dsi_enable_pll_clock(dsidev, 0);
1146 return r; 1658 return r;
1147} 1659}
1148 1660
1149void dsi_pll_uninit(void) 1661void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
1150{ 1662{
1663 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1664
1665 dsi->pll_locked = 0;
1666 dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
1667 if (disconnect_lanes) {
1668 WARN_ON(!dsi->vdds_dsi_enabled);
1669 regulator_disable(dsi->vdds_dsi_reg);
1670 dsi->vdds_dsi_enabled = false;
1671 }
1672
1673 dsi_disable_scp_clk(dsidev);
1151 enable_clocks(0); 1674 enable_clocks(0);
1152 dsi_enable_pll_clock(0); 1675 dsi_enable_pll_clock(dsidev, 0);
1153 1676
1154 dsi.pll_locked = 0;
1155 dsi_pll_power(DSI_PLL_POWER_OFF);
1156 regulator_disable(dsi.vdds_dsi_reg);
1157 DSSDBG("PLL uninit done\n"); 1677 DSSDBG("PLL uninit done\n");
1158} 1678}
1159 1679
1160void dsi_dump_clocks(struct seq_file *s) 1680static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1681 struct seq_file *s)
1161{ 1682{
1162 int clksel; 1683 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1163 struct dsi_clock_info *cinfo = &dsi.current_cinfo; 1684 struct dsi_clock_info *cinfo = &dsi->current_cinfo;
1685 enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
1686 int dsi_module = dsi_get_dsidev_id(dsidev);
1164 1687
1165 enable_clocks(1); 1688 dispc_clk_src = dss_get_dispc_clk_source();
1689 dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
1166 1690
1167 clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11); 1691 enable_clocks(1);
1168 1692
1169 seq_printf(s, "- DSI PLL -\n"); 1693 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
1170 1694
1171 seq_printf(s, "dsi pll source = %s\n", 1695 seq_printf(s, "dsi pll source = %s\n",
1172 clksel == 0 ? 1696 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree");
1173 "dss2_alwon_fclk" : "pclkfree");
1174 1697
1175 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1698 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
1176 1699
1177 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", 1700 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
1178 cinfo->clkin4ddr, cinfo->regm); 1701 cinfo->clkin4ddr, cinfo->regm);
1179 1702
1180 seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", 1703 seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
1181 cinfo->dsi1_pll_fclk, 1704 dss_get_generic_clk_source_name(dispc_clk_src),
1182 cinfo->regm3, 1705 dss_feat_get_clk_source_name(dispc_clk_src),
1183 dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1706 cinfo->dsi_pll_hsdiv_dispc_clk,
1707 cinfo->regm_dispc,
1708 dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
1184 "off" : "on"); 1709 "off" : "on");
1185 1710
1186 seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", 1711 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
1187 cinfo->dsi2_pll_fclk, 1712 dss_get_generic_clk_source_name(dsi_clk_src),
1188 cinfo->regm4, 1713 dss_feat_get_clk_source_name(dsi_clk_src),
1189 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1714 cinfo->dsi_pll_hsdiv_dsi_clk,
1715 cinfo->regm_dsi,
1716 dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
1190 "off" : "on"); 1717 "off" : "on");
1191 1718
1192 seq_printf(s, "- DSI -\n"); 1719 seq_printf(s, "- DSI%d -\n", dsi_module + 1);
1193 1720
1194 seq_printf(s, "dsi fclk source = %s\n", 1721 seq_printf(s, "dsi fclk source = %s (%s)\n",
1195 dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? 1722 dss_get_generic_clk_source_name(dsi_clk_src),
1196 "dss1_alwon_fclk" : "dsi2_pll_fclk"); 1723 dss_feat_get_clk_source_name(dsi_clk_src));
1197 1724
1198 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1725 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
1199 1726
1200 seq_printf(s, "DDR_CLK\t\t%lu\n", 1727 seq_printf(s, "DDR_CLK\t\t%lu\n",
1201 cinfo->clkin4ddr / 4); 1728 cinfo->clkin4ddr / 4);
1202 1729
1203 seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs()); 1730 seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
1204 1731
1205 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); 1732 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk);
1206 1733
1207 seq_printf(s, "VP_CLK\t\t%lu\n"
1208 "VP_PCLK\t\t%lu\n",
1209 dispc_lclk_rate(),
1210 dispc_pclk_rate());
1211
1212 enable_clocks(0); 1734 enable_clocks(0);
1213} 1735}
1214 1736
1737void dsi_dump_clocks(struct seq_file *s)
1738{
1739 struct platform_device *dsidev;
1740 int i;
1741
1742 for (i = 0; i < MAX_NUM_DSI; i++) {
1743 dsidev = dsi_get_dsidev_from_id(i);
1744 if (dsidev)
1745 dsi_dump_dsidev_clocks(dsidev, s);
1746 }
1747}
1748
1215#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 1749#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
1216void dsi_dump_irqs(struct seq_file *s) 1750static void dsi_dump_dsidev_irqs(struct platform_device *dsidev,
1751 struct seq_file *s)
1217{ 1752{
1753 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1218 unsigned long flags; 1754 unsigned long flags;
1219 struct dsi_irq_stats stats; 1755 struct dsi_irq_stats stats;
1756 int dsi_module = dsi_get_dsidev_id(dsidev);
1220 1757
1221 spin_lock_irqsave(&dsi.irq_stats_lock, flags); 1758 spin_lock_irqsave(&dsi->irq_stats_lock, flags);
1222 1759
1223 stats = dsi.irq_stats; 1760 stats = dsi->irq_stats;
1224 memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); 1761 memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats));
1225 dsi.irq_stats.last_reset = jiffies; 1762 dsi->irq_stats.last_reset = jiffies;
1226 1763
1227 spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); 1764 spin_unlock_irqrestore(&dsi->irq_stats_lock, flags);
1228 1765
1229 seq_printf(s, "period %u ms\n", 1766 seq_printf(s, "period %u ms\n",
1230 jiffies_to_msecs(jiffies - stats.last_reset)); 1767 jiffies_to_msecs(jiffies - stats.last_reset));
@@ -1233,7 +1770,7 @@ void dsi_dump_irqs(struct seq_file *s)
1233#define PIS(x) \ 1770#define PIS(x) \
1234 seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); 1771 seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
1235 1772
1236 seq_printf(s, "-- DSI interrupts --\n"); 1773 seq_printf(s, "-- DSI%d interrupts --\n", dsi_module + 1);
1237 PIS(VC0); 1774 PIS(VC0);
1238 PIS(VC1); 1775 PIS(VC1);
1239 PIS(VC2); 1776 PIS(VC2);
@@ -1299,13 +1836,45 @@ void dsi_dump_irqs(struct seq_file *s)
1299 PIS(ULPSACTIVENOT_ALL1); 1836 PIS(ULPSACTIVENOT_ALL1);
1300#undef PIS 1837#undef PIS
1301} 1838}
1839
1840static void dsi1_dump_irqs(struct seq_file *s)
1841{
1842 struct platform_device *dsidev = dsi_get_dsidev_from_id(0);
1843
1844 dsi_dump_dsidev_irqs(dsidev, s);
1845}
1846
1847static void dsi2_dump_irqs(struct seq_file *s)
1848{
1849 struct platform_device *dsidev = dsi_get_dsidev_from_id(1);
1850
1851 dsi_dump_dsidev_irqs(dsidev, s);
1852}
1853
1854void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
1855 const struct file_operations *debug_fops)
1856{
1857 struct platform_device *dsidev;
1858
1859 dsidev = dsi_get_dsidev_from_id(0);
1860 if (dsidev)
1861 debugfs_create_file("dsi1_irqs", S_IRUGO, debugfs_dir,
1862 &dsi1_dump_irqs, debug_fops);
1863
1864 dsidev = dsi_get_dsidev_from_id(1);
1865 if (dsidev)
1866 debugfs_create_file("dsi2_irqs", S_IRUGO, debugfs_dir,
1867 &dsi2_dump_irqs, debug_fops);
1868}
1302#endif 1869#endif
1303 1870
1304void dsi_dump_regs(struct seq_file *s) 1871static void dsi_dump_dsidev_regs(struct platform_device *dsidev,
1872 struct seq_file *s)
1305{ 1873{
1306#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) 1874#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r))
1307 1875
1308 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1876 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1877 dsi_enable_scp_clk(dsidev);
1309 1878
1310 DUMPREG(DSI_REVISION); 1879 DUMPREG(DSI_REVISION);
1311 DUMPREG(DSI_SYSCONFIG); 1880 DUMPREG(DSI_SYSCONFIG);
@@ -1377,25 +1946,57 @@ void dsi_dump_regs(struct seq_file *s)
1377 DUMPREG(DSI_PLL_CONFIGURATION1); 1946 DUMPREG(DSI_PLL_CONFIGURATION1);
1378 DUMPREG(DSI_PLL_CONFIGURATION2); 1947 DUMPREG(DSI_PLL_CONFIGURATION2);
1379 1948
1380 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1949 dsi_disable_scp_clk(dsidev);
1950 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1381#undef DUMPREG 1951#undef DUMPREG
1382} 1952}
1383 1953
1384enum dsi_complexio_power_state { 1954static void dsi1_dump_regs(struct seq_file *s)
1955{
1956 struct platform_device *dsidev = dsi_get_dsidev_from_id(0);
1957
1958 dsi_dump_dsidev_regs(dsidev, s);
1959}
1960
1961static void dsi2_dump_regs(struct seq_file *s)
1962{
1963 struct platform_device *dsidev = dsi_get_dsidev_from_id(1);
1964
1965 dsi_dump_dsidev_regs(dsidev, s);
1966}
1967
1968void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
1969 const struct file_operations *debug_fops)
1970{
1971 struct platform_device *dsidev;
1972
1973 dsidev = dsi_get_dsidev_from_id(0);
1974 if (dsidev)
1975 debugfs_create_file("dsi1_regs", S_IRUGO, debugfs_dir,
1976 &dsi1_dump_regs, debug_fops);
1977
1978 dsidev = dsi_get_dsidev_from_id(1);
1979 if (dsidev)
1980 debugfs_create_file("dsi2_regs", S_IRUGO, debugfs_dir,
1981 &dsi2_dump_regs, debug_fops);
1982}
1983enum dsi_cio_power_state {
1385 DSI_COMPLEXIO_POWER_OFF = 0x0, 1984 DSI_COMPLEXIO_POWER_OFF = 0x0,
1386 DSI_COMPLEXIO_POWER_ON = 0x1, 1985 DSI_COMPLEXIO_POWER_ON = 0x1,
1387 DSI_COMPLEXIO_POWER_ULPS = 0x2, 1986 DSI_COMPLEXIO_POWER_ULPS = 0x2,
1388}; 1987};
1389 1988
1390static int dsi_complexio_power(enum dsi_complexio_power_state state) 1989static int dsi_cio_power(struct platform_device *dsidev,
1990 enum dsi_cio_power_state state)
1391{ 1991{
1392 int t = 0; 1992 int t = 0;
1393 1993
1394 /* PWR_CMD */ 1994 /* PWR_CMD */
1395 REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27); 1995 REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, state, 28, 27);
1396 1996
1397 /* PWR_STATUS */ 1997 /* PWR_STATUS */
1398 while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { 1998 while (FLD_GET(dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1),
1999 26, 25) != state) {
1399 if (++t > 1000) { 2000 if (++t > 1000) {
1400 DSSERR("failed to set complexio power state to " 2001 DSSERR("failed to set complexio power state to "
1401 "%d\n", state); 2002 "%d\n", state);
@@ -1407,9 +2008,70 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state)
1407 return 0; 2008 return 0;
1408} 2009}
1409 2010
1410static void dsi_complexio_config(struct omap_dss_device *dssdev) 2011/* Number of data lanes present on DSI interface */
2012static inline int dsi_get_num_data_lanes(struct platform_device *dsidev)
1411{ 2013{
2014 /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
2015 * of data lanes as 2 by default */
2016 if (dss_has_feature(FEAT_DSI_GNQ))
2017 return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */
2018 else
2019 return 2;
2020}
2021
2022/* Number of data lanes used by the dss device */
2023static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
2024{
2025 int num_data_lanes = 0;
2026
2027 if (dssdev->phy.dsi.data1_lane != 0)
2028 num_data_lanes++;
2029 if (dssdev->phy.dsi.data2_lane != 0)
2030 num_data_lanes++;
2031 if (dssdev->phy.dsi.data3_lane != 0)
2032 num_data_lanes++;
2033 if (dssdev->phy.dsi.data4_lane != 0)
2034 num_data_lanes++;
2035
2036 return num_data_lanes;
2037}
2038
2039static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
2040{
2041 int val;
2042
2043 /* line buffer on OMAP3 is 1024 x 24bits */
2044 /* XXX: for some reason using full buffer size causes
2045 * considerable TX slowdown with update sizes that fill the
2046 * whole buffer */
2047 if (!dss_has_feature(FEAT_DSI_GNQ))
2048 return 1023 * 3;
2049
2050 val = REG_GET(dsidev, DSI_GNQ, 14, 12); /* VP1_LINE_BUFFER_SIZE */
2051
2052 switch (val) {
2053 case 1:
2054 return 512 * 3; /* 512x24 bits */
2055 case 2:
2056 return 682 * 3; /* 682x24 bits */
2057 case 3:
2058 return 853 * 3; /* 853x24 bits */
2059 case 4:
2060 return 1024 * 3; /* 1024x24 bits */
2061 case 5:
2062 return 1194 * 3; /* 1194x24 bits */
2063 case 6:
2064 return 1365 * 3; /* 1365x24 bits */
2065 default:
2066 BUG();
2067 }
2068}
2069
2070static void dsi_set_lane_config(struct omap_dss_device *dssdev)
2071{
2072 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1412 u32 r; 2073 u32 r;
2074 int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
1413 2075
1414 int clk_lane = dssdev->phy.dsi.clk_lane; 2076 int clk_lane = dssdev->phy.dsi.clk_lane;
1415 int data1_lane = dssdev->phy.dsi.data1_lane; 2077 int data1_lane = dssdev->phy.dsi.data1_lane;
@@ -1418,14 +2080,28 @@ static void dsi_complexio_config(struct omap_dss_device *dssdev)
1418 int data1_pol = dssdev->phy.dsi.data1_pol; 2080 int data1_pol = dssdev->phy.dsi.data1_pol;
1419 int data2_pol = dssdev->phy.dsi.data2_pol; 2081 int data2_pol = dssdev->phy.dsi.data2_pol;
1420 2082
1421 r = dsi_read_reg(DSI_COMPLEXIO_CFG1); 2083 r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
1422 r = FLD_MOD(r, clk_lane, 2, 0); 2084 r = FLD_MOD(r, clk_lane, 2, 0);
1423 r = FLD_MOD(r, clk_pol, 3, 3); 2085 r = FLD_MOD(r, clk_pol, 3, 3);
1424 r = FLD_MOD(r, data1_lane, 6, 4); 2086 r = FLD_MOD(r, data1_lane, 6, 4);
1425 r = FLD_MOD(r, data1_pol, 7, 7); 2087 r = FLD_MOD(r, data1_pol, 7, 7);
1426 r = FLD_MOD(r, data2_lane, 10, 8); 2088 r = FLD_MOD(r, data2_lane, 10, 8);
1427 r = FLD_MOD(r, data2_pol, 11, 11); 2089 r = FLD_MOD(r, data2_pol, 11, 11);
1428 dsi_write_reg(DSI_COMPLEXIO_CFG1, r); 2090 if (num_data_lanes_dssdev > 2) {
2091 int data3_lane = dssdev->phy.dsi.data3_lane;
2092 int data3_pol = dssdev->phy.dsi.data3_pol;
2093
2094 r = FLD_MOD(r, data3_lane, 14, 12);
2095 r = FLD_MOD(r, data3_pol, 15, 15);
2096 }
2097 if (num_data_lanes_dssdev > 3) {
2098 int data4_lane = dssdev->phy.dsi.data4_lane;
2099 int data4_pol = dssdev->phy.dsi.data4_pol;
2100
2101 r = FLD_MOD(r, data4_lane, 18, 16);
2102 r = FLD_MOD(r, data4_pol, 19, 19);
2103 }
2104 dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
1429 2105
1430 /* The configuration of the DSI complex I/O (number of data lanes, 2106 /* The configuration of the DSI complex I/O (number of data lanes,
1431 position, differential order) should not be changed while 2107 position, differential order) should not be changed while
@@ -1439,27 +2115,31 @@ static void dsi_complexio_config(struct omap_dss_device *dssdev)
1439 DSI complex I/O configuration is unknown. */ 2115 DSI complex I/O configuration is unknown. */
1440 2116
1441 /* 2117 /*
1442 REG_FLD_MOD(DSI_CTRL, 1, 0, 0); 2118 REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
1443 REG_FLD_MOD(DSI_CTRL, 0, 0, 0); 2119 REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
1444 REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); 2120 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
1445 REG_FLD_MOD(DSI_CTRL, 1, 0, 0); 2121 REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
1446 */ 2122 */
1447} 2123}
1448 2124
1449static inline unsigned ns2ddr(unsigned ns) 2125static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
1450{ 2126{
2127 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2128
1451 /* convert time in ns to ddr ticks, rounding up */ 2129 /* convert time in ns to ddr ticks, rounding up */
1452 unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; 2130 unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
1453 return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; 2131 return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
1454} 2132}
1455 2133
1456static inline unsigned ddr2ns(unsigned ddr) 2134static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
1457{ 2135{
1458 unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; 2136 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2137
2138 unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
1459 return ddr * 1000 * 1000 / (ddr_clk / 1000); 2139 return ddr * 1000 * 1000 / (ddr_clk / 1000);
1460} 2140}
1461 2141
1462static void dsi_complexio_timings(void) 2142static void dsi_cio_timings(struct platform_device *dsidev)
1463{ 2143{
1464 u32 r; 2144 u32 r;
1465 u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit; 2145 u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
@@ -1471,139 +2151,323 @@ static void dsi_complexio_timings(void)
1471 /* 1 * DDR_CLK = 2 * UI */ 2151 /* 1 * DDR_CLK = 2 * UI */
1472 2152
1473 /* min 40ns + 4*UI max 85ns + 6*UI */ 2153 /* min 40ns + 4*UI max 85ns + 6*UI */
1474 ths_prepare = ns2ddr(70) + 2; 2154 ths_prepare = ns2ddr(dsidev, 70) + 2;
1475 2155
1476 /* min 145ns + 10*UI */ 2156 /* min 145ns + 10*UI */
1477 ths_prepare_ths_zero = ns2ddr(175) + 2; 2157 ths_prepare_ths_zero = ns2ddr(dsidev, 175) + 2;
1478 2158
1479 /* min max(8*UI, 60ns+4*UI) */ 2159 /* min max(8*UI, 60ns+4*UI) */
1480 ths_trail = ns2ddr(60) + 5; 2160 ths_trail = ns2ddr(dsidev, 60) + 5;
1481 2161
1482 /* min 100ns */ 2162 /* min 100ns */
1483 ths_exit = ns2ddr(145); 2163 ths_exit = ns2ddr(dsidev, 145);
1484 2164
1485 /* tlpx min 50n */ 2165 /* tlpx min 50n */
1486 tlpx_half = ns2ddr(25); 2166 tlpx_half = ns2ddr(dsidev, 25);
1487 2167
1488 /* min 60ns */ 2168 /* min 60ns */
1489 tclk_trail = ns2ddr(60) + 2; 2169 tclk_trail = ns2ddr(dsidev, 60) + 2;
1490 2170
1491 /* min 38ns, max 95ns */ 2171 /* min 38ns, max 95ns */
1492 tclk_prepare = ns2ddr(65); 2172 tclk_prepare = ns2ddr(dsidev, 65);
1493 2173
1494 /* min tclk-prepare + tclk-zero = 300ns */ 2174 /* min tclk-prepare + tclk-zero = 300ns */
1495 tclk_zero = ns2ddr(260); 2175 tclk_zero = ns2ddr(dsidev, 260);
1496 2176
1497 DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n", 2177 DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n",
1498 ths_prepare, ddr2ns(ths_prepare), 2178 ths_prepare, ddr2ns(dsidev, ths_prepare),
1499 ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero)); 2179 ths_prepare_ths_zero, ddr2ns(dsidev, ths_prepare_ths_zero));
1500 DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n", 2180 DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n",
1501 ths_trail, ddr2ns(ths_trail), 2181 ths_trail, ddr2ns(dsidev, ths_trail),
1502 ths_exit, ddr2ns(ths_exit)); 2182 ths_exit, ddr2ns(dsidev, ths_exit));
1503 2183
1504 DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), " 2184 DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), "
1505 "tclk_zero %u (%uns)\n", 2185 "tclk_zero %u (%uns)\n",
1506 tlpx_half, ddr2ns(tlpx_half), 2186 tlpx_half, ddr2ns(dsidev, tlpx_half),
1507 tclk_trail, ddr2ns(tclk_trail), 2187 tclk_trail, ddr2ns(dsidev, tclk_trail),
1508 tclk_zero, ddr2ns(tclk_zero)); 2188 tclk_zero, ddr2ns(dsidev, tclk_zero));
1509 DSSDBG("tclk_prepare %u (%uns)\n", 2189 DSSDBG("tclk_prepare %u (%uns)\n",
1510 tclk_prepare, ddr2ns(tclk_prepare)); 2190 tclk_prepare, ddr2ns(dsidev, tclk_prepare));
1511 2191
1512 /* program timings */ 2192 /* program timings */
1513 2193
1514 r = dsi_read_reg(DSI_DSIPHY_CFG0); 2194 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
1515 r = FLD_MOD(r, ths_prepare, 31, 24); 2195 r = FLD_MOD(r, ths_prepare, 31, 24);
1516 r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16); 2196 r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
1517 r = FLD_MOD(r, ths_trail, 15, 8); 2197 r = FLD_MOD(r, ths_trail, 15, 8);
1518 r = FLD_MOD(r, ths_exit, 7, 0); 2198 r = FLD_MOD(r, ths_exit, 7, 0);
1519 dsi_write_reg(DSI_DSIPHY_CFG0, r); 2199 dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r);
1520 2200
1521 r = dsi_read_reg(DSI_DSIPHY_CFG1); 2201 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
1522 r = FLD_MOD(r, tlpx_half, 22, 16); 2202 r = FLD_MOD(r, tlpx_half, 22, 16);
1523 r = FLD_MOD(r, tclk_trail, 15, 8); 2203 r = FLD_MOD(r, tclk_trail, 15, 8);
1524 r = FLD_MOD(r, tclk_zero, 7, 0); 2204 r = FLD_MOD(r, tclk_zero, 7, 0);
1525 dsi_write_reg(DSI_DSIPHY_CFG1, r); 2205 dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r);
1526 2206
1527 r = dsi_read_reg(DSI_DSIPHY_CFG2); 2207 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
1528 r = FLD_MOD(r, tclk_prepare, 7, 0); 2208 r = FLD_MOD(r, tclk_prepare, 7, 0);
1529 dsi_write_reg(DSI_DSIPHY_CFG2, r); 2209 dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r);
2210}
2211
2212static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
2213 enum dsi_lane lanes)
2214{
2215 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2216 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2217 int clk_lane = dssdev->phy.dsi.clk_lane;
2218 int data1_lane = dssdev->phy.dsi.data1_lane;
2219 int data2_lane = dssdev->phy.dsi.data2_lane;
2220 int data3_lane = dssdev->phy.dsi.data3_lane;
2221 int data4_lane = dssdev->phy.dsi.data4_lane;
2222 int clk_pol = dssdev->phy.dsi.clk_pol;
2223 int data1_pol = dssdev->phy.dsi.data1_pol;
2224 int data2_pol = dssdev->phy.dsi.data2_pol;
2225 int data3_pol = dssdev->phy.dsi.data3_pol;
2226 int data4_pol = dssdev->phy.dsi.data4_pol;
2227
2228 u32 l = 0;
2229 u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26;
2230
2231 if (lanes & DSI_CLK_P)
2232 l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
2233 if (lanes & DSI_CLK_N)
2234 l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0));
2235
2236 if (lanes & DSI_DATA1_P)
2237 l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1));
2238 if (lanes & DSI_DATA1_N)
2239 l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0));
2240
2241 if (lanes & DSI_DATA2_P)
2242 l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1));
2243 if (lanes & DSI_DATA2_N)
2244 l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0));
2245
2246 if (lanes & DSI_DATA3_P)
2247 l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1));
2248 if (lanes & DSI_DATA3_N)
2249 l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0));
2250
2251 if (lanes & DSI_DATA4_P)
2252 l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1));
2253 if (lanes & DSI_DATA4_N)
2254 l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0));
2255 /*
2256 * Bits in REGLPTXSCPDAT4TO0DXDY:
2257 * 17: DY0 18: DX0
2258 * 19: DY1 20: DX1
2259 * 21: DY2 22: DX2
2260 * 23: DY3 24: DX3
2261 * 25: DY4 26: DX4
2262 */
2263
2264 /* Set the lane override configuration */
2265
2266 /* REGLPTXSCPDAT4TO0DXDY */
2267 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, l, lptxscp_start, 17);
2268
2269 /* Enable lane override */
2270
2271 /* ENLPTXSCPDAT */
2272 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 1, 27, 27);
1530} 2273}
1531 2274
2275static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
2276{
2277 /* Disable lane override */
2278 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */
2279 /* Reset the lane override configuration */
2280 /* REGLPTXSCPDAT4TO0DXDY */
2281 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17);
2282}
1532 2283
1533static int dsi_complexio_init(struct omap_dss_device *dssdev) 2284static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
1534{ 2285{
1535 int r = 0; 2286 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2287 int t;
2288 int bits[3];
2289 bool in_use[3];
2290
2291 if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
2292 bits[0] = 28;
2293 bits[1] = 27;
2294 bits[2] = 26;
2295 } else {
2296 bits[0] = 24;
2297 bits[1] = 25;
2298 bits[2] = 26;
2299 }
2300
2301 in_use[0] = false;
2302 in_use[1] = false;
2303 in_use[2] = false;
2304
2305 if (dssdev->phy.dsi.clk_lane != 0)
2306 in_use[dssdev->phy.dsi.clk_lane - 1] = true;
2307 if (dssdev->phy.dsi.data1_lane != 0)
2308 in_use[dssdev->phy.dsi.data1_lane - 1] = true;
2309 if (dssdev->phy.dsi.data2_lane != 0)
2310 in_use[dssdev->phy.dsi.data2_lane - 1] = true;
2311
2312 t = 100000;
2313 while (true) {
2314 u32 l;
2315 int i;
2316 int ok;
2317
2318 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
2319
2320 ok = 0;
2321 for (i = 0; i < 3; ++i) {
2322 if (!in_use[i] || (l & (1 << bits[i])))
2323 ok++;
2324 }
2325
2326 if (ok == 3)
2327 break;
2328
2329 if (--t == 0) {
2330 for (i = 0; i < 3; ++i) {
2331 if (!in_use[i] || (l & (1 << bits[i])))
2332 continue;
2333
2334 DSSERR("CIO TXCLKESC%d domain not coming " \
2335 "out of reset\n", i);
2336 }
2337 return -EIO;
2338 }
2339 }
2340
2341 return 0;
2342}
2343
2344static int dsi_cio_init(struct omap_dss_device *dssdev)
2345{
2346 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2347 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2348 int r;
2349 int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
2350 u32 l;
2351
2352 DSSDBGF();
1536 2353
1537 DSSDBG("dsi_complexio_init\n"); 2354 if (dsi->dsi_mux_pads)
2355 dsi->dsi_mux_pads(true);
1538 2356
1539 /* CIO_CLK_ICG, enable L3 clk to CIO */ 2357 dsi_enable_scp_clk(dsidev);
1540 REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14);
1541 2358
1542 /* A dummy read using the SCP interface to any DSIPHY register is 2359 /* A dummy read using the SCP interface to any DSIPHY register is
1543 * required after DSIPHY reset to complete the reset of the DSI complex 2360 * required after DSIPHY reset to complete the reset of the DSI complex
1544 * I/O. */ 2361 * I/O. */
1545 dsi_read_reg(DSI_DSIPHY_CFG5); 2362 dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
1546 2363
1547 if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) { 2364 if (wait_for_bit_change(dsidev, DSI_DSIPHY_CFG5, 30, 1) != 1) {
1548 DSSERR("ComplexIO PHY not coming out of reset.\n"); 2365 DSSERR("CIO SCP Clock domain not coming out of reset.\n");
1549 r = -ENODEV; 2366 r = -EIO;
1550 goto err; 2367 goto err_scp_clk_dom;
1551 } 2368 }
1552 2369
1553 dsi_complexio_config(dssdev); 2370 dsi_set_lane_config(dssdev);
2371
2372 /* set TX STOP MODE timer to maximum for this operation */
2373 l = dsi_read_reg(dsidev, DSI_TIMING1);
2374 l = FLD_MOD(l, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2375 l = FLD_MOD(l, 1, 14, 14); /* STOP_STATE_X16_IO */
2376 l = FLD_MOD(l, 1, 13, 13); /* STOP_STATE_X4_IO */
2377 l = FLD_MOD(l, 0x1fff, 12, 0); /* STOP_STATE_COUNTER_IO */
2378 dsi_write_reg(dsidev, DSI_TIMING1, l);
2379
2380 if (dsi->ulps_enabled) {
2381 u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P;
2382
2383 DSSDBG("manual ulps exit\n");
2384
2385 /* ULPS is exited by Mark-1 state for 1ms, followed by
2386 * stop state. DSS HW cannot do this via the normal
2387 * ULPS exit sequence, as after reset the DSS HW thinks
2388 * that we are not in ULPS mode, and refuses to send the
2389 * sequence. So we need to send the ULPS exit sequence
2390 * manually.
2391 */
2392
2393 if (num_data_lanes_dssdev > 2)
2394 lane_mask |= DSI_DATA3_P;
2395
2396 if (num_data_lanes_dssdev > 3)
2397 lane_mask |= DSI_DATA4_P;
1554 2398
1555 r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON); 2399 dsi_cio_enable_lane_override(dssdev, lane_mask);
2400 }
1556 2401
2402 r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
1557 if (r) 2403 if (r)
1558 goto err; 2404 goto err_cio_pwr;
1559 2405
1560 if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) { 2406 if (wait_for_bit_change(dsidev, DSI_COMPLEXIO_CFG1, 29, 1) != 1) {
1561 DSSERR("ComplexIO not coming out of reset.\n"); 2407 DSSERR("CIO PWR clock domain not coming out of reset.\n");
1562 r = -ENODEV; 2408 r = -ENODEV;
1563 goto err; 2409 goto err_cio_pwr_dom;
1564 } 2410 }
1565 2411
1566 if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) { 2412 dsi_if_enable(dsidev, true);
1567 DSSERR("ComplexIO LDO power down.\n"); 2413 dsi_if_enable(dsidev, false);
1568 r = -ENODEV; 2414 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
1569 goto err; 2415
2416 r = dsi_cio_wait_tx_clk_esc_reset(dssdev);
2417 if (r)
2418 goto err_tx_clk_esc_rst;
2419
2420 if (dsi->ulps_enabled) {
2421 /* Keep Mark-1 state for 1ms (as per DSI spec) */
2422 ktime_t wait = ns_to_ktime(1000 * 1000);
2423 set_current_state(TASK_UNINTERRUPTIBLE);
2424 schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
2425
2426 /* Disable the override. The lanes should be set to Mark-11
2427 * state by the HW */
2428 dsi_cio_disable_lane_override(dsidev);
1570 } 2429 }
1571 2430
1572 dsi_complexio_timings(); 2431 /* FORCE_TX_STOP_MODE_IO */
2432 REG_FLD_MOD(dsidev, DSI_TIMING1, 0, 15, 15);
1573 2433
1574 /* 2434 dsi_cio_timings(dsidev);
1575 The configuration of the DSI complex I/O (number of data lanes, 2435
1576 position, differential order) should not be changed while 2436 dsi->ulps_enabled = false;
1577 DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. For the
1578 hardware to recognize a new configuration of the complex I/O (done
1579 in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to follow
1580 this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, next
1581 reset the DSS.DSI_CTRL[0] IF_EN to 0, then set DSS.DSI_CLK_CTRL[20]
1582 LP_CLK_ENABLE to 1, and finally, set again the DSS.DSI_CTRL[0] IF_EN
1583 bit to 1. If the sequence is not followed, the DSi complex I/O
1584 configuration is undetermined.
1585 */
1586 dsi_if_enable(1);
1587 dsi_if_enable(0);
1588 REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
1589 dsi_if_enable(1);
1590 dsi_if_enable(0);
1591 2437
1592 DSSDBG("CIO init done\n"); 2438 DSSDBG("CIO init done\n");
1593err: 2439
2440 return 0;
2441
2442err_tx_clk_esc_rst:
2443 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 20, 20); /* LP_CLK_ENABLE */
2444err_cio_pwr_dom:
2445 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
2446err_cio_pwr:
2447 if (dsi->ulps_enabled)
2448 dsi_cio_disable_lane_override(dsidev);
2449err_scp_clk_dom:
2450 dsi_disable_scp_clk(dsidev);
2451 if (dsi->dsi_mux_pads)
2452 dsi->dsi_mux_pads(false);
1594 return r; 2453 return r;
1595} 2454}
1596 2455
1597static void dsi_complexio_uninit(void) 2456static void dsi_cio_uninit(struct platform_device *dsidev)
1598{ 2457{
1599 dsi_complexio_power(DSI_COMPLEXIO_POWER_OFF); 2458 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2459
2460 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
2461 dsi_disable_scp_clk(dsidev);
2462 if (dsi->dsi_mux_pads)
2463 dsi->dsi_mux_pads(false);
1600} 2464}
1601 2465
1602static int _dsi_wait_reset(void) 2466static int _dsi_wait_reset(struct platform_device *dsidev)
1603{ 2467{
1604 int t = 0; 2468 int t = 0;
1605 2469
1606 while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { 2470 while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
1607 if (++t > 5) { 2471 if (++t > 5) {
1608 DSSERR("soft reset failed\n"); 2472 DSSERR("soft reset failed\n");
1609 return -ENODEV; 2473 return -ENODEV;
@@ -1614,42 +2478,30 @@ static int _dsi_wait_reset(void)
1614 return 0; 2478 return 0;
1615} 2479}
1616 2480
1617static int _dsi_reset(void) 2481static int _dsi_reset(struct platform_device *dsidev)
1618{ 2482{
1619 /* Soft reset */ 2483 /* Soft reset */
1620 REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1); 2484 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
1621 return _dsi_wait_reset(); 2485 return _dsi_wait_reset(dsidev);
1622}
1623
1624static void dsi_reset_tx_fifo(int channel)
1625{
1626 u32 mask;
1627 u32 l;
1628
1629 /* set fifosize of the channel to 0, then return the old size */
1630 l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE);
1631
1632 mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4);
1633 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask);
1634
1635 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l);
1636} 2486}
1637 2487
1638static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, 2488static void dsi_config_tx_fifo(struct platform_device *dsidev,
2489 enum fifo_size size1, enum fifo_size size2,
1639 enum fifo_size size3, enum fifo_size size4) 2490 enum fifo_size size3, enum fifo_size size4)
1640{ 2491{
2492 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1641 u32 r = 0; 2493 u32 r = 0;
1642 int add = 0; 2494 int add = 0;
1643 int i; 2495 int i;
1644 2496
1645 dsi.vc[0].fifo_size = size1; 2497 dsi->vc[0].fifo_size = size1;
1646 dsi.vc[1].fifo_size = size2; 2498 dsi->vc[1].fifo_size = size2;
1647 dsi.vc[2].fifo_size = size3; 2499 dsi->vc[2].fifo_size = size3;
1648 dsi.vc[3].fifo_size = size4; 2500 dsi->vc[3].fifo_size = size4;
1649 2501
1650 for (i = 0; i < 4; i++) { 2502 for (i = 0; i < 4; i++) {
1651 u8 v; 2503 u8 v;
1652 int size = dsi.vc[i].fifo_size; 2504 int size = dsi->vc[i].fifo_size;
1653 2505
1654 if (add + size > 4) { 2506 if (add + size > 4) {
1655 DSSERR("Illegal FIFO configuration\n"); 2507 DSSERR("Illegal FIFO configuration\n");
@@ -1662,24 +2514,26 @@ static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
1662 add += size; 2514 add += size;
1663 } 2515 }
1664 2516
1665 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r); 2517 dsi_write_reg(dsidev, DSI_TX_FIFO_VC_SIZE, r);
1666} 2518}
1667 2519
1668static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2, 2520static void dsi_config_rx_fifo(struct platform_device *dsidev,
2521 enum fifo_size size1, enum fifo_size size2,
1669 enum fifo_size size3, enum fifo_size size4) 2522 enum fifo_size size3, enum fifo_size size4)
1670{ 2523{
2524 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1671 u32 r = 0; 2525 u32 r = 0;
1672 int add = 0; 2526 int add = 0;
1673 int i; 2527 int i;
1674 2528
1675 dsi.vc[0].fifo_size = size1; 2529 dsi->vc[0].fifo_size = size1;
1676 dsi.vc[1].fifo_size = size2; 2530 dsi->vc[1].fifo_size = size2;
1677 dsi.vc[2].fifo_size = size3; 2531 dsi->vc[2].fifo_size = size3;
1678 dsi.vc[3].fifo_size = size4; 2532 dsi->vc[3].fifo_size = size4;
1679 2533
1680 for (i = 0; i < 4; i++) { 2534 for (i = 0; i < 4; i++) {
1681 u8 v; 2535 u8 v;
1682 int size = dsi.vc[i].fifo_size; 2536 int size = dsi->vc[i].fifo_size;
1683 2537
1684 if (add + size > 4) { 2538 if (add + size > 4) {
1685 DSSERR("Illegal FIFO configuration\n"); 2539 DSSERR("Illegal FIFO configuration\n");
@@ -1692,18 +2546,18 @@ static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2,
1692 add += size; 2546 add += size;
1693 } 2547 }
1694 2548
1695 dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r); 2549 dsi_write_reg(dsidev, DSI_RX_FIFO_VC_SIZE, r);
1696} 2550}
1697 2551
1698static int dsi_force_tx_stop_mode_io(void) 2552static int dsi_force_tx_stop_mode_io(struct platform_device *dsidev)
1699{ 2553{
1700 u32 r; 2554 u32 r;
1701 2555
1702 r = dsi_read_reg(DSI_TIMING1); 2556 r = dsi_read_reg(dsidev, DSI_TIMING1);
1703 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ 2557 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
1704 dsi_write_reg(DSI_TIMING1, r); 2558 dsi_write_reg(dsidev, DSI_TIMING1, r);
1705 2559
1706 if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) { 2560 if (wait_for_bit_change(dsidev, DSI_TIMING1, 15, 0) != 0) {
1707 DSSERR("TX_STOP bit not going down\n"); 2561 DSSERR("TX_STOP bit not going down\n");
1708 return -EIO; 2562 return -EIO;
1709 } 2563 }
@@ -1711,16 +2565,135 @@ static int dsi_force_tx_stop_mode_io(void)
1711 return 0; 2565 return 0;
1712} 2566}
1713 2567
1714static int dsi_vc_enable(int channel, bool enable) 2568static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel)
2569{
2570 return REG_GET(dsidev, DSI_VC_CTRL(channel), 0, 0);
2571}
2572
2573static void dsi_packet_sent_handler_vp(void *data, u32 mask)
2574{
2575 struct dsi_packet_sent_handler_data *vp_data =
2576 (struct dsi_packet_sent_handler_data *) data;
2577 struct dsi_data *dsi = dsi_get_dsidrv_data(vp_data->dsidev);
2578 const int channel = dsi->update_channel;
2579 u8 bit = dsi->te_enabled ? 30 : 31;
2580
2581 if (REG_GET(vp_data->dsidev, DSI_VC_TE(channel), bit, bit) == 0)
2582 complete(vp_data->completion);
2583}
2584
2585static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel)
2586{
2587 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2588 DECLARE_COMPLETION_ONSTACK(completion);
2589 struct dsi_packet_sent_handler_data vp_data = { dsidev, &completion };
2590 int r = 0;
2591 u8 bit;
2592
2593 bit = dsi->te_enabled ? 30 : 31;
2594
2595 r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
2596 &vp_data, DSI_VC_IRQ_PACKET_SENT);
2597 if (r)
2598 goto err0;
2599
2600 /* Wait for completion only if TE_EN/TE_START is still set */
2601 if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit)) {
2602 if (wait_for_completion_timeout(&completion,
2603 msecs_to_jiffies(10)) == 0) {
2604 DSSERR("Failed to complete previous frame transfer\n");
2605 r = -EIO;
2606 goto err1;
2607 }
2608 }
2609
2610 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
2611 &vp_data, DSI_VC_IRQ_PACKET_SENT);
2612
2613 return 0;
2614err1:
2615 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
2616 &vp_data, DSI_VC_IRQ_PACKET_SENT);
2617err0:
2618 return r;
2619}
2620
2621static void dsi_packet_sent_handler_l4(void *data, u32 mask)
2622{
2623 struct dsi_packet_sent_handler_data *l4_data =
2624 (struct dsi_packet_sent_handler_data *) data;
2625 struct dsi_data *dsi = dsi_get_dsidrv_data(l4_data->dsidev);
2626 const int channel = dsi->update_channel;
2627
2628 if (REG_GET(l4_data->dsidev, DSI_VC_CTRL(channel), 5, 5) == 0)
2629 complete(l4_data->completion);
2630}
2631
2632static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel)
2633{
2634 DECLARE_COMPLETION_ONSTACK(completion);
2635 struct dsi_packet_sent_handler_data l4_data = { dsidev, &completion };
2636 int r = 0;
2637
2638 r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
2639 &l4_data, DSI_VC_IRQ_PACKET_SENT);
2640 if (r)
2641 goto err0;
2642
2643 /* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */
2644 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5)) {
2645 if (wait_for_completion_timeout(&completion,
2646 msecs_to_jiffies(10)) == 0) {
2647 DSSERR("Failed to complete previous l4 transfer\n");
2648 r = -EIO;
2649 goto err1;
2650 }
2651 }
2652
2653 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
2654 &l4_data, DSI_VC_IRQ_PACKET_SENT);
2655
2656 return 0;
2657err1:
2658 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
2659 &l4_data, DSI_VC_IRQ_PACKET_SENT);
2660err0:
2661 return r;
2662}
2663
2664static int dsi_sync_vc(struct platform_device *dsidev, int channel)
2665{
2666 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2667
2668 WARN_ON(!dsi_bus_is_locked(dsidev));
2669
2670 WARN_ON(in_interrupt());
2671
2672 if (!dsi_vc_is_enabled(dsidev, channel))
2673 return 0;
2674
2675 switch (dsi->vc[channel].mode) {
2676 case DSI_VC_MODE_VP:
2677 return dsi_sync_vc_vp(dsidev, channel);
2678 case DSI_VC_MODE_L4:
2679 return dsi_sync_vc_l4(dsidev, channel);
2680 default:
2681 BUG();
2682 }
2683}
2684
2685static int dsi_vc_enable(struct platform_device *dsidev, int channel,
2686 bool enable)
1715{ 2687{
1716 DSSDBG("dsi_vc_enable channel %d, enable %d\n", 2688 DSSDBG("dsi_vc_enable channel %d, enable %d\n",
1717 channel, enable); 2689 channel, enable);
1718 2690
1719 enable = enable ? 1 : 0; 2691 enable = enable ? 1 : 0;
1720 2692
1721 REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0); 2693 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 0, 0);
1722 2694
1723 if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) { 2695 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel),
2696 0, enable) != enable) {
1724 DSSERR("Failed to set dsi_vc_enable to %d\n", enable); 2697 DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
1725 return -EIO; 2698 return -EIO;
1726 } 2699 }
@@ -1728,13 +2701,13 @@ static int dsi_vc_enable(int channel, bool enable)
1728 return 0; 2701 return 0;
1729} 2702}
1730 2703
1731static void dsi_vc_initial_config(int channel) 2704static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
1732{ 2705{
1733 u32 r; 2706 u32 r;
1734 2707
1735 DSSDBGF("%d", channel); 2708 DSSDBGF("%d", channel);
1736 2709
1737 r = dsi_read_reg(DSI_VC_CTRL(channel)); 2710 r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
1738 2711
1739 if (FLD_GET(r, 15, 15)) /* VC_BUSY */ 2712 if (FLD_GET(r, 15, 15)) /* VC_BUSY */
1740 DSSERR("VC(%d) busy when trying to configure it!\n", 2713 DSSERR("VC(%d) busy when trying to configure it!\n",
@@ -1747,87 +2720,107 @@ static void dsi_vc_initial_config(int channel)
1747 r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ 2720 r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
1748 r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ 2721 r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
1749 r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */ 2722 r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
2723 if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
2724 r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
1750 2725
1751 r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ 2726 r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
1752 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2727 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
1753 2728
1754 dsi_write_reg(DSI_VC_CTRL(channel), r); 2729 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r);
1755
1756 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1757} 2730}
1758 2731
1759static int dsi_vc_config_l4(int channel) 2732static int dsi_vc_config_l4(struct platform_device *dsidev, int channel)
1760{ 2733{
1761 if (dsi.vc[channel].mode == DSI_VC_MODE_L4) 2734 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2735
2736 if (dsi->vc[channel].mode == DSI_VC_MODE_L4)
1762 return 0; 2737 return 0;
1763 2738
1764 DSSDBGF("%d", channel); 2739 DSSDBGF("%d", channel);
1765 2740
1766 dsi_vc_enable(channel, 0); 2741 dsi_sync_vc(dsidev, channel);
2742
2743 dsi_vc_enable(dsidev, channel, 0);
1767 2744
1768 /* VC_BUSY */ 2745 /* VC_BUSY */
1769 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) { 2746 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
1770 DSSERR("vc(%d) busy when trying to config for L4\n", channel); 2747 DSSERR("vc(%d) busy when trying to config for L4\n", channel);
1771 return -EIO; 2748 return -EIO;
1772 } 2749 }
1773 2750
1774 REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ 2751 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
2752
2753 /* DCS_CMD_ENABLE */
2754 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
2755 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 30, 30);
1775 2756
1776 dsi_vc_enable(channel, 1); 2757 dsi_vc_enable(dsidev, channel, 1);
1777 2758
1778 dsi.vc[channel].mode = DSI_VC_MODE_L4; 2759 dsi->vc[channel].mode = DSI_VC_MODE_L4;
1779 2760
1780 return 0; 2761 return 0;
1781} 2762}
1782 2763
1783static int dsi_vc_config_vp(int channel) 2764static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
1784{ 2765{
1785 if (dsi.vc[channel].mode == DSI_VC_MODE_VP) 2766 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2767
2768 if (dsi->vc[channel].mode == DSI_VC_MODE_VP)
1786 return 0; 2769 return 0;
1787 2770
1788 DSSDBGF("%d", channel); 2771 DSSDBGF("%d", channel);
1789 2772
1790 dsi_vc_enable(channel, 0); 2773 dsi_sync_vc(dsidev, channel);
2774
2775 dsi_vc_enable(dsidev, channel, 0);
1791 2776
1792 /* VC_BUSY */ 2777 /* VC_BUSY */
1793 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) { 2778 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
1794 DSSERR("vc(%d) busy when trying to config for VP\n", channel); 2779 DSSERR("vc(%d) busy when trying to config for VP\n", channel);
1795 return -EIO; 2780 return -EIO;
1796 } 2781 }
1797 2782
1798 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */ 2783 /* SOURCE, 1 = video port */
2784 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 1, 1);
2785
2786 /* DCS_CMD_ENABLE */
2787 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
2788 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 30, 30);
1799 2789
1800 dsi_vc_enable(channel, 1); 2790 dsi_vc_enable(dsidev, channel, 1);
1801 2791
1802 dsi.vc[channel].mode = DSI_VC_MODE_VP; 2792 dsi->vc[channel].mode = DSI_VC_MODE_VP;
1803 2793
1804 return 0; 2794 return 0;
1805} 2795}
1806 2796
1807 2797
1808void omapdss_dsi_vc_enable_hs(int channel, bool enable) 2798void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
2799 bool enable)
1809{ 2800{
2801 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2802
1810 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); 2803 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
1811 2804
1812 WARN_ON(!dsi_bus_is_locked()); 2805 WARN_ON(!dsi_bus_is_locked(dsidev));
1813 2806
1814 dsi_vc_enable(channel, 0); 2807 dsi_vc_enable(dsidev, channel, 0);
1815 dsi_if_enable(0); 2808 dsi_if_enable(dsidev, 0);
1816 2809
1817 REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9); 2810 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 9, 9);
1818 2811
1819 dsi_vc_enable(channel, 1); 2812 dsi_vc_enable(dsidev, channel, 1);
1820 dsi_if_enable(1); 2813 dsi_if_enable(dsidev, 1);
1821 2814
1822 dsi_force_tx_stop_mode_io(); 2815 dsi_force_tx_stop_mode_io(dsidev);
1823} 2816}
1824EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); 2817EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
1825 2818
1826static void dsi_vc_flush_long_data(int channel) 2819static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel)
1827{ 2820{
1828 while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2821 while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
1829 u32 val; 2822 u32 val;
1830 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2823 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
1831 DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n", 2824 DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
1832 (val >> 0) & 0xff, 2825 (val >> 0) & 0xff,
1833 (val >> 8) & 0xff, 2826 (val >> 8) & 0xff,
@@ -1873,13 +2866,14 @@ static void dsi_show_rx_ack_with_err(u16 err)
1873 DSSERR("\t\tDSI Protocol Violation\n"); 2866 DSSERR("\t\tDSI Protocol Violation\n");
1874} 2867}
1875 2868
1876static u16 dsi_vc_flush_receive_data(int channel) 2869static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
2870 int channel)
1877{ 2871{
1878 /* RX_FIFO_NOT_EMPTY */ 2872 /* RX_FIFO_NOT_EMPTY */
1879 while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2873 while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
1880 u32 val; 2874 u32 val;
1881 u8 dt; 2875 u8 dt;
1882 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2876 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
1883 DSSERR("\trawval %#08x\n", val); 2877 DSSERR("\trawval %#08x\n", val);
1884 dt = FLD_GET(val, 5, 0); 2878 dt = FLD_GET(val, 5, 0);
1885 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 2879 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
@@ -1894,7 +2888,7 @@ static u16 dsi_vc_flush_receive_data(int channel)
1894 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 2888 } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
1895 DSSERR("\tDCS long response, len %d\n", 2889 DSSERR("\tDCS long response, len %d\n",
1896 FLD_GET(val, 23, 8)); 2890 FLD_GET(val, 23, 8));
1897 dsi_vc_flush_long_data(channel); 2891 dsi_vc_flush_long_data(dsidev, channel);
1898 } else { 2892 } else {
1899 DSSERR("\tunknown datatype 0x%02x\n", dt); 2893 DSSERR("\tunknown datatype 0x%02x\n", dt);
1900 } 2894 }
@@ -1902,74 +2896,90 @@ static u16 dsi_vc_flush_receive_data(int channel)
1902 return 0; 2896 return 0;
1903} 2897}
1904 2898
1905static int dsi_vc_send_bta(int channel) 2899static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
1906{ 2900{
1907 if (dsi.debug_write || dsi.debug_read) 2901 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2902
2903 if (dsi->debug_write || dsi->debug_read)
1908 DSSDBG("dsi_vc_send_bta %d\n", channel); 2904 DSSDBG("dsi_vc_send_bta %d\n", channel);
1909 2905
1910 WARN_ON(!dsi_bus_is_locked()); 2906 WARN_ON(!dsi_bus_is_locked(dsidev));
1911 2907
1912 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 2908 /* RX_FIFO_NOT_EMPTY */
2909 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
1913 DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); 2910 DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
1914 dsi_vc_flush_receive_data(channel); 2911 dsi_vc_flush_receive_data(dsidev, channel);
1915 } 2912 }
1916 2913
1917 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */ 2914 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
1918 2915
1919 return 0; 2916 return 0;
1920} 2917}
1921 2918
1922int dsi_vc_send_bta_sync(int channel) 2919int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
1923{ 2920{
2921 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2922 DECLARE_COMPLETION_ONSTACK(completion);
1924 int r = 0; 2923 int r = 0;
1925 u32 err; 2924 u32 err;
1926 2925
1927 INIT_COMPLETION(dsi.bta_completion); 2926 r = dsi_register_isr_vc(dsidev, channel, dsi_completion_handler,
2927 &completion, DSI_VC_IRQ_BTA);
2928 if (r)
2929 goto err0;
1928 2930
1929 dsi_vc_enable_bta_irq(channel); 2931 r = dsi_register_isr(dsidev, dsi_completion_handler, &completion,
2932 DSI_IRQ_ERROR_MASK);
2933 if (r)
2934 goto err1;
1930 2935
1931 r = dsi_vc_send_bta(channel); 2936 r = dsi_vc_send_bta(dsidev, channel);
1932 if (r) 2937 if (r)
1933 goto err; 2938 goto err2;
1934 2939
1935 if (wait_for_completion_timeout(&dsi.bta_completion, 2940 if (wait_for_completion_timeout(&completion,
1936 msecs_to_jiffies(500)) == 0) { 2941 msecs_to_jiffies(500)) == 0) {
1937 DSSERR("Failed to receive BTA\n"); 2942 DSSERR("Failed to receive BTA\n");
1938 r = -EIO; 2943 r = -EIO;
1939 goto err; 2944 goto err2;
1940 } 2945 }
1941 2946
1942 err = dsi_get_errors(); 2947 err = dsi_get_errors(dsidev);
1943 if (err) { 2948 if (err) {
1944 DSSERR("Error while sending BTA: %x\n", err); 2949 DSSERR("Error while sending BTA: %x\n", err);
1945 r = -EIO; 2950 r = -EIO;
1946 goto err; 2951 goto err2;
1947 } 2952 }
1948err: 2953err2:
1949 dsi_vc_disable_bta_irq(channel); 2954 dsi_unregister_isr(dsidev, dsi_completion_handler, &completion,
1950 2955 DSI_IRQ_ERROR_MASK);
2956err1:
2957 dsi_unregister_isr_vc(dsidev, channel, dsi_completion_handler,
2958 &completion, DSI_VC_IRQ_BTA);
2959err0:
1951 return r; 2960 return r;
1952} 2961}
1953EXPORT_SYMBOL(dsi_vc_send_bta_sync); 2962EXPORT_SYMBOL(dsi_vc_send_bta_sync);
1954 2963
1955static inline void dsi_vc_write_long_header(int channel, u8 data_type, 2964static inline void dsi_vc_write_long_header(struct platform_device *dsidev,
1956 u16 len, u8 ecc) 2965 int channel, u8 data_type, u16 len, u8 ecc)
1957{ 2966{
2967 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1958 u32 val; 2968 u32 val;
1959 u8 data_id; 2969 u8 data_id;
1960 2970
1961 WARN_ON(!dsi_bus_is_locked()); 2971 WARN_ON(!dsi_bus_is_locked(dsidev));
1962 2972
1963 data_id = data_type | channel << 6; 2973 data_id = data_type | dsi->vc[channel].vc_id << 6;
1964 2974
1965 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 2975 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
1966 FLD_VAL(ecc, 31, 24); 2976 FLD_VAL(ecc, 31, 24);
1967 2977
1968 dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val); 2978 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(channel), val);
1969} 2979}
1970 2980
1971static inline void dsi_vc_write_long_payload(int channel, 2981static inline void dsi_vc_write_long_payload(struct platform_device *dsidev,
1972 u8 b1, u8 b2, u8 b3, u8 b4) 2982 int channel, u8 b1, u8 b2, u8 b3, u8 b4)
1973{ 2983{
1974 u32 val; 2984 u32 val;
1975 2985
@@ -1978,34 +2988,35 @@ static inline void dsi_vc_write_long_payload(int channel,
1978/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n", 2988/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
1979 b1, b2, b3, b4, val); */ 2989 b1, b2, b3, b4, val); */
1980 2990
1981 dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val); 2991 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
1982} 2992}
1983 2993
1984static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, 2994static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
1985 u8 ecc) 2995 u8 data_type, u8 *data, u16 len, u8 ecc)
1986{ 2996{
1987 /*u32 val; */ 2997 /*u32 val; */
2998 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1988 int i; 2999 int i;
1989 u8 *p; 3000 u8 *p;
1990 int r = 0; 3001 int r = 0;
1991 u8 b1, b2, b3, b4; 3002 u8 b1, b2, b3, b4;
1992 3003
1993 if (dsi.debug_write) 3004 if (dsi->debug_write)
1994 DSSDBG("dsi_vc_send_long, %d bytes\n", len); 3005 DSSDBG("dsi_vc_send_long, %d bytes\n", len);
1995 3006
1996 /* len + header */ 3007 /* len + header */
1997 if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) { 3008 if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
1998 DSSERR("unable to send long packet: packet too long.\n"); 3009 DSSERR("unable to send long packet: packet too long.\n");
1999 return -EINVAL; 3010 return -EINVAL;
2000 } 3011 }
2001 3012
2002 dsi_vc_config_l4(channel); 3013 dsi_vc_config_l4(dsidev, channel);
2003 3014
2004 dsi_vc_write_long_header(channel, data_type, len, ecc); 3015 dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc);
2005 3016
2006 p = data; 3017 p = data;
2007 for (i = 0; i < len >> 2; i++) { 3018 for (i = 0; i < len >> 2; i++) {
2008 if (dsi.debug_write) 3019 if (dsi->debug_write)
2009 DSSDBG("\tsending full packet %d\n", i); 3020 DSSDBG("\tsending full packet %d\n", i);
2010 3021
2011 b1 = *p++; 3022 b1 = *p++;
@@ -2013,14 +3024,14 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2013 b3 = *p++; 3024 b3 = *p++;
2014 b4 = *p++; 3025 b4 = *p++;
2015 3026
2016 dsi_vc_write_long_payload(channel, b1, b2, b3, b4); 3027 dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, b4);
2017 } 3028 }
2018 3029
2019 i = len % 4; 3030 i = len % 4;
2020 if (i) { 3031 if (i) {
2021 b1 = 0; b2 = 0; b3 = 0; 3032 b1 = 0; b2 = 0; b3 = 0;
2022 3033
2023 if (dsi.debug_write) 3034 if (dsi->debug_write)
2024 DSSDBG("\tsending remainder bytes %d\n", i); 3035 DSSDBG("\tsending remainder bytes %d\n", i);
2025 3036
2026 switch (i) { 3037 switch (i) {
@@ -2038,62 +3049,69 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2038 break; 3049 break;
2039 } 3050 }
2040 3051
2041 dsi_vc_write_long_payload(channel, b1, b2, b3, 0); 3052 dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, 0);
2042 } 3053 }
2043 3054
2044 return r; 3055 return r;
2045} 3056}
2046 3057
2047static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) 3058static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
3059 u8 data_type, u16 data, u8 ecc)
2048{ 3060{
3061 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2049 u32 r; 3062 u32 r;
2050 u8 data_id; 3063 u8 data_id;
2051 3064
2052 WARN_ON(!dsi_bus_is_locked()); 3065 WARN_ON(!dsi_bus_is_locked(dsidev));
2053 3066
2054 if (dsi.debug_write) 3067 if (dsi->debug_write)
2055 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", 3068 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
2056 channel, 3069 channel,
2057 data_type, data & 0xff, (data >> 8) & 0xff); 3070 data_type, data & 0xff, (data >> 8) & 0xff);
2058 3071
2059 dsi_vc_config_l4(channel); 3072 dsi_vc_config_l4(dsidev, channel);
2060 3073
2061 if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) { 3074 if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) {
2062 DSSERR("ERROR FIFO FULL, aborting transfer\n"); 3075 DSSERR("ERROR FIFO FULL, aborting transfer\n");
2063 return -EINVAL; 3076 return -EINVAL;
2064 } 3077 }
2065 3078
2066 data_id = data_type | channel << 6; 3079 data_id = data_type | dsi->vc[channel].vc_id << 6;
2067 3080
2068 r = (data_id << 0) | (data << 8) | (ecc << 24); 3081 r = (data_id << 0) | (data << 8) | (ecc << 24);
2069 3082
2070 dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r); 3083 dsi_write_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel), r);
2071 3084
2072 return 0; 3085 return 0;
2073} 3086}
2074 3087
2075int dsi_vc_send_null(int channel) 3088int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
2076{ 3089{
3090 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2077 u8 nullpkg[] = {0, 0, 0, 0}; 3091 u8 nullpkg[] = {0, 0, 0, 0};
2078 return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0); 3092
3093 return dsi_vc_send_long(dsidev, channel, DSI_DT_NULL_PACKET, nullpkg,
3094 4, 0);
2079} 3095}
2080EXPORT_SYMBOL(dsi_vc_send_null); 3096EXPORT_SYMBOL(dsi_vc_send_null);
2081 3097
2082int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len) 3098int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
3099 u8 *data, int len)
2083{ 3100{
3101 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2084 int r; 3102 int r;
2085 3103
2086 BUG_ON(len == 0); 3104 BUG_ON(len == 0);
2087 3105
2088 if (len == 1) { 3106 if (len == 1) {
2089 r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0, 3107 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0,
2090 data[0], 0); 3108 data[0], 0);
2091 } else if (len == 2) { 3109 } else if (len == 2) {
2092 r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1, 3110 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1,
2093 data[0] | (data[1] << 8), 0); 3111 data[0] | (data[1] << 8), 0);
2094 } else { 3112 } else {
2095 /* 0x39 = DCS Long Write */ 3113 /* 0x39 = DCS Long Write */
2096 r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE, 3114 r = dsi_vc_send_long(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
2097 data, len, 0); 3115 data, len, 0);
2098 } 3116 }
2099 3117
@@ -2101,21 +3119,24 @@ int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len)
2101} 3119}
2102EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); 3120EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
2103 3121
2104int dsi_vc_dcs_write(int channel, u8 *data, int len) 3122int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
3123 int len)
2105{ 3124{
3125 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2106 int r; 3126 int r;
2107 3127
2108 r = dsi_vc_dcs_write_nosync(channel, data, len); 3128 r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len);
2109 if (r) 3129 if (r)
2110 goto err; 3130 goto err;
2111 3131
2112 r = dsi_vc_send_bta_sync(channel); 3132 r = dsi_vc_send_bta_sync(dssdev, channel);
2113 if (r) 3133 if (r)
2114 goto err; 3134 goto err;
2115 3135
2116 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 3136 /* RX_FIFO_NOT_EMPTY */
3137 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
2117 DSSERR("rx fifo not empty after write, dumping data:\n"); 3138 DSSERR("rx fifo not empty after write, dumping data:\n");
2118 dsi_vc_flush_receive_data(channel); 3139 dsi_vc_flush_receive_data(dsidev, channel);
2119 r = -EIO; 3140 r = -EIO;
2120 goto err; 3141 goto err;
2121 } 3142 }
@@ -2128,47 +3149,51 @@ err:
2128} 3149}
2129EXPORT_SYMBOL(dsi_vc_dcs_write); 3150EXPORT_SYMBOL(dsi_vc_dcs_write);
2130 3151
2131int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd) 3152int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd)
2132{ 3153{
2133 return dsi_vc_dcs_write(channel, &dcs_cmd, 1); 3154 return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1);
2134} 3155}
2135EXPORT_SYMBOL(dsi_vc_dcs_write_0); 3156EXPORT_SYMBOL(dsi_vc_dcs_write_0);
2136 3157
2137int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param) 3158int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3159 u8 param)
2138{ 3160{
2139 u8 buf[2]; 3161 u8 buf[2];
2140 buf[0] = dcs_cmd; 3162 buf[0] = dcs_cmd;
2141 buf[1] = param; 3163 buf[1] = param;
2142 return dsi_vc_dcs_write(channel, buf, 2); 3164 return dsi_vc_dcs_write(dssdev, channel, buf, 2);
2143} 3165}
2144EXPORT_SYMBOL(dsi_vc_dcs_write_1); 3166EXPORT_SYMBOL(dsi_vc_dcs_write_1);
2145 3167
2146int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) 3168int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3169 u8 *buf, int buflen)
2147{ 3170{
3171 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3172 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2148 u32 val; 3173 u32 val;
2149 u8 dt; 3174 u8 dt;
2150 int r; 3175 int r;
2151 3176
2152 if (dsi.debug_read) 3177 if (dsi->debug_read)
2153 DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); 3178 DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
2154 3179
2155 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); 3180 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0);
2156 if (r) 3181 if (r)
2157 goto err; 3182 goto err;
2158 3183
2159 r = dsi_vc_send_bta_sync(channel); 3184 r = dsi_vc_send_bta_sync(dssdev, channel);
2160 if (r) 3185 if (r)
2161 goto err; 3186 goto err;
2162 3187
2163 /* RX_FIFO_NOT_EMPTY */ 3188 /* RX_FIFO_NOT_EMPTY */
2164 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { 3189 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) {
2165 DSSERR("RX fifo empty when trying to read.\n"); 3190 DSSERR("RX fifo empty when trying to read.\n");
2166 r = -EIO; 3191 r = -EIO;
2167 goto err; 3192 goto err;
2168 } 3193 }
2169 3194
2170 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 3195 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
2171 if (dsi.debug_read) 3196 if (dsi->debug_read)
2172 DSSDBG("\theader: %08x\n", val); 3197 DSSDBG("\theader: %08x\n", val);
2173 dt = FLD_GET(val, 5, 0); 3198 dt = FLD_GET(val, 5, 0);
2174 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 3199 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
@@ -2179,7 +3204,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2179 3204
2180 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 3205 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
2181 u8 data = FLD_GET(val, 15, 8); 3206 u8 data = FLD_GET(val, 15, 8);
2182 if (dsi.debug_read) 3207 if (dsi->debug_read)
2183 DSSDBG("\tDCS short response, 1 byte: %02x\n", data); 3208 DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
2184 3209
2185 if (buflen < 1) { 3210 if (buflen < 1) {
@@ -2192,7 +3217,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2192 return 1; 3217 return 1;
2193 } else if (dt == DSI_DT_RX_SHORT_READ_2) { 3218 } else if (dt == DSI_DT_RX_SHORT_READ_2) {
2194 u16 data = FLD_GET(val, 23, 8); 3219 u16 data = FLD_GET(val, 23, 8);
2195 if (dsi.debug_read) 3220 if (dsi->debug_read)
2196 DSSDBG("\tDCS short response, 2 byte: %04x\n", data); 3221 DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
2197 3222
2198 if (buflen < 2) { 3223 if (buflen < 2) {
@@ -2207,7 +3232,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2207 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 3232 } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
2208 int w; 3233 int w;
2209 int len = FLD_GET(val, 23, 8); 3234 int len = FLD_GET(val, 23, 8);
2210 if (dsi.debug_read) 3235 if (dsi->debug_read)
2211 DSSDBG("\tDCS long response, len %d\n", len); 3236 DSSDBG("\tDCS long response, len %d\n", len);
2212 3237
2213 if (len > buflen) { 3238 if (len > buflen) {
@@ -2218,8 +3243,9 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2218 /* two byte checksum ends the packet, not included in len */ 3243 /* two byte checksum ends the packet, not included in len */
2219 for (w = 0; w < len + 2;) { 3244 for (w = 0; w < len + 2;) {
2220 int b; 3245 int b;
2221 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 3246 val = dsi_read_reg(dsidev,
2222 if (dsi.debug_read) 3247 DSI_VC_SHORT_PACKET_HEADER(channel));
3248 if (dsi->debug_read)
2223 DSSDBG("\t\t%02x %02x %02x %02x\n", 3249 DSSDBG("\t\t%02x %02x %02x %02x\n",
2224 (val >> 0) & 0xff, 3250 (val >> 0) & 0xff,
2225 (val >> 8) & 0xff, 3251 (val >> 8) & 0xff,
@@ -2250,11 +3276,12 @@ err:
2250} 3276}
2251EXPORT_SYMBOL(dsi_vc_dcs_read); 3277EXPORT_SYMBOL(dsi_vc_dcs_read);
2252 3278
2253int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) 3279int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3280 u8 *data)
2254{ 3281{
2255 int r; 3282 int r;
2256 3283
2257 r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1); 3284 r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, data, 1);
2258 3285
2259 if (r < 0) 3286 if (r < 0)
2260 return r; 3287 return r;
@@ -2266,12 +3293,13 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2266} 3293}
2267EXPORT_SYMBOL(dsi_vc_dcs_read_1); 3294EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2268 3295
2269int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2) 3296int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3297 u8 *data1, u8 *data2)
2270{ 3298{
2271 u8 buf[2]; 3299 u8 buf[2];
2272 int r; 3300 int r;
2273 3301
2274 r = dsi_vc_dcs_read(channel, dcs_cmd, buf, 2); 3302 r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, buf, 2);
2275 3303
2276 if (r < 0) 3304 if (r < 0)
2277 return r; 3305 return r;
@@ -2286,14 +3314,94 @@ int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2)
2286} 3314}
2287EXPORT_SYMBOL(dsi_vc_dcs_read_2); 3315EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2288 3316
2289int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 3317int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
3318 u16 len)
2290{ 3319{
2291 return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE, 3320 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3321
3322 return dsi_vc_send_short(dsidev, channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
2292 len, 0); 3323 len, 0);
2293} 3324}
2294EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); 3325EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
2295 3326
2296static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16) 3327static int dsi_enter_ulps(struct platform_device *dsidev)
3328{
3329 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3330 DECLARE_COMPLETION_ONSTACK(completion);
3331 int r;
3332
3333 DSSDBGF();
3334
3335 WARN_ON(!dsi_bus_is_locked(dsidev));
3336
3337 WARN_ON(dsi->ulps_enabled);
3338
3339 if (dsi->ulps_enabled)
3340 return 0;
3341
3342 if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
3343 DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n");
3344 return -EIO;
3345 }
3346
3347 dsi_sync_vc(dsidev, 0);
3348 dsi_sync_vc(dsidev, 1);
3349 dsi_sync_vc(dsidev, 2);
3350 dsi_sync_vc(dsidev, 3);
3351
3352 dsi_force_tx_stop_mode_io(dsidev);
3353
3354 dsi_vc_enable(dsidev, 0, false);
3355 dsi_vc_enable(dsidev, 1, false);
3356 dsi_vc_enable(dsidev, 2, false);
3357 dsi_vc_enable(dsidev, 3, false);
3358
3359 if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 16, 16)) { /* HS_BUSY */
3360 DSSERR("HS busy when enabling ULPS\n");
3361 return -EIO;
3362 }
3363
3364 if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 17, 17)) { /* LP_BUSY */
3365 DSSERR("LP busy when enabling ULPS\n");
3366 return -EIO;
3367 }
3368
3369 r = dsi_register_isr_cio(dsidev, dsi_completion_handler, &completion,
3370 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3371 if (r)
3372 return r;
3373
3374 /* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
3375 /* LANEx_ULPS_SIG2 */
3376 REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
3377 7, 5);
3378
3379 if (wait_for_completion_timeout(&completion,
3380 msecs_to_jiffies(1000)) == 0) {
3381 DSSERR("ULPS enable timeout\n");
3382 r = -EIO;
3383 goto err;
3384 }
3385
3386 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
3387 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3388
3389 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
3390
3391 dsi_if_enable(dsidev, false);
3392
3393 dsi->ulps_enabled = true;
3394
3395 return 0;
3396
3397err:
3398 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
3399 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3400 return r;
3401}
3402
3403static void dsi_set_lp_rx_timeout(struct platform_device *dsidev,
3404 unsigned ticks, bool x4, bool x16)
2297{ 3405{
2298 unsigned long fck; 3406 unsigned long fck;
2299 unsigned long total_ticks; 3407 unsigned long total_ticks;
@@ -2302,14 +3410,14 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
2302 BUG_ON(ticks > 0x1fff); 3410 BUG_ON(ticks > 0x1fff);
2303 3411
2304 /* ticks in DSI_FCK */ 3412 /* ticks in DSI_FCK */
2305 fck = dsi_fclk_rate(); 3413 fck = dsi_fclk_rate(dsidev);
2306 3414
2307 r = dsi_read_reg(DSI_TIMING2); 3415 r = dsi_read_reg(dsidev, DSI_TIMING2);
2308 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ 3416 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */
2309 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */ 3417 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */
2310 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */ 3418 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */
2311 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ 3419 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */
2312 dsi_write_reg(DSI_TIMING2, r); 3420 dsi_write_reg(dsidev, DSI_TIMING2, r);
2313 3421
2314 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); 3422 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2315 3423
@@ -2319,7 +3427,8 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
2319 (total_ticks * 1000) / (fck / 1000 / 1000)); 3427 (total_ticks * 1000) / (fck / 1000 / 1000));
2320} 3428}
2321 3429
2322static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16) 3430static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
3431 bool x8, bool x16)
2323{ 3432{
2324 unsigned long fck; 3433 unsigned long fck;
2325 unsigned long total_ticks; 3434 unsigned long total_ticks;
@@ -2328,14 +3437,14 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
2328 BUG_ON(ticks > 0x1fff); 3437 BUG_ON(ticks > 0x1fff);
2329 3438
2330 /* ticks in DSI_FCK */ 3439 /* ticks in DSI_FCK */
2331 fck = dsi_fclk_rate(); 3440 fck = dsi_fclk_rate(dsidev);
2332 3441
2333 r = dsi_read_reg(DSI_TIMING1); 3442 r = dsi_read_reg(dsidev, DSI_TIMING1);
2334 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ 3443 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */
2335 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */ 3444 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */
2336 r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */ 3445 r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */
2337 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ 3446 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
2338 dsi_write_reg(DSI_TIMING1, r); 3447 dsi_write_reg(dsidev, DSI_TIMING1, r);
2339 3448
2340 total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1); 3449 total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1);
2341 3450
@@ -2345,7 +3454,8 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
2345 (total_ticks * 1000) / (fck / 1000 / 1000)); 3454 (total_ticks * 1000) / (fck / 1000 / 1000));
2346} 3455}
2347 3456
2348static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16) 3457static void dsi_set_stop_state_counter(struct platform_device *dsidev,
3458 unsigned ticks, bool x4, bool x16)
2349{ 3459{
2350 unsigned long fck; 3460 unsigned long fck;
2351 unsigned long total_ticks; 3461 unsigned long total_ticks;
@@ -2354,14 +3464,14 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
2354 BUG_ON(ticks > 0x1fff); 3464 BUG_ON(ticks > 0x1fff);
2355 3465
2356 /* ticks in DSI_FCK */ 3466 /* ticks in DSI_FCK */
2357 fck = dsi_fclk_rate(); 3467 fck = dsi_fclk_rate(dsidev);
2358 3468
2359 r = dsi_read_reg(DSI_TIMING1); 3469 r = dsi_read_reg(dsidev, DSI_TIMING1);
2360 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ 3470 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2361 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */ 3471 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */
2362 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */ 3472 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */
2363 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ 3473 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */
2364 dsi_write_reg(DSI_TIMING1, r); 3474 dsi_write_reg(dsidev, DSI_TIMING1, r);
2365 3475
2366 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); 3476 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2367 3477
@@ -2371,7 +3481,8 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
2371 (total_ticks * 1000) / (fck / 1000 / 1000)); 3481 (total_ticks * 1000) / (fck / 1000 / 1000));
2372} 3482}
2373 3483
2374static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16) 3484static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
3485 unsigned ticks, bool x4, bool x16)
2375{ 3486{
2376 unsigned long fck; 3487 unsigned long fck;
2377 unsigned long total_ticks; 3488 unsigned long total_ticks;
@@ -2380,14 +3491,14 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
2380 BUG_ON(ticks > 0x1fff); 3491 BUG_ON(ticks > 0x1fff);
2381 3492
2382 /* ticks in TxByteClkHS */ 3493 /* ticks in TxByteClkHS */
2383 fck = dsi_get_txbyteclkhs(); 3494 fck = dsi_get_txbyteclkhs(dsidev);
2384 3495
2385 r = dsi_read_reg(DSI_TIMING2); 3496 r = dsi_read_reg(dsidev, DSI_TIMING2);
2386 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ 3497 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */
2387 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */ 3498 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */
2388 r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */ 3499 r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */
2389 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ 3500 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */
2390 dsi_write_reg(DSI_TIMING2, r); 3501 dsi_write_reg(dsidev, DSI_TIMING2, r);
2391 3502
2392 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); 3503 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2393 3504
@@ -2398,24 +3509,25 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
2398} 3509}
2399static int dsi_proto_config(struct omap_dss_device *dssdev) 3510static int dsi_proto_config(struct omap_dss_device *dssdev)
2400{ 3511{
3512 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2401 u32 r; 3513 u32 r;
2402 int buswidth = 0; 3514 int buswidth = 0;
2403 3515
2404 dsi_config_tx_fifo(DSI_FIFO_SIZE_32, 3516 dsi_config_tx_fifo(dsidev, DSI_FIFO_SIZE_32,
2405 DSI_FIFO_SIZE_32, 3517 DSI_FIFO_SIZE_32,
2406 DSI_FIFO_SIZE_32, 3518 DSI_FIFO_SIZE_32,
2407 DSI_FIFO_SIZE_32); 3519 DSI_FIFO_SIZE_32);
2408 3520
2409 dsi_config_rx_fifo(DSI_FIFO_SIZE_32, 3521 dsi_config_rx_fifo(dsidev, DSI_FIFO_SIZE_32,
2410 DSI_FIFO_SIZE_32, 3522 DSI_FIFO_SIZE_32,
2411 DSI_FIFO_SIZE_32, 3523 DSI_FIFO_SIZE_32,
2412 DSI_FIFO_SIZE_32); 3524 DSI_FIFO_SIZE_32);
2413 3525
2414 /* XXX what values for the timeouts? */ 3526 /* XXX what values for the timeouts? */
2415 dsi_set_stop_state_counter(0x1000, false, false); 3527 dsi_set_stop_state_counter(dsidev, 0x1000, false, false);
2416 dsi_set_ta_timeout(0x1fff, true, true); 3528 dsi_set_ta_timeout(dsidev, 0x1fff, true, true);
2417 dsi_set_lp_rx_timeout(0x1fff, true, true); 3529 dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
2418 dsi_set_hs_tx_timeout(0x1fff, true, true); 3530 dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
2419 3531
2420 switch (dssdev->ctrl.pixel_size) { 3532 switch (dssdev->ctrl.pixel_size) {
2421 case 16: 3533 case 16:
@@ -2431,7 +3543,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2431 BUG(); 3543 BUG();
2432 } 3544 }
2433 3545
2434 r = dsi_read_reg(DSI_CTRL); 3546 r = dsi_read_reg(dsidev, DSI_CTRL);
2435 r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */ 3547 r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */
2436 r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */ 3548 r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */
2437 r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */ 3549 r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */
@@ -2441,21 +3553,25 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2441 r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */ 3553 r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */
2442 r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ 3554 r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
2443 r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ 3555 r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
2444 r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ 3556 if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
2445 r = FLD_MOD(r, 0, 25, 25); /* DCS_CMD_CODE, 1=start, 0=continue */ 3557 r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */
3558 /* DCS_CMD_CODE, 1=start, 0=continue */
3559 r = FLD_MOD(r, 0, 25, 25);
3560 }
2446 3561
2447 dsi_write_reg(DSI_CTRL, r); 3562 dsi_write_reg(dsidev, DSI_CTRL, r);
2448 3563
2449 dsi_vc_initial_config(0); 3564 dsi_vc_initial_config(dsidev, 0);
2450 dsi_vc_initial_config(1); 3565 dsi_vc_initial_config(dsidev, 1);
2451 dsi_vc_initial_config(2); 3566 dsi_vc_initial_config(dsidev, 2);
2452 dsi_vc_initial_config(3); 3567 dsi_vc_initial_config(dsidev, 3);
2453 3568
2454 return 0; 3569 return 0;
2455} 3570}
2456 3571
2457static void dsi_proto_timings(struct omap_dss_device *dssdev) 3572static void dsi_proto_timings(struct omap_dss_device *dssdev)
2458{ 3573{
3574 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2459 unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; 3575 unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
2460 unsigned tclk_pre, tclk_post; 3576 unsigned tclk_pre, tclk_post;
2461 unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; 3577 unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
@@ -2465,32 +3581,27 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2465 unsigned ths_eot; 3581 unsigned ths_eot;
2466 u32 r; 3582 u32 r;
2467 3583
2468 r = dsi_read_reg(DSI_DSIPHY_CFG0); 3584 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
2469 ths_prepare = FLD_GET(r, 31, 24); 3585 ths_prepare = FLD_GET(r, 31, 24);
2470 ths_prepare_ths_zero = FLD_GET(r, 23, 16); 3586 ths_prepare_ths_zero = FLD_GET(r, 23, 16);
2471 ths_zero = ths_prepare_ths_zero - ths_prepare; 3587 ths_zero = ths_prepare_ths_zero - ths_prepare;
2472 ths_trail = FLD_GET(r, 15, 8); 3588 ths_trail = FLD_GET(r, 15, 8);
2473 ths_exit = FLD_GET(r, 7, 0); 3589 ths_exit = FLD_GET(r, 7, 0);
2474 3590
2475 r = dsi_read_reg(DSI_DSIPHY_CFG1); 3591 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
2476 tlpx = FLD_GET(r, 22, 16) * 2; 3592 tlpx = FLD_GET(r, 22, 16) * 2;
2477 tclk_trail = FLD_GET(r, 15, 8); 3593 tclk_trail = FLD_GET(r, 15, 8);
2478 tclk_zero = FLD_GET(r, 7, 0); 3594 tclk_zero = FLD_GET(r, 7, 0);
2479 3595
2480 r = dsi_read_reg(DSI_DSIPHY_CFG2); 3596 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
2481 tclk_prepare = FLD_GET(r, 7, 0); 3597 tclk_prepare = FLD_GET(r, 7, 0);
2482 3598
2483 /* min 8*UI */ 3599 /* min 8*UI */
2484 tclk_pre = 20; 3600 tclk_pre = 20;
2485 /* min 60ns + 52*UI */ 3601 /* min 60ns + 52*UI */
2486 tclk_post = ns2ddr(60) + 26; 3602 tclk_post = ns2ddr(dsidev, 60) + 26;
2487 3603
2488 /* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */ 3604 ths_eot = DIV_ROUND_UP(4, dsi_get_num_data_lanes_dssdev(dssdev));
2489 if (dssdev->phy.dsi.data1_lane != 0 &&
2490 dssdev->phy.dsi.data2_lane != 0)
2491 ths_eot = 2;
2492 else
2493 ths_eot = 4;
2494 3605
2495 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, 3606 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare,
2496 4); 3607 4);
@@ -2499,10 +3610,10 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2499 BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255); 3610 BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255);
2500 BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255); 3611 BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255);
2501 3612
2502 r = dsi_read_reg(DSI_CLK_TIMING); 3613 r = dsi_read_reg(dsidev, DSI_CLK_TIMING);
2503 r = FLD_MOD(r, ddr_clk_pre, 15, 8); 3614 r = FLD_MOD(r, ddr_clk_pre, 15, 8);
2504 r = FLD_MOD(r, ddr_clk_post, 7, 0); 3615 r = FLD_MOD(r, ddr_clk_post, 7, 0);
2505 dsi_write_reg(DSI_CLK_TIMING, r); 3616 dsi_write_reg(dsidev, DSI_CLK_TIMING, r);
2506 3617
2507 DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n", 3618 DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n",
2508 ddr_clk_pre, 3619 ddr_clk_pre,
@@ -2516,7 +3627,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2516 3627
2517 r = FLD_VAL(enter_hs_mode_lat, 31, 16) | 3628 r = FLD_VAL(enter_hs_mode_lat, 31, 16) |
2518 FLD_VAL(exit_hs_mode_lat, 15, 0); 3629 FLD_VAL(exit_hs_mode_lat, 15, 0);
2519 dsi_write_reg(DSI_VM_TIMING7, r); 3630 dsi_write_reg(dsidev, DSI_VM_TIMING7, r);
2520 3631
2521 DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", 3632 DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
2522 enter_hs_mode_lat, exit_hs_mode_lat); 3633 enter_hs_mode_lat, exit_hs_mode_lat);
@@ -2526,25 +3637,27 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2526#define DSI_DECL_VARS \ 3637#define DSI_DECL_VARS \
2527 int __dsi_cb = 0; u32 __dsi_cv = 0; 3638 int __dsi_cb = 0; u32 __dsi_cv = 0;
2528 3639
2529#define DSI_FLUSH(ch) \ 3640#define DSI_FLUSH(dsidev, ch) \
2530 if (__dsi_cb > 0) { \ 3641 if (__dsi_cb > 0) { \
2531 /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \ 3642 /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \
2532 dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \ 3643 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \
2533 __dsi_cb = __dsi_cv = 0; \ 3644 __dsi_cb = __dsi_cv = 0; \
2534 } 3645 }
2535 3646
2536#define DSI_PUSH(ch, data) \ 3647#define DSI_PUSH(dsidev, ch, data) \
2537 do { \ 3648 do { \
2538 __dsi_cv |= (data) << (__dsi_cb * 8); \ 3649 __dsi_cv |= (data) << (__dsi_cb * 8); \
2539 /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \ 3650 /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \
2540 if (++__dsi_cb > 3) \ 3651 if (++__dsi_cb > 3) \
2541 DSI_FLUSH(ch); \ 3652 DSI_FLUSH(dsidev, ch); \
2542 } while (0) 3653 } while (0)
2543 3654
2544static int dsi_update_screen_l4(struct omap_dss_device *dssdev, 3655static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2545 int x, int y, int w, int h) 3656 int x, int y, int w, int h)
2546{ 3657{
2547 /* Note: supports only 24bit colors in 32bit container */ 3658 /* Note: supports only 24bit colors in 32bit container */
3659 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3660 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2548 int first = 1; 3661 int first = 1;
2549 int fifo_stalls = 0; 3662 int fifo_stalls = 0;
2550 int max_dsi_packet_size; 3663 int max_dsi_packet_size;
@@ -2583,7 +3696,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2583 * in fifo */ 3696 * in fifo */
2584 3697
2585 /* When using CPU, max long packet size is TX buffer size */ 3698 /* When using CPU, max long packet size is TX buffer size */
2586 max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4; 3699 max_dsi_packet_size = dsi->vc[0].fifo_size * 32 * 4;
2587 3700
2588 /* we seem to get better perf if we divide the tx fifo to half, 3701 /* we seem to get better perf if we divide the tx fifo to half,
2589 and while the other half is being sent, we fill the other half 3702 and while the other half is being sent, we fill the other half
@@ -2612,35 +3725,36 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2612#if 1 3725#if 1
2613 /* using fifo not empty */ 3726 /* using fifo not empty */
2614 /* TX_FIFO_NOT_EMPTY */ 3727 /* TX_FIFO_NOT_EMPTY */
2615 while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { 3728 while (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(0)), 5, 5)) {
2616 fifo_stalls++; 3729 fifo_stalls++;
2617 if (fifo_stalls > 0xfffff) { 3730 if (fifo_stalls > 0xfffff) {
2618 DSSERR("fifo stalls overflow, pixels left %d\n", 3731 DSSERR("fifo stalls overflow, pixels left %d\n",
2619 pixels_left); 3732 pixels_left);
2620 dsi_if_enable(0); 3733 dsi_if_enable(dsidev, 0);
2621 return -EIO; 3734 return -EIO;
2622 } 3735 }
2623 udelay(1); 3736 udelay(1);
2624 } 3737 }
2625#elif 1 3738#elif 1
2626 /* using fifo emptiness */ 3739 /* using fifo emptiness */
2627 while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 < 3740 while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
2628 max_dsi_packet_size) { 3741 max_dsi_packet_size) {
2629 fifo_stalls++; 3742 fifo_stalls++;
2630 if (fifo_stalls > 0xfffff) { 3743 if (fifo_stalls > 0xfffff) {
2631 DSSERR("fifo stalls overflow, pixels left %d\n", 3744 DSSERR("fifo stalls overflow, pixels left %d\n",
2632 pixels_left); 3745 pixels_left);
2633 dsi_if_enable(0); 3746 dsi_if_enable(dsidev, 0);
2634 return -EIO; 3747 return -EIO;
2635 } 3748 }
2636 } 3749 }
2637#else 3750#else
2638 while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) { 3751 while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS,
3752 7, 0) + 1) * 4 == 0) {
2639 fifo_stalls++; 3753 fifo_stalls++;
2640 if (fifo_stalls > 0xfffff) { 3754 if (fifo_stalls > 0xfffff) {
2641 DSSERR("fifo stalls overflow, pixels left %d\n", 3755 DSSERR("fifo stalls overflow, pixels left %d\n",
2642 pixels_left); 3756 pixels_left);
2643 dsi_if_enable(0); 3757 dsi_if_enable(dsidev, 0);
2644 return -EIO; 3758 return -EIO;
2645 } 3759 }
2646 } 3760 }
@@ -2649,17 +3763,17 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2649 3763
2650 pixels_left -= pixels; 3764 pixels_left -= pixels;
2651 3765
2652 dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE, 3766 dsi_vc_write_long_header(dsidev, 0, DSI_DT_DCS_LONG_WRITE,
2653 1 + pixels * bytespp, 0); 3767 1 + pixels * bytespp, 0);
2654 3768
2655 DSI_PUSH(0, dcs_cmd); 3769 DSI_PUSH(dsidev, 0, dcs_cmd);
2656 3770
2657 while (pixels-- > 0) { 3771 while (pixels-- > 0) {
2658 u32 pix = __raw_readl(data++); 3772 u32 pix = __raw_readl(data++);
2659 3773
2660 DSI_PUSH(0, (pix >> 16) & 0xff); 3774 DSI_PUSH(dsidev, 0, (pix >> 16) & 0xff);
2661 DSI_PUSH(0, (pix >> 8) & 0xff); 3775 DSI_PUSH(dsidev, 0, (pix >> 8) & 0xff);
2662 DSI_PUSH(0, (pix >> 0) & 0xff); 3776 DSI_PUSH(dsidev, 0, (pix >> 0) & 0xff);
2663 3777
2664 current_x++; 3778 current_x++;
2665 if (current_x == x+w) { 3779 if (current_x == x+w) {
@@ -2668,7 +3782,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2668 } 3782 }
2669 } 3783 }
2670 3784
2671 DSI_FLUSH(0); 3785 DSI_FLUSH(dsidev, 0);
2672 } 3786 }
2673 3787
2674 return 0; 3788 return 0;
@@ -2677,6 +3791,8 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2677static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, 3791static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2678 u16 x, u16 y, u16 w, u16 h) 3792 u16 x, u16 y, u16 w, u16 h)
2679{ 3793{
3794 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3795 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2680 unsigned bytespp; 3796 unsigned bytespp;
2681 unsigned bytespl; 3797 unsigned bytespl;
2682 unsigned bytespf; 3798 unsigned bytespf;
@@ -2685,16 +3801,13 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2685 unsigned packet_len; 3801 unsigned packet_len;
2686 u32 l; 3802 u32 l;
2687 int r; 3803 int r;
2688 const unsigned channel = dsi.update_channel; 3804 const unsigned channel = dsi->update_channel;
2689 /* line buffer is 1024 x 24bits */ 3805 const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
2690 /* XXX: for some reason using full buffer size causes considerable TX
2691 * slowdown with update sizes that fill the whole buffer */
2692 const unsigned line_buf_size = 1023 * 3;
2693 3806
2694 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", 3807 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
2695 x, y, w, h); 3808 x, y, w, h);
2696 3809
2697 dsi_vc_config_vp(channel); 3810 dsi_vc_config_vp(dsidev, channel);
2698 3811
2699 bytespp = dssdev->ctrl.pixel_size / 8; 3812 bytespp = dssdev->ctrl.pixel_size / 8;
2700 bytespl = w * bytespp; 3813 bytespl = w * bytespp;
@@ -2715,15 +3828,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2715 total_len += (bytespf % packet_payload) + 1; 3828 total_len += (bytespf % packet_payload) + 1;
2716 3829
2717 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ 3830 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
2718 dsi_write_reg(DSI_VC_TE(channel), l); 3831 dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
2719 3832
2720 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); 3833 dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
3834 packet_len, 0);
2721 3835
2722 if (dsi.te_enabled) 3836 if (dsi->te_enabled)
2723 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ 3837 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
2724 else 3838 else
2725 l = FLD_MOD(l, 1, 31, 31); /* TE_START */ 3839 l = FLD_MOD(l, 1, 31, 31); /* TE_START */
2726 dsi_write_reg(DSI_VC_TE(channel), l); 3840 dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
2727 3841
2728 /* We put SIDLEMODE to no-idle for the duration of the transfer, 3842 /* We put SIDLEMODE to no-idle for the duration of the transfer,
2729 * because DSS interrupts are not capable of waking up the CPU and the 3843 * because DSS interrupts are not capable of waking up the CPU and the
@@ -2733,23 +3847,23 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2733 */ 3847 */
2734 dispc_disable_sidle(); 3848 dispc_disable_sidle();
2735 3849
2736 dsi_perf_mark_start(); 3850 dsi_perf_mark_start(dsidev);
2737 3851
2738 r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work, 3852 r = schedule_delayed_work(&dsi->framedone_timeout_work,
2739 msecs_to_jiffies(250)); 3853 msecs_to_jiffies(250));
2740 BUG_ON(r == 0); 3854 BUG_ON(r == 0);
2741 3855
2742 dss_start_update(dssdev); 3856 dss_start_update(dssdev);
2743 3857
2744 if (dsi.te_enabled) { 3858 if (dsi->te_enabled) {
2745 /* disable LP_RX_TO, so that we can receive TE. Time to wait 3859 /* disable LP_RX_TO, so that we can receive TE. Time to wait
2746 * for TE is longer than the timer allows */ 3860 * for TE is longer than the timer allows */
2747 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ 3861 REG_FLD_MOD(dsidev, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
2748 3862
2749 dsi_vc_send_bta(channel); 3863 dsi_vc_send_bta(dsidev, channel);
2750 3864
2751#ifdef DSI_CATCH_MISSING_TE 3865#ifdef DSI_CATCH_MISSING_TE
2752 mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250)); 3866 mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250));
2753#endif 3867#endif
2754 } 3868 }
2755} 3869}
@@ -2761,40 +3875,28 @@ static void dsi_te_timeout(unsigned long arg)
2761} 3875}
2762#endif 3876#endif
2763 3877
2764static void dsi_handle_framedone(int error) 3878static void dsi_handle_framedone(struct platform_device *dsidev, int error)
2765{ 3879{
2766 const int channel = dsi.update_channel; 3880 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2767
2768 cancel_delayed_work(&dsi.framedone_timeout_work);
2769
2770 dsi_vc_disable_bta_irq(channel);
2771 3881
2772 /* SIDLEMODE back to smart-idle */ 3882 /* SIDLEMODE back to smart-idle */
2773 dispc_enable_sidle(); 3883 dispc_enable_sidle();
2774 3884
2775 dsi.bta_callback = NULL; 3885 if (dsi->te_enabled) {
2776
2777 if (dsi.te_enabled) {
2778 /* enable LP_RX_TO again after the TE */ 3886 /* enable LP_RX_TO again after the TE */
2779 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 3887 REG_FLD_MOD(dsidev, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2780 }
2781
2782 /* RX_FIFO_NOT_EMPTY */
2783 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2784 DSSERR("Received error during frame transfer:\n");
2785 dsi_vc_flush_receive_data(channel);
2786 if (!error)
2787 error = -EIO;
2788 } 3888 }
2789 3889
2790 dsi.framedone_callback(error, dsi.framedone_data); 3890 dsi->framedone_callback(error, dsi->framedone_data);
2791 3891
2792 if (!error) 3892 if (!error)
2793 dsi_perf_show("DISPC"); 3893 dsi_perf_show(dsidev, "DISPC");
2794} 3894}
2795 3895
2796static void dsi_framedone_timeout_work_callback(struct work_struct *work) 3896static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2797{ 3897{
3898 struct dsi_data *dsi = container_of(work, struct dsi_data,
3899 framedone_timeout_work.work);
2798 /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after 3900 /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after
2799 * 250ms which would conflict with this timeout work. What should be 3901 * 250ms which would conflict with this timeout work. What should be
2800 * done is first cancel the transfer on the HW, and then cancel the 3902 * done is first cancel the transfer on the HW, and then cancel the
@@ -2804,66 +3906,34 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2804 3906
2805 DSSERR("Framedone not received for 250ms!\n"); 3907 DSSERR("Framedone not received for 250ms!\n");
2806 3908
2807 dsi_handle_framedone(-ETIMEDOUT); 3909 dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
2808}
2809
2810static void dsi_framedone_bta_callback(void)
2811{
2812 dsi_handle_framedone(0);
2813
2814#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2815 dispc_fake_vsync_irq();
2816#endif
2817} 3910}
2818 3911
2819static void dsi_framedone_irq_callback(void *data, u32 mask) 3912static void dsi_framedone_irq_callback(void *data, u32 mask)
2820{ 3913{
2821 const int channel = dsi.update_channel; 3914 struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
2822 int r; 3915 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3916 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2823 3917
2824 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 3918 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
2825 * turns itself off. However, DSI still has the pixels in its buffers, 3919 * turns itself off. However, DSI still has the pixels in its buffers,
2826 * and is sending the data. 3920 * and is sending the data.
2827 */ 3921 */
2828 3922
2829 if (dsi.te_enabled) { 3923 __cancel_delayed_work(&dsi->framedone_timeout_work);
2830 /* enable LP_RX_TO again after the TE */
2831 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2832 }
2833
2834 /* Send BTA after the frame. We need this for the TE to work, as TE
2835 * trigger is only sent for BTAs without preceding packet. Thus we need
2836 * to BTA after the pixel packets so that next BTA will cause TE
2837 * trigger.
2838 *
2839 * This is not needed when TE is not in use, but we do it anyway to
2840 * make sure that the transfer has been completed. It would be more
2841 * optimal, but more complex, to wait only just before starting next
2842 * transfer.
2843 *
2844 * Also, as there's no interrupt telling when the transfer has been
2845 * done and the channel could be reconfigured, the only way is to
2846 * busyloop until TE_SIZE is zero. With BTA we can do this
2847 * asynchronously.
2848 * */
2849
2850 dsi.bta_callback = dsi_framedone_bta_callback;
2851
2852 barrier();
2853 3924
2854 dsi_vc_enable_bta_irq(channel); 3925 dsi_handle_framedone(dsidev, 0);
2855 3926
2856 r = dsi_vc_send_bta(channel); 3927#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2857 if (r) { 3928 dispc_fake_vsync_irq();
2858 DSSERR("BTA after framedone failed\n"); 3929#endif
2859 dsi_handle_framedone(-EIO);
2860 }
2861} 3930}
2862 3931
2863int omap_dsi_prepare_update(struct omap_dss_device *dssdev, 3932int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2864 u16 *x, u16 *y, u16 *w, u16 *h, 3933 u16 *x, u16 *y, u16 *w, u16 *h,
2865 bool enlarge_update_area) 3934 bool enlarge_update_area)
2866{ 3935{
3936 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2867 u16 dw, dh; 3937 u16 dw, dh;
2868 3938
2869 dssdev->driver->get_resolution(dssdev, &dw, &dh); 3939 dssdev->driver->get_resolution(dssdev, &dw, &dh);
@@ -2883,12 +3953,12 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2883 if (*w == 0 || *h == 0) 3953 if (*w == 0 || *h == 0)
2884 return -EINVAL; 3954 return -EINVAL;
2885 3955
2886 dsi_perf_mark_setup(); 3956 dsi_perf_mark_setup(dsidev);
2887 3957
2888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 3958 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2889 dss_setup_partial_planes(dssdev, x, y, w, h, 3959 dss_setup_partial_planes(dssdev, x, y, w, h,
2890 enlarge_update_area); 3960 enlarge_update_area);
2891 dispc_set_lcd_size(*w, *h); 3961 dispc_set_lcd_size(dssdev->manager->id, *w, *h);
2892 } 3962 }
2893 3963
2894 return 0; 3964 return 0;
@@ -2900,7 +3970,10 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2900 u16 x, u16 y, u16 w, u16 h, 3970 u16 x, u16 y, u16 w, u16 h,
2901 void (*callback)(int, void *), void *data) 3971 void (*callback)(int, void *), void *data)
2902{ 3972{
2903 dsi.update_channel = channel; 3973 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3974 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3975
3976 dsi->update_channel = channel;
2904 3977
2905 /* OMAP DSS cannot send updates of odd widths. 3978 /* OMAP DSS cannot send updates of odd widths.
2906 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON 3979 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
@@ -2909,14 +3982,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2909 BUG_ON(x % 2 == 1); 3982 BUG_ON(x % 2 == 1);
2910 3983
2911 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 3984 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2912 dsi.framedone_callback = callback; 3985 dsi->framedone_callback = callback;
2913 dsi.framedone_data = data; 3986 dsi->framedone_data = data;
2914 3987
2915 dsi.update_region.x = x; 3988 dsi->update_region.x = x;
2916 dsi.update_region.y = y; 3989 dsi->update_region.y = y;
2917 dsi.update_region.w = w; 3990 dsi->update_region.w = w;
2918 dsi.update_region.h = h; 3991 dsi->update_region.h = h;
2919 dsi.update_region.device = dssdev; 3992 dsi->update_region.device = dssdev;
2920 3993
2921 dsi_update_screen_dispc(dssdev, x, y, w, h); 3994 dsi_update_screen_dispc(dssdev, x, y, w, h);
2922 } else { 3995 } else {
@@ -2926,7 +3999,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2926 if (r) 3999 if (r)
2927 return r; 4000 return r;
2928 4001
2929 dsi_perf_show("L4"); 4002 dsi_perf_show(dsidev, "L4");
2930 callback(0, data); 4003 callback(0, data);
2931 } 4004 }
2932 4005
@@ -2939,20 +4012,26 @@ EXPORT_SYMBOL(omap_dsi_update);
2939static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4012static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
2940{ 4013{
2941 int r; 4014 int r;
4015 u32 irq;
4016
4017 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4018 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
2942 4019
2943 r = omap_dispc_register_isr(dsi_framedone_irq_callback, NULL, 4020 r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
2944 DISPC_IRQ_FRAMEDONE); 4021 irq);
2945 if (r) { 4022 if (r) {
2946 DSSERR("can't get FRAMEDONE irq\n"); 4023 DSSERR("can't get FRAMEDONE irq\n");
2947 return r; 4024 return r;
2948 } 4025 }
2949 4026
2950 dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); 4027 dispc_set_lcd_display_type(dssdev->manager->id,
4028 OMAP_DSS_LCD_DISPLAY_TFT);
2951 4029
2952 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_DSI); 4030 dispc_set_parallel_interface_mode(dssdev->manager->id,
2953 dispc_enable_fifohandcheck(1); 4031 OMAP_DSS_PARALLELMODE_DSI);
4032 dispc_enable_fifohandcheck(dssdev->manager->id, 1);
2954 4033
2955 dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); 4034 dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
2956 4035
2957 { 4036 {
2958 struct omap_video_timings timings = { 4037 struct omap_video_timings timings = {
@@ -2964,7 +4043,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
2964 .vbp = 0, 4043 .vbp = 0,
2965 }; 4044 };
2966 4045
2967 dispc_set_lcd_timings(&timings); 4046 dispc_set_lcd_timings(dssdev->manager->id, &timings);
2968 } 4047 }
2969 4048
2970 return 0; 4049 return 0;
@@ -2972,28 +4051,34 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
2972 4051
2973static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4052static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
2974{ 4053{
2975 omap_dispc_unregister_isr(dsi_framedone_irq_callback, NULL, 4054 u32 irq;
2976 DISPC_IRQ_FRAMEDONE); 4055
4056 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4057 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4058
4059 omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
4060 irq);
2977} 4061}
2978 4062
2979static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4063static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
2980{ 4064{
4065 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2981 struct dsi_clock_info cinfo; 4066 struct dsi_clock_info cinfo;
2982 int r; 4067 int r;
2983 4068
2984 /* we always use DSS2_FCK as input clock */ 4069 /* we always use DSS_CLK_SYSCK as input clock */
2985 cinfo.use_dss2_fck = true; 4070 cinfo.use_sys_clk = true;
2986 cinfo.regn = dssdev->phy.dsi.div.regn; 4071 cinfo.regn = dssdev->clocks.dsi.regn;
2987 cinfo.regm = dssdev->phy.dsi.div.regm; 4072 cinfo.regm = dssdev->clocks.dsi.regm;
2988 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 4073 cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc;
2989 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 4074 cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi;
2990 r = dsi_calc_clock_rates(&cinfo); 4075 r = dsi_calc_clock_rates(dssdev, &cinfo);
2991 if (r) { 4076 if (r) {
2992 DSSERR("Failed to calc dsi clocks\n"); 4077 DSSERR("Failed to calc dsi clocks\n");
2993 return r; 4078 return r;
2994 } 4079 }
2995 4080
2996 r = dsi_pll_set_clock_div(&cinfo); 4081 r = dsi_pll_set_clock_div(dsidev, &cinfo);
2997 if (r) { 4082 if (r) {
2998 DSSERR("Failed to set dsi clocks\n"); 4083 DSSERR("Failed to set dsi clocks\n");
2999 return r; 4084 return r;
@@ -3004,14 +4089,15 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
3004 4089
3005static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) 4090static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3006{ 4091{
4092 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3007 struct dispc_clock_info dispc_cinfo; 4093 struct dispc_clock_info dispc_cinfo;
3008 int r; 4094 int r;
3009 unsigned long long fck; 4095 unsigned long long fck;
3010 4096
3011 fck = dsi_get_dsi1_pll_rate(); 4097 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
3012 4098
3013 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; 4099 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
3014 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; 4100 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
3015 4101
3016 r = dispc_calc_clock_rates(fck, &dispc_cinfo); 4102 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
3017 if (r) { 4103 if (r) {
@@ -3019,7 +4105,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3019 return r; 4105 return r;
3020 } 4106 }
3021 4107
3022 r = dispc_set_clock_div(&dispc_cinfo); 4108 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
3023 if (r) { 4109 if (r) {
3024 DSSERR("Failed to set dispc clocks\n"); 4110 DSSERR("Failed to set dispc clocks\n");
3025 return r; 4111 return r;
@@ -3030,11 +4116,11 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3030 4116
3031static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4117static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3032{ 4118{
4119 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4120 int dsi_module = dsi_get_dsidev_id(dsidev);
3033 int r; 4121 int r;
3034 4122
3035 _dsi_print_reset_status(); 4123 r = dsi_pll_init(dsidev, true, true);
3036
3037 r = dsi_pll_init(dssdev, true, true);
3038 if (r) 4124 if (r)
3039 goto err0; 4125 goto err0;
3040 4126
@@ -3042,8 +4128,10 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3042 if (r) 4128 if (r)
3043 goto err1; 4129 goto err1;
3044 4130
3045 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 4131 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
3046 dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); 4132 dss_select_dsi_clk_source(dsi_module, dssdev->clocks.dsi.dsi_fclk_src);
4133 dss_select_lcd_clk_source(dssdev->manager->id,
4134 dssdev->clocks.dispc.channel.lcd_clk_src);
3047 4135
3048 DSSDBG("PLL OK\n"); 4136 DSSDBG("PLL OK\n");
3049 4137
@@ -3051,82 +4139,92 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3051 if (r) 4139 if (r)
3052 goto err2; 4140 goto err2;
3053 4141
3054 r = dsi_complexio_init(dssdev); 4142 r = dsi_cio_init(dssdev);
3055 if (r) 4143 if (r)
3056 goto err2; 4144 goto err2;
3057 4145
3058 _dsi_print_reset_status(); 4146 _dsi_print_reset_status(dsidev);
3059 4147
3060 dsi_proto_timings(dssdev); 4148 dsi_proto_timings(dssdev);
3061 dsi_set_lp_clk_divisor(dssdev); 4149 dsi_set_lp_clk_divisor(dssdev);
3062 4150
3063 if (1) 4151 if (1)
3064 _dsi_print_reset_status(); 4152 _dsi_print_reset_status(dsidev);
3065 4153
3066 r = dsi_proto_config(dssdev); 4154 r = dsi_proto_config(dssdev);
3067 if (r) 4155 if (r)
3068 goto err3; 4156 goto err3;
3069 4157
3070 /* enable interface */ 4158 /* enable interface */
3071 dsi_vc_enable(0, 1); 4159 dsi_vc_enable(dsidev, 0, 1);
3072 dsi_vc_enable(1, 1); 4160 dsi_vc_enable(dsidev, 1, 1);
3073 dsi_vc_enable(2, 1); 4161 dsi_vc_enable(dsidev, 2, 1);
3074 dsi_vc_enable(3, 1); 4162 dsi_vc_enable(dsidev, 3, 1);
3075 dsi_if_enable(1); 4163 dsi_if_enable(dsidev, 1);
3076 dsi_force_tx_stop_mode_io(); 4164 dsi_force_tx_stop_mode_io(dsidev);
3077 4165
3078 return 0; 4166 return 0;
3079err3: 4167err3:
3080 dsi_complexio_uninit(); 4168 dsi_cio_uninit(dsidev);
3081err2: 4169err2:
3082 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 4170 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
3083 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 4171 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
3084err1: 4172err1:
3085 dsi_pll_uninit(); 4173 dsi_pll_uninit(dsidev, true);
3086err0: 4174err0:
3087 return r; 4175 return r;
3088} 4176}
3089 4177
3090static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 4178static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4179 bool disconnect_lanes, bool enter_ulps)
3091{ 4180{
3092 /* disable interface */ 4181 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3093 dsi_if_enable(0); 4182 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3094 dsi_vc_enable(0, 0); 4183 int dsi_module = dsi_get_dsidev_id(dsidev);
3095 dsi_vc_enable(1, 0); 4184
3096 dsi_vc_enable(2, 0); 4185 if (enter_ulps && !dsi->ulps_enabled)
3097 dsi_vc_enable(3, 0); 4186 dsi_enter_ulps(dsidev);
3098 4187
3099 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 4188 /* disable interface */
3100 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 4189 dsi_if_enable(dsidev, 0);
3101 dsi_complexio_uninit(); 4190 dsi_vc_enable(dsidev, 0, 0);
3102 dsi_pll_uninit(); 4191 dsi_vc_enable(dsidev, 1, 0);
4192 dsi_vc_enable(dsidev, 2, 0);
4193 dsi_vc_enable(dsidev, 3, 0);
4194
4195 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4196 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
4197 dsi_cio_uninit(dsidev);
4198 dsi_pll_uninit(dsidev, disconnect_lanes);
3103} 4199}
3104 4200
3105static int dsi_core_init(void) 4201static int dsi_core_init(struct platform_device *dsidev)
3106{ 4202{
3107 /* Autoidle */ 4203 /* Autoidle */
3108 REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0); 4204 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0);
3109 4205
3110 /* ENWAKEUP */ 4206 /* ENWAKEUP */
3111 REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2); 4207 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2);
3112 4208
3113 /* SIDLEMODE smart-idle */ 4209 /* SIDLEMODE smart-idle */
3114 REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3); 4210 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3);
3115 4211
3116 _dsi_initialize_irq(); 4212 _dsi_initialize_irq(dsidev);
3117 4213
3118 return 0; 4214 return 0;
3119} 4215}
3120 4216
3121int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) 4217int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3122{ 4218{
4219 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4220 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3123 int r = 0; 4221 int r = 0;
3124 4222
3125 DSSDBG("dsi_display_enable\n"); 4223 DSSDBG("dsi_display_enable\n");
3126 4224
3127 WARN_ON(!dsi_bus_is_locked()); 4225 WARN_ON(!dsi_bus_is_locked(dsidev));
3128 4226
3129 mutex_lock(&dsi.lock); 4227 mutex_lock(&dsi->lock);
3130 4228
3131 r = omap_dss_start_device(dssdev); 4229 r = omap_dss_start_device(dssdev);
3132 if (r) { 4230 if (r) {
@@ -3135,13 +4233,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3135 } 4233 }
3136 4234
3137 enable_clocks(1); 4235 enable_clocks(1);
3138 dsi_enable_pll_clock(1); 4236 dsi_enable_pll_clock(dsidev, 1);
3139 4237
3140 r = _dsi_reset(); 4238 r = _dsi_reset(dsidev);
3141 if (r) 4239 if (r)
3142 goto err1; 4240 goto err1;
3143 4241
3144 dsi_core_init(); 4242 dsi_core_init(dsidev);
3145 4243
3146 r = dsi_display_init_dispc(dssdev); 4244 r = dsi_display_init_dispc(dssdev);
3147 if (r) 4245 if (r)
@@ -3151,7 +4249,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3151 if (r) 4249 if (r)
3152 goto err2; 4250 goto err2;
3153 4251
3154 mutex_unlock(&dsi.lock); 4252 mutex_unlock(&dsi->lock);
3155 4253
3156 return 0; 4254 return 0;
3157 4255
@@ -3159,39 +4257,46 @@ err2:
3159 dsi_display_uninit_dispc(dssdev); 4257 dsi_display_uninit_dispc(dssdev);
3160err1: 4258err1:
3161 enable_clocks(0); 4259 enable_clocks(0);
3162 dsi_enable_pll_clock(0); 4260 dsi_enable_pll_clock(dsidev, 0);
3163 omap_dss_stop_device(dssdev); 4261 omap_dss_stop_device(dssdev);
3164err0: 4262err0:
3165 mutex_unlock(&dsi.lock); 4263 mutex_unlock(&dsi->lock);
3166 DSSDBG("dsi_display_enable FAILED\n"); 4264 DSSDBG("dsi_display_enable FAILED\n");
3167 return r; 4265 return r;
3168} 4266}
3169EXPORT_SYMBOL(omapdss_dsi_display_enable); 4267EXPORT_SYMBOL(omapdss_dsi_display_enable);
3170 4268
3171void omapdss_dsi_display_disable(struct omap_dss_device *dssdev) 4269void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
4270 bool disconnect_lanes, bool enter_ulps)
3172{ 4271{
4272 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4273 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4274
3173 DSSDBG("dsi_display_disable\n"); 4275 DSSDBG("dsi_display_disable\n");
3174 4276
3175 WARN_ON(!dsi_bus_is_locked()); 4277 WARN_ON(!dsi_bus_is_locked(dsidev));
3176 4278
3177 mutex_lock(&dsi.lock); 4279 mutex_lock(&dsi->lock);
3178 4280
3179 dsi_display_uninit_dispc(dssdev); 4281 dsi_display_uninit_dispc(dssdev);
3180 4282
3181 dsi_display_uninit_dsi(dssdev); 4283 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
3182 4284
3183 enable_clocks(0); 4285 enable_clocks(0);
3184 dsi_enable_pll_clock(0); 4286 dsi_enable_pll_clock(dsidev, 0);
3185 4287
3186 omap_dss_stop_device(dssdev); 4288 omap_dss_stop_device(dssdev);
3187 4289
3188 mutex_unlock(&dsi.lock); 4290 mutex_unlock(&dsi->lock);
3189} 4291}
3190EXPORT_SYMBOL(omapdss_dsi_display_disable); 4292EXPORT_SYMBOL(omapdss_dsi_display_disable);
3191 4293
3192int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) 4294int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
3193{ 4295{
3194 dsi.te_enabled = enable; 4296 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4297 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4298
4299 dsi->te_enabled = enable;
3195 return 0; 4300 return 0;
3196} 4301}
3197EXPORT_SYMBOL(omapdss_dsi_enable_te); 4302EXPORT_SYMBOL(omapdss_dsi_enable_te);
@@ -3211,97 +4316,284 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3211 4316
3212int dsi_init_display(struct omap_dss_device *dssdev) 4317int dsi_init_display(struct omap_dss_device *dssdev)
3213{ 4318{
4319 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4320 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4321 int dsi_module = dsi_get_dsidev_id(dsidev);
4322
3214 DSSDBG("DSI init\n"); 4323 DSSDBG("DSI init\n");
3215 4324
3216 /* XXX these should be figured out dynamically */ 4325 /* XXX these should be figured out dynamically */
3217 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 4326 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3218 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 4327 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
3219 4328
3220 dsi.vc[0].dssdev = dssdev; 4329 if (dsi->vdds_dsi_reg == NULL) {
3221 dsi.vc[1].dssdev = dssdev; 4330 struct regulator *vdds_dsi;
4331
4332 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
4333
4334 if (IS_ERR(vdds_dsi)) {
4335 DSSERR("can't get VDDS_DSI regulator\n");
4336 return PTR_ERR(vdds_dsi);
4337 }
4338
4339 dsi->vdds_dsi_reg = vdds_dsi;
4340 }
4341
4342 if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) {
4343 DSSERR("DSI%d can't support more than %d data lanes\n",
4344 dsi_module + 1, dsi->num_data_lanes);
4345 return -EINVAL;
4346 }
4347
4348 return 0;
4349}
4350
4351int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
4352{
4353 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4354 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4355 int i;
4356
4357 for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
4358 if (!dsi->vc[i].dssdev) {
4359 dsi->vc[i].dssdev = dssdev;
4360 *channel = i;
4361 return 0;
4362 }
4363 }
4364
4365 DSSERR("cannot get VC for display %s", dssdev->name);
4366 return -ENOSPC;
4367}
4368EXPORT_SYMBOL(omap_dsi_request_vc);
4369
4370int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
4371{
4372 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4373 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4374
4375 if (vc_id < 0 || vc_id > 3) {
4376 DSSERR("VC ID out of range\n");
4377 return -EINVAL;
4378 }
4379
4380 if (channel < 0 || channel > 3) {
4381 DSSERR("Virtual Channel out of range\n");
4382 return -EINVAL;
4383 }
4384
4385 if (dsi->vc[channel].dssdev != dssdev) {
4386 DSSERR("Virtual Channel not allocated to display %s\n",
4387 dssdev->name);
4388 return -EINVAL;
4389 }
4390
4391 dsi->vc[channel].vc_id = vc_id;
3222 4392
3223 return 0; 4393 return 0;
3224} 4394}
4395EXPORT_SYMBOL(omap_dsi_set_vc_id);
4396
4397void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
4398{
4399 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4400 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4401
4402 if ((channel >= 0 && channel <= 3) &&
4403 dsi->vc[channel].dssdev == dssdev) {
4404 dsi->vc[channel].dssdev = NULL;
4405 dsi->vc[channel].vc_id = 0;
4406 }
4407}
4408EXPORT_SYMBOL(omap_dsi_release_vc);
4409
4410void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
4411{
4412 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1)
4413 DSSERR("%s (%s) not active\n",
4414 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
4415 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
4416}
3225 4417
3226void dsi_wait_dsi1_pll_active(void) 4418void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
3227{ 4419{
3228 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) 4420 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1)
3229 DSSERR("DSI1 PLL clock not active\n"); 4421 DSSERR("%s (%s) not active\n",
4422 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
4423 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
3230} 4424}
3231 4425
3232void dsi_wait_dsi2_pll_active(void) 4426static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
3233{ 4427{
3234 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) 4428 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3235 DSSERR("DSI2 PLL clock not active\n"); 4429
4430 dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
4431 dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
4432 dsi->regm_dispc_max =
4433 dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
4434 dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
4435 dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
4436 dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
4437 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
3236} 4438}
3237 4439
3238int dsi_init(struct platform_device *pdev) 4440static int dsi_init(struct platform_device *dsidev)
3239{ 4441{
4442 struct omap_display_platform_data *dss_plat_data;
4443 struct omap_dss_board_info *board_info;
3240 u32 rev; 4444 u32 rev;
3241 int r; 4445 int r, i, dsi_module = dsi_get_dsidev_id(dsidev);
4446 struct resource *dsi_mem;
4447 struct dsi_data *dsi;
3242 4448
3243 spin_lock_init(&dsi.errors_lock); 4449 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
3244 dsi.errors = 0; 4450 if (!dsi) {
4451 r = -ENOMEM;
4452 goto err0;
4453 }
3245 4454
3246#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 4455 dsi->pdev = dsidev;
3247 spin_lock_init(&dsi.irq_stats_lock); 4456 dsi_pdev_map[dsi_module] = dsidev;
3248 dsi.irq_stats.last_reset = jiffies; 4457 dev_set_drvdata(&dsidev->dev, dsi);
3249#endif
3250 4458
3251 init_completion(&dsi.bta_completion); 4459 dss_plat_data = dsidev->dev.platform_data;
4460 board_info = dss_plat_data->board_data;
4461 dsi->dsi_mux_pads = board_info->dsi_mux_pads;
3252 4462
3253 mutex_init(&dsi.lock); 4463 spin_lock_init(&dsi->irq_lock);
3254 sema_init(&dsi.bus_lock, 1); 4464 spin_lock_init(&dsi->errors_lock);
4465 dsi->errors = 0;
3255 4466
3256 dsi.workqueue = create_singlethread_workqueue("dsi"); 4467#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3257 if (dsi.workqueue == NULL) 4468 spin_lock_init(&dsi->irq_stats_lock);
3258 return -ENOMEM; 4469 dsi->irq_stats.last_reset = jiffies;
4470#endif
3259 4471
3260 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work, 4472 mutex_init(&dsi->lock);
4473 sema_init(&dsi->bus_lock, 1);
4474
4475 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
3261 dsi_framedone_timeout_work_callback); 4476 dsi_framedone_timeout_work_callback);
3262 4477
3263#ifdef DSI_CATCH_MISSING_TE 4478#ifdef DSI_CATCH_MISSING_TE
3264 init_timer(&dsi.te_timer); 4479 init_timer(&dsi->te_timer);
3265 dsi.te_timer.function = dsi_te_timeout; 4480 dsi->te_timer.function = dsi_te_timeout;
3266 dsi.te_timer.data = 0; 4481 dsi->te_timer.data = 0;
3267#endif 4482#endif
3268 dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); 4483 dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
3269 if (!dsi.base) { 4484 if (!dsi_mem) {
4485 DSSERR("can't get IORESOURCE_MEM DSI\n");
4486 r = -EINVAL;
4487 goto err1;
4488 }
4489 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem));
4490 if (!dsi->base) {
3270 DSSERR("can't ioremap DSI\n"); 4491 DSSERR("can't ioremap DSI\n");
3271 r = -ENOMEM; 4492 r = -ENOMEM;
3272 goto err1; 4493 goto err1;
3273 } 4494 }
4495 dsi->irq = platform_get_irq(dsi->pdev, 0);
4496 if (dsi->irq < 0) {
4497 DSSERR("platform_get_irq failed\n");
4498 r = -ENODEV;
4499 goto err2;
4500 }
3274 4501
3275 dsi.vdds_dsi_reg = dss_get_vdds_dsi(); 4502 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED,
3276 if (IS_ERR(dsi.vdds_dsi_reg)) { 4503 dev_name(&dsidev->dev), dsi->pdev);
3277 iounmap(dsi.base); 4504 if (r < 0) {
3278 DSSERR("can't get VDDS_DSI regulator\n"); 4505 DSSERR("request_irq failed\n");
3279 r = PTR_ERR(dsi.vdds_dsi_reg);
3280 goto err2; 4506 goto err2;
3281 } 4507 }
3282 4508
4509 /* DSI VCs initialization */
4510 for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
4511 dsi->vc[i].mode = DSI_VC_MODE_L4;
4512 dsi->vc[i].dssdev = NULL;
4513 dsi->vc[i].vc_id = 0;
4514 }
4515
4516 dsi_calc_clock_param_ranges(dsidev);
4517
3283 enable_clocks(1); 4518 enable_clocks(1);
3284 4519
3285 rev = dsi_read_reg(DSI_REVISION); 4520 rev = dsi_read_reg(dsidev, DSI_REVISION);
3286 printk(KERN_INFO "OMAP DSI rev %d.%d\n", 4521 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
3287 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 4522 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3288 4523
4524 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
4525
3289 enable_clocks(0); 4526 enable_clocks(0);
3290 4527
3291 return 0; 4528 return 0;
3292err2: 4529err2:
3293 iounmap(dsi.base); 4530 iounmap(dsi->base);
3294err1: 4531err1:
3295 destroy_workqueue(dsi.workqueue); 4532 kfree(dsi);
4533err0:
3296 return r; 4534 return r;
3297} 4535}
3298 4536
3299void dsi_exit(void) 4537static void dsi_exit(struct platform_device *dsidev)
3300{ 4538{
3301 iounmap(dsi.base); 4539 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4540
4541 if (dsi->vdds_dsi_reg != NULL) {
4542 if (dsi->vdds_dsi_enabled) {
4543 regulator_disable(dsi->vdds_dsi_reg);
4544 dsi->vdds_dsi_enabled = false;
4545 }
4546
4547 regulator_put(dsi->vdds_dsi_reg);
4548 dsi->vdds_dsi_reg = NULL;
4549 }
3302 4550
3303 destroy_workqueue(dsi.workqueue); 4551 free_irq(dsi->irq, dsi->pdev);
4552 iounmap(dsi->base);
4553
4554 kfree(dsi);
3304 4555
3305 DSSDBG("omap_dsi_exit\n"); 4556 DSSDBG("omap_dsi_exit\n");
3306} 4557}
3307 4558
4559/* DSI1 HW IP initialisation */
4560static int omap_dsi1hw_probe(struct platform_device *dsidev)
4561{
4562 int r;
4563
4564 r = dsi_init(dsidev);
4565 if (r) {
4566 DSSERR("Failed to initialize DSI\n");
4567 goto err_dsi;
4568 }
4569err_dsi:
4570 return r;
4571}
4572
4573static int omap_dsi1hw_remove(struct platform_device *dsidev)
4574{
4575 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4576
4577 dsi_exit(dsidev);
4578 WARN_ON(dsi->scp_clk_refcount > 0);
4579 return 0;
4580}
4581
4582static struct platform_driver omap_dsi1hw_driver = {
4583 .probe = omap_dsi1hw_probe,
4584 .remove = omap_dsi1hw_remove,
4585 .driver = {
4586 .name = "omapdss_dsi1",
4587 .owner = THIS_MODULE,
4588 },
4589};
4590
4591int dsi_init_platform_driver(void)
4592{
4593 return platform_driver_register(&omap_dsi1hw_driver);
4594}
4595
4596void dsi_uninit_platform_driver(void)
4597{
4598 return platform_driver_unregister(&omap_dsi1hw_driver);
4599}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c3621c9171..d9489d5c4f08 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -26,14 +26,13 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/seq_file.h> 29#include <linux/seq_file.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32 31
33#include <plat/display.h> 32#include <video/omapdss.h>
33#include <plat/clock.h>
34#include "dss.h" 34#include "dss.h"
35 35#include "dss_features.h"
36#define DSS_BASE 0x48050000
37 36
38#define DSS_SZ_REGS SZ_512 37#define DSS_SZ_REGS SZ_512
39 38
@@ -46,7 +45,6 @@ struct dss_reg {
46#define DSS_REVISION DSS_REG(0x0000) 45#define DSS_REVISION DSS_REG(0x0000)
47#define DSS_SYSCONFIG DSS_REG(0x0010) 46#define DSS_SYSCONFIG DSS_REG(0x0010)
48#define DSS_SYSSTATUS DSS_REG(0x0014) 47#define DSS_SYSSTATUS DSS_REG(0x0014)
49#define DSS_IRQSTATUS DSS_REG(0x0018)
50#define DSS_CONTROL DSS_REG(0x0040) 48#define DSS_CONTROL DSS_REG(0x0040)
51#define DSS_SDI_CONTROL DSS_REG(0x0044) 49#define DSS_SDI_CONTROL DSS_REG(0x0044)
52#define DSS_PLL_CONTROL DSS_REG(0x0048) 50#define DSS_PLL_CONTROL DSS_REG(0x0048)
@@ -59,21 +57,41 @@ struct dss_reg {
59 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 57 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
60 58
61static struct { 59static struct {
60 struct platform_device *pdev;
62 void __iomem *base; 61 void __iomem *base;
62 int ctx_id;
63 63
64 struct clk *dpll4_m4_ck; 64 struct clk *dpll4_m4_ck;
65 struct clk *dss_ick;
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;
65 71
66 unsigned long cache_req_pck; 72 unsigned long cache_req_pck;
67 unsigned long cache_prate; 73 unsigned long cache_prate;
68 struct dss_clock_info cache_dss_cinfo; 74 struct dss_clock_info cache_dss_cinfo;
69 struct dispc_clock_info cache_dispc_cinfo; 75 struct dispc_clock_info cache_dispc_cinfo;
70 76
71 enum dss_clk_source dsi_clk_source; 77 enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
72 enum dss_clk_source dispc_clk_source; 78 enum omap_dss_clk_source dispc_clk_source;
79 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
73 80
74 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 81 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
75} dss; 82} dss;
76 83
84static const char * const dss_generic_clk_source_names[] = {
85 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
86 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
87 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
88};
89
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
77static int _omap_dss_wait_reset(void); 95static int _omap_dss_wait_reset(void);
78 96
79static inline void dss_write_reg(const struct dss_reg idx, u32 val) 97static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -99,10 +117,11 @@ void dss_save_context(void)
99 SR(SYSCONFIG); 117 SR(SYSCONFIG);
100 SR(CONTROL); 118 SR(CONTROL);
101 119
102#ifdef CONFIG_OMAP2_DSS_SDI 120 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
103 SR(SDI_CONTROL); 121 OMAP_DISPLAY_TYPE_SDI) {
104 SR(PLL_CONTROL); 122 SR(SDI_CONTROL);
105#endif 123 SR(PLL_CONTROL);
124 }
106} 125}
107 126
108void dss_restore_context(void) 127void dss_restore_context(void)
@@ -113,10 +132,11 @@ void dss_restore_context(void)
113 RR(SYSCONFIG); 132 RR(SYSCONFIG);
114 RR(CONTROL); 133 RR(CONTROL);
115 134
116#ifdef CONFIG_OMAP2_DSS_SDI 135 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
117 RR(SDI_CONTROL); 136 OMAP_DISPLAY_TYPE_SDI) {
118 RR(PLL_CONTROL); 137 RR(SDI_CONTROL);
119#endif 138 RR(PLL_CONTROL);
139 }
120} 140}
121 141
122#undef SR 142#undef SR
@@ -209,125 +229,235 @@ void dss_sdi_disable(void)
209 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 229 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
210} 230}
211 231
232const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
233{
234 return dss_generic_clk_source_names[clk_src];
235}
236
212void dss_dump_clocks(struct seq_file *s) 237void dss_dump_clocks(struct seq_file *s)
213{ 238{
214 unsigned long dpll4_ck_rate; 239 unsigned long dpll4_ck_rate;
215 unsigned long dpll4_m4_ck_rate; 240 unsigned long dpll4_m4_ck_rate;
241 const char *fclk_name, *fclk_real_name;
242 unsigned long fclk_rate;
216 243
217 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
218
219 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
220 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
221 245
222 seq_printf(s, "- DSS -\n"); 246 seq_printf(s, "- DSS -\n");
223 247
224 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); 248 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);
250 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
225 251
226 if (cpu_is_omap3630()) 252 if (dss.dpll4_m4_ck) {
227 seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", 253 dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
228 dpll4_ck_rate, 254 dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
229 dpll4_ck_rate / dpll4_m4_ck_rate, 255
230 dss_clk_get_rate(DSS_CLK_FCK1)); 256 seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
231 else
232 seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
233 dpll4_ck_rate,
234 dpll4_ck_rate / dpll4_m4_ck_rate,
235 dss_clk_get_rate(DSS_CLK_FCK1));
236 257
237 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 258 if (cpu_is_omap3630() || cpu_is_omap44xx())
259 seq_printf(s, "%s (%s) = %lu / %lu = %lu\n",
260 fclk_name, fclk_real_name,
261 dpll4_ck_rate,
262 dpll4_ck_rate / dpll4_m4_ck_rate,
263 fclk_rate);
264 else
265 seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
266 fclk_name, fclk_real_name,
267 dpll4_ck_rate,
268 dpll4_ck_rate / dpll4_m4_ck_rate,
269 fclk_rate);
270 } else {
271 seq_printf(s, "%s (%s) = %lu\n",
272 fclk_name, fclk_real_name,
273 fclk_rate);
274 }
275
276 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
238} 277}
239 278
240void dss_dump_regs(struct seq_file *s) 279void dss_dump_regs(struct seq_file *s)
241{ 280{
242#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 281#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
243 282
244 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 283 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
245 284
246 DUMPREG(DSS_REVISION); 285 DUMPREG(DSS_REVISION);
247 DUMPREG(DSS_SYSCONFIG); 286 DUMPREG(DSS_SYSCONFIG);
248 DUMPREG(DSS_SYSSTATUS); 287 DUMPREG(DSS_SYSSTATUS);
249 DUMPREG(DSS_IRQSTATUS);
250 DUMPREG(DSS_CONTROL); 288 DUMPREG(DSS_CONTROL);
251 DUMPREG(DSS_SDI_CONTROL);
252 DUMPREG(DSS_PLL_CONTROL);
253 DUMPREG(DSS_SDI_STATUS);
254 289
255 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 290 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
291 OMAP_DISPLAY_TYPE_SDI) {
292 DUMPREG(DSS_SDI_CONTROL);
293 DUMPREG(DSS_PLL_CONTROL);
294 DUMPREG(DSS_SDI_STATUS);
295 }
296
297 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
256#undef DUMPREG 298#undef DUMPREG
257} 299}
258 300
259void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 301void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
260{ 302{
303 struct platform_device *dsidev;
261 int b; 304 int b;
305 u8 start, end;
306
307 switch (clk_src) {
308 case OMAP_DSS_CLK_SRC_FCK:
309 b = 0;
310 break;
311 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
312 b = 1;
313 dsidev = dsi_get_dsidev_from_id(0);
314 dsi_wait_pll_hsdiv_dispc_active(dsidev);
315 break;
316 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
317 b = 2;
318 dsidev = dsi_get_dsidev_from_id(1);
319 dsi_wait_pll_hsdiv_dispc_active(dsidev);
320 break;
321 default:
322 BUG();
323 }
262 324
263 BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && 325 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
264 clk_src != DSS_SRC_DSS1_ALWON_FCLK);
265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270 326
271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 327 REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
272 328
273 dss.dispc_clk_source = clk_src; 329 dss.dispc_clk_source = clk_src;
274} 330}
275 331
276void dss_select_dsi_clk_source(enum dss_clk_source clk_src) 332void dss_select_dsi_clk_source(int dsi_module,
333 enum omap_dss_clk_source clk_src)
277{ 334{
335 struct platform_device *dsidev;
278 int b; 336 int b;
279 337
280 BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && 338 switch (clk_src) {
281 clk_src != DSS_SRC_DSS1_ALWON_FCLK); 339 case OMAP_DSS_CLK_SRC_FCK:
340 b = 0;
341 break;
342 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
343 BUG_ON(dsi_module != 0);
344 b = 1;
345 dsidev = dsi_get_dsidev_from_id(0);
346 dsi_wait_pll_hsdiv_dsi_active(dsidev);
347 break;
348 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
349 BUG_ON(dsi_module != 1);
350 b = 1;
351 dsidev = dsi_get_dsidev_from_id(1);
352 dsi_wait_pll_hsdiv_dsi_active(dsidev);
353 break;
354 default:
355 BUG();
356 }
282 357
283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 358 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
284 359
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK) 360 dss.dsi_clk_source[dsi_module] = clk_src;
286 dsi_wait_dsi2_pll_active(); 361}
287 362
288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 363void dss_select_lcd_clk_source(enum omap_channel channel,
364 enum omap_dss_clk_source clk_src)
365{
366 struct platform_device *dsidev;
367 int b, ix, pos;
289 368
290 dss.dsi_clk_source = clk_src; 369 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
370 return;
371
372 switch (clk_src) {
373 case OMAP_DSS_CLK_SRC_FCK:
374 b = 0;
375 break;
376 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
377 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
378 b = 1;
379 dsidev = dsi_get_dsidev_from_id(0);
380 dsi_wait_pll_hsdiv_dispc_active(dsidev);
381 break;
382 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
383 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2);
384 b = 1;
385 dsidev = dsi_get_dsidev_from_id(1);
386 dsi_wait_pll_hsdiv_dispc_active(dsidev);
387 break;
388 default:
389 BUG();
390 }
391
392 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12;
393 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
394
395 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
396 dss.lcd_clk_source[ix] = clk_src;
291} 397}
292 398
293enum dss_clk_source dss_get_dispc_clk_source(void) 399enum omap_dss_clk_source dss_get_dispc_clk_source(void)
294{ 400{
295 return dss.dispc_clk_source; 401 return dss.dispc_clk_source;
296} 402}
297 403
298enum dss_clk_source dss_get_dsi_clk_source(void) 404enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
299{ 405{
300 return dss.dsi_clk_source; 406 return dss.dsi_clk_source[dsi_module];
407}
408
409enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
410{
411 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
412 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
413 return dss.lcd_clk_source[ix];
414 } else {
415 /* LCD_CLK source is the same as DISPC_FCLK source for
416 * OMAP2 and OMAP3 */
417 return dss.dispc_clk_source;
418 }
301} 419}
302 420
303/* calculate clock rates using dividers in cinfo */ 421/* calculate clock rates using dividers in cinfo */
304int dss_calc_clock_rates(struct dss_clock_info *cinfo) 422int dss_calc_clock_rates(struct dss_clock_info *cinfo)
305{ 423{
306 unsigned long prate; 424 if (dss.dpll4_m4_ck) {
425 unsigned long prate;
426 u16 fck_div_max = 16;
307 427
308 if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) || 428 if (cpu_is_omap3630() || cpu_is_omap44xx())
309 cinfo->fck_div == 0) 429 fck_div_max = 32;
310 return -EINVAL; 430
431 if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
432 return -EINVAL;
311 433
312 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 434 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
313 435
314 cinfo->fck = prate / cinfo->fck_div; 436 cinfo->fck = prate / cinfo->fck_div;
437 } else {
438 if (cinfo->fck_div != 0)
439 return -EINVAL;
440 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
441 }
315 442
316 return 0; 443 return 0;
317} 444}
318 445
319int dss_set_clock_div(struct dss_clock_info *cinfo) 446int dss_set_clock_div(struct dss_clock_info *cinfo)
320{ 447{
321 unsigned long prate; 448 if (dss.dpll4_m4_ck) {
322 int r; 449 unsigned long prate;
450 int r;
323 451
324 if (cpu_is_omap34xx()) {
325 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 452 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
326 DSSDBG("dpll4_m4 = %ld\n", prate); 453 DSSDBG("dpll4_m4 = %ld\n", prate);
327 454
328 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 455 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
329 if (r) 456 if (r)
330 return r; 457 return r;
458 } else {
459 if (cinfo->fck_div != 0)
460 return -EINVAL;
331 } 461 }
332 462
333 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 463 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
@@ -337,12 +467,14 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
337 467
338int dss_get_clock_div(struct dss_clock_info *cinfo) 468int dss_get_clock_div(struct dss_clock_info *cinfo)
339{ 469{
340 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); 470 cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
341 471
342 if (cpu_is_omap34xx()) { 472 if (dss.dpll4_m4_ck) {
343 unsigned long prate; 473 unsigned long prate;
474
344 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 475 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
345 if (cpu_is_omap3630()) 476
477 if (cpu_is_omap3630() || cpu_is_omap44xx())
346 cinfo->fck_div = prate / (cinfo->fck); 478 cinfo->fck_div = prate / (cinfo->fck);
347 else 479 else
348 cinfo->fck_div = prate / (cinfo->fck / 2); 480 cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -355,7 +487,7 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
355 487
356unsigned long dss_get_dpll4_rate(void) 488unsigned long dss_get_dpll4_rate(void)
357{ 489{
358 if (cpu_is_omap34xx()) 490 if (dss.dpll4_m4_ck)
359 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 491 return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
360 else 492 else
361 return 0; 493 return 0;
@@ -369,16 +501,18 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
369 struct dss_clock_info best_dss; 501 struct dss_clock_info best_dss;
370 struct dispc_clock_info best_dispc; 502 struct dispc_clock_info best_dispc;
371 503
372 unsigned long fck; 504 unsigned long fck, max_dss_fck;
373 505
374 u16 fck_div; 506 u16 fck_div, fck_div_max = 16;
375 507
376 int match = 0; 508 int match = 0;
377 int min_fck_per_pck; 509 int min_fck_per_pck;
378 510
379 prate = dss_get_dpll4_rate(); 511 prate = dss_get_dpll4_rate();
380 512
381 fck = dss_clk_get_rate(DSS_CLK_FCK1); 513 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
514
515 fck = dss_clk_get_rate(DSS_CLK_FCK);
382 if (req_pck == dss.cache_req_pck && 516 if (req_pck == dss.cache_req_pck &&
383 ((cpu_is_omap34xx() && prate == dss.cache_prate) || 517 ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
384 dss.cache_dss_cinfo.fck == fck)) { 518 dss.cache_dss_cinfo.fck == fck)) {
@@ -391,7 +525,7 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
391 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; 525 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
392 526
393 if (min_fck_per_pck && 527 if (min_fck_per_pck &&
394 req_pck * min_fck_per_pck > DISPC_MAX_FCK) { 528 req_pck * min_fck_per_pck > max_dss_fck) {
395 DSSERR("Requested pixel clock not possible with the current " 529 DSSERR("Requested pixel clock not possible with the current "
396 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " 530 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
397 "the constraint off.\n"); 531 "the constraint off.\n");
@@ -402,10 +536,10 @@ retry:
402 memset(&best_dss, 0, sizeof(best_dss)); 536 memset(&best_dss, 0, sizeof(best_dss));
403 memset(&best_dispc, 0, sizeof(best_dispc)); 537 memset(&best_dispc, 0, sizeof(best_dispc));
404 538
405 if (cpu_is_omap24xx()) { 539 if (dss.dpll4_m4_ck == NULL) {
406 struct dispc_clock_info cur_dispc; 540 struct dispc_clock_info cur_dispc;
407 /* XXX can we change the clock on omap2? */ 541 /* XXX can we change the clock on omap2? */
408 fck = dss_clk_get_rate(DSS_CLK_FCK1); 542 fck = dss_clk_get_rate(DSS_CLK_FCK);
409 fck_div = 1; 543 fck_div = 1;
410 544
411 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); 545 dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -417,17 +551,19 @@ retry:
417 best_dispc = cur_dispc; 551 best_dispc = cur_dispc;
418 552
419 goto found; 553 goto found;
420 } else if (cpu_is_omap34xx()) { 554 } else {
421 for (fck_div = (cpu_is_omap3630() ? 32 : 16); 555 if (cpu_is_omap3630() || cpu_is_omap44xx())
422 fck_div > 0; --fck_div) { 556 fck_div_max = 32;
557
558 for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
423 struct dispc_clock_info cur_dispc; 559 struct dispc_clock_info cur_dispc;
424 560
425 if (cpu_is_omap3630()) 561 if (fck_div_max == 32)
426 fck = prate / fck_div; 562 fck = prate / fck_div;
427 else 563 else
428 fck = prate / fck_div * 2; 564 fck = prate / fck_div * 2;
429 565
430 if (fck > DISPC_MAX_FCK) 566 if (fck > max_dss_fck)
431 continue; 567 continue;
432 568
433 if (min_fck_per_pck && 569 if (min_fck_per_pck &&
@@ -450,8 +586,6 @@ retry:
450 goto found; 586 goto found;
451 } 587 }
452 } 588 }
453 } else {
454 BUG();
455 } 589 }
456 590
457found: 591found:
@@ -482,31 +616,6 @@ found:
482 return 0; 616 return 0;
483} 617}
484 618
485
486
487static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
488{
489 dispc_irq_handler();
490
491 return IRQ_HANDLED;
492}
493
494static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
495{
496 u32 irqstatus;
497
498 irqstatus = dss_read_reg(DSS_IRQSTATUS);
499
500 if (irqstatus & (1<<0)) /* DISPC_IRQ */
501 dispc_irq_handler();
502#ifdef CONFIG_OMAP2_DSS_DSI
503 if (irqstatus & (1<<1)) /* DSI_IRQ */
504 dsi_irq_handler();
505#endif
506
507 return IRQ_HANDLED;
508}
509
510static int _omap_dss_wait_reset(void) 619static int _omap_dss_wait_reset(void)
511{ 620{
512 int t = 0; 621 int t = 0;
@@ -549,34 +658,50 @@ void dss_set_dac_pwrdn_bgz(bool enable)
549 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ 658 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
550} 659}
551 660
552int dss_init(bool skip_init) 661void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
662{
663 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
664}
665
666static int dss_init(void)
553{ 667{
554 int r; 668 int r;
555 u32 rev; 669 u32 rev;
670 struct resource *dss_mem;
671 struct clk *dpll4_m4_ck;
556 672
557 dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); 673 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
674 if (!dss_mem) {
675 DSSERR("can't get IORESOURCE_MEM DSS\n");
676 r = -EINVAL;
677 goto fail0;
678 }
679 dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
558 if (!dss.base) { 680 if (!dss.base) {
559 DSSERR("can't ioremap DSS\n"); 681 DSSERR("can't ioremap DSS\n");
560 r = -ENOMEM; 682 r = -ENOMEM;
561 goto fail0; 683 goto fail0;
562 } 684 }
563 685
564 if (!skip_init) { 686 /* disable LCD and DIGIT output. This seems to fix the synclost
565 /* disable LCD and DIGIT output. This seems to fix the synclost 687 * problem that we get, if the bootloader starts the DSS and
566 * problem that we get, if the bootloader starts the DSS and 688 * the kernel resets it */
567 * the kernel resets it */ 689 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
568 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); 690
569 691#ifdef CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET
570 /* We need to wait here a bit, otherwise we sometimes start to 692 /* We need to wait here a bit, otherwise we sometimes start to
571 * get synclost errors, and after that only power cycle will 693 * get synclost errors, and after that only power cycle will
572 * restore DSS functionality. I have no idea why this happens. 694 * restore DSS functionality. I have no idea why this happens.
573 * And we have to wait _before_ resetting the DSS, but after 695 * And we have to wait _before_ resetting the DSS, but after
574 * enabling clocks. 696 * enabling clocks.
575 */ 697 *
576 msleep(50); 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
577 703
578 _omap_dss_reset(); 704 _omap_dss_reset();
579 }
580 705
581 /* autoidle */ 706 /* autoidle */
582 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); 707 REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
@@ -589,29 +714,31 @@ int dss_init(bool skip_init)
589 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 714 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
590 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 715 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
591#endif 716#endif
592
593 r = request_irq(INT_24XX_DSS_IRQ,
594 cpu_is_omap24xx()
595 ? dss_irq_handler_omap2
596 : dss_irq_handler_omap3,
597 0, "OMAP DSS", NULL);
598
599 if (r < 0) {
600 DSSERR("omap2 dss: request_irq failed\n");
601 goto fail1;
602 }
603
604 if (cpu_is_omap34xx()) { 717 if (cpu_is_omap34xx()) {
605 dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); 718 dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
606 if (IS_ERR(dss.dpll4_m4_ck)) { 719 if (IS_ERR(dpll4_m4_ck)) {
607 DSSERR("Failed to get dpll4_m4_ck\n"); 720 DSSERR("Failed to get dpll4_m4_ck\n");
608 r = PTR_ERR(dss.dpll4_m4_ck); 721 r = PTR_ERR(dpll4_m4_ck);
609 goto fail2; 722 goto fail1;
610 } 723 }
724 } else if (cpu_is_omap44xx()) {
725 dpll4_m4_ck = clk_get(NULL, "dpll_per_m5x2_ck");
726 if (IS_ERR(dpll4_m4_ck)) {
727 DSSERR("Failed to get dpll4_m4_ck\n");
728 r = PTR_ERR(dpll4_m4_ck);
729 goto fail1;
730 }
731 } else { /* omap24xx */
732 dpll4_m4_ck = NULL;
611 } 733 }
612 734
613 dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 735 dss.dpll4_m4_ck = dpll4_m4_ck;
614 dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; 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;
615 742
616 dss_save_context(); 743 dss_save_context();
617 744
@@ -621,21 +748,427 @@ int dss_init(bool skip_init)
621 748
622 return 0; 749 return 0;
623 750
624fail2:
625 free_irq(INT_24XX_DSS_IRQ, NULL);
626fail1: 751fail1:
627 iounmap(dss.base); 752 iounmap(dss.base);
628fail0: 753fail0:
629 return r; 754 return r;
630} 755}
631 756
632void dss_exit(void) 757static void dss_exit(void)
633{ 758{
634 if (cpu_is_omap34xx()) 759 if (dss.dpll4_m4_ck)
635 clk_put(dss.dpll4_m4_ck); 760 clk_put(dss.dpll4_m4_ck);
636 761
637 free_irq(INT_24XX_DSS_IRQ, NULL);
638
639 iounmap(dss.base); 762 iounmap(dss.base);
640} 763}
641 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;
901}
902
903static void dss_put_clocks(void)
904{
905 if (dss.dss_video_fck)
906 clk_put(dss.dss_video_fck);
907 if (dss.dss_tv_fck)
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}
987
988static void dss_clk_disable_no_ctx(enum dss_clock clks)
989{
990 unsigned num_clks = count_clk_bits(clks);
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}
1005
1006void dss_clk_disable(enum dss_clock clks)
1007{
1008 if (cpu_is_omap34xx()) {
1009 unsigned num_clks = count_clk_bits(clks);
1010
1011 BUG_ON(dss.num_clks_enabled < num_clks);
1012
1013 if (dss.num_clks_enabled == num_clks)
1014 save_all_ctx();
1015 }
1016
1017 dss_clk_disable_no_ctx(clks);
1018}
1019
1020static void dss_clk_enable_all_no_ctx(void)
1021{
1022 enum dss_clock clks;
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
1034 clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
1035 if (cpu_is_omap34xx())
1036 clks |= DSS_CLK_VIDFCK;
1037 dss_clk_disable_no_ctx(clks);
1038}
1039
1040#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1041/* CLOCKS */
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}
1077#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
1078
1079/* DEBUGFS */
1080#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
1081void dss_debug_dump_clocks(struct seq_file *s)
1082{
1083 core_dump_clocks(s);
1084 dss_dump_clocks(s);
1085 dispc_dump_clocks(s);
1086#ifdef CONFIG_OMAP2_DSS_DSI
1087 dsi_dump_clocks(s);
1088#endif
1089}
1090#endif
1091
1092
1093/* DSS HW IP initialisation */
1094static int omap_dsshw_probe(struct platform_device *pdev)
1095{
1096 int r;
1097
1098 dss.pdev = pdev;
1099
1100 r = dss_get_clocks();
1101 if (r)
1102 goto err_clocks;
1103
1104 dss_clk_enable_all_no_ctx();
1105
1106 dss.ctx_id = dss_get_ctx_id();
1107 DSSDBG("initial ctx id %u\n", dss.ctx_id);
1108
1109 r = dss_init();
1110 if (r) {
1111 DSSERR("Failed to initialize DSS\n");
1112 goto err_dss;
1113 }
1114
1115 r = dpi_init();
1116 if (r) {
1117 DSSERR("Failed to initialize DPI\n");
1118 goto err_dpi;
1119 }
1120
1121 r = sdi_init();
1122 if (r) {
1123 DSSERR("Failed to initialize SDI\n");
1124 goto err_sdi;
1125 }
1126
1127 dss_clk_disable_all_no_ctx();
1128 return 0;
1129err_sdi:
1130 dpi_exit();
1131err_dpi:
1132 dss_exit();
1133err_dss:
1134 dss_clk_disable_all_no_ctx();
1135 dss_put_clocks();
1136err_clocks:
1137 return r;
1138}
1139
1140static int omap_dsshw_remove(struct platform_device *pdev)
1141{
1142
1143 dss_exit();
1144
1145 /*
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
1153 dss_put_clocks();
1154 return 0;
1155}
1156
1157static struct platform_driver omap_dsshw_driver = {
1158 .probe = omap_dsshw_probe,
1159 .remove = omap_dsshw_remove,
1160 .driver = {
1161 .name = "omapdss_dss",
1162 .owner = THIS_MODULE,
1163 },
1164};
1165
1166int dss_init_platform_driver(void)
1167{
1168 return platform_driver_register(&omap_dsshw_driver);
1169}
1170
1171void dss_uninit_platform_driver(void)
1172{
1173 return platform_driver_unregister(&omap_dsshw_driver);
1174}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5c7940d5f282..8ab6d43329bb 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,8 +97,6 @@ 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
100#define DISPC_MAX_FCK 173000000
101
102enum omap_burst_size { 100enum omap_burst_size {
103 OMAP_DSS_BURST_4x32 = 0, 101 OMAP_DSS_BURST_4x32 = 0,
104 OMAP_DSS_BURST_8x32 = 1, 102 OMAP_DSS_BURST_8x32 = 1,
@@ -112,17 +110,16 @@ enum omap_parallel_interface_mode {
112}; 110};
113 111
114enum dss_clock { 112enum dss_clock {
115 DSS_CLK_ICK = 1 << 0, 113 DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
116 DSS_CLK_FCK1 = 1 << 1, 114 DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
117 DSS_CLK_FCK2 = 1 << 2, 115 DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
118 DSS_CLK_54M = 1 << 3, 116 DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
119 DSS_CLK_96M = 1 << 4, 117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
120}; 118};
121 119
122enum dss_clk_source { 120enum dss_hdmi_venc_clk_source_select {
123 DSS_SRC_DSI1_PLL_FCLK, 121 DSS_VENC_TV_CLK = 0,
124 DSS_SRC_DSI2_PLL_FCLK, 122 DSS_HDMI_M_PCLK = 1,
125 DSS_SRC_DSS1_ALWON_FCLK,
126}; 123};
127 124
128struct dss_clock_info { 125struct dss_clock_info {
@@ -148,36 +145,42 @@ struct dsi_clock_info {
148 unsigned long fint; 145 unsigned long fint;
149 unsigned long clkin4ddr; 146 unsigned long clkin4ddr;
150 unsigned long clkin; 147 unsigned long clkin;
151 unsigned long dsi1_pll_fclk; 148 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
152 unsigned long dsi2_pll_fclk; 149 * OMAP4: PLLx_CLK1 */
153 150 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
151 * OMAP4: PLLx_CLK2 */
154 unsigned long lp_clk; 152 unsigned long lp_clk;
155 153
156 /* dividers */ 154 /* dividers */
157 u16 regn; 155 u16 regn;
158 u16 regm; 156 u16 regm;
159 u16 regm3; 157 u16 regm_dispc; /* OMAP3: REGM3
160 u16 regm4; 158 * OMAP4: REGM4 */
161 159 u16 regm_dsi; /* OMAP3: REGM4
160 * OMAP4: REGM5 */
162 u16 lp_clk_div; 161 u16 lp_clk_div;
163 162
164 u8 highfreq; 163 u8 highfreq;
165 bool use_dss2_fck; 164 bool use_sys_clk;
165};
166
167/* HDMI PLL structure */
168struct hdmi_pll_info {
169 u16 regn;
170 u16 regm;
171 u32 regmf;
172 u16 regm2;
173 u16 regsd;
174 u16 dcofreq;
166}; 175};
167 176
168struct seq_file; 177struct seq_file;
169struct platform_device; 178struct platform_device;
170 179
171/* core */ 180/* core */
172void dss_clk_enable(enum dss_clock clks);
173void dss_clk_disable(enum dss_clock clks);
174unsigned long dss_clk_get_rate(enum dss_clock clk);
175int dss_need_ctx_restore(void);
176void dss_dump_clocks(struct seq_file *s);
177struct bus_type *dss_get_bus(void); 181struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void); 182struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void); 183struct regulator *dss_get_vdds_sdi(void);
180struct regulator *dss_get_vdda_dac(void);
181 184
182/* display */ 185/* display */
183int dss_suspend_all_devices(void); 186int dss_suspend_all_devices(void);
@@ -214,22 +217,36 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
214void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 217void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
215 218
216/* DSS */ 219/* DSS */
217int dss_init(bool skip_init); 220int dss_init_platform_driver(void);
218void dss_exit(void); 221void dss_uninit_platform_driver(void);
219 222
223void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
220void dss_save_context(void); 224void dss_save_context(void);
221void dss_restore_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);
231void dss_dump_clocks(struct seq_file *s);
222 232
223void dss_dump_regs(struct seq_file *s); 233void dss_dump_regs(struct seq_file *s);
234#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
235void dss_debug_dump_clocks(struct seq_file *s);
236#endif
224 237
225void dss_sdi_init(u8 datapairs); 238void dss_sdi_init(u8 datapairs);
226int dss_sdi_enable(void); 239int dss_sdi_enable(void);
227void dss_sdi_disable(void); 240void dss_sdi_disable(void);
228 241
229void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 242void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
230void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 243void dss_select_dsi_clk_source(int dsi_module,
231enum dss_clk_source dss_get_dispc_clk_source(void); 244 enum omap_dss_clk_source clk_src);
232enum dss_clk_source dss_get_dsi_clk_source(void); 245void dss_select_lcd_clk_source(enum omap_channel channel,
246 enum omap_dss_clk_source clk_src);
247enum omap_dss_clk_source dss_get_dispc_clk_source(void);
248enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module);
249enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
233 250
234void dss_set_venc_output(enum omap_dss_venc_type type); 251void dss_set_venc_output(enum omap_dss_venc_type type);
235void dss_set_dac_pwrdn_bgz(bool enable); 252void dss_set_dac_pwrdn_bgz(bool enable);
@@ -244,11 +261,11 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
244 261
245/* SDI */ 262/* SDI */
246#ifdef CONFIG_OMAP2_DSS_SDI 263#ifdef CONFIG_OMAP2_DSS_SDI
247int sdi_init(bool skip_init); 264int sdi_init(void);
248void sdi_exit(void); 265void sdi_exit(void);
249int sdi_init_display(struct omap_dss_device *display); 266int sdi_init_display(struct omap_dss_device *display);
250#else 267#else
251static inline int sdi_init(bool skip_init) 268static inline int sdi_init(void)
252{ 269{
253 return 0; 270 return 0;
254} 271}
@@ -259,54 +276,97 @@ static inline void sdi_exit(void)
259 276
260/* DSI */ 277/* DSI */
261#ifdef CONFIG_OMAP2_DSS_DSI 278#ifdef CONFIG_OMAP2_DSS_DSI
262int dsi_init(struct platform_device *pdev); 279
263void dsi_exit(void); 280struct dentry;
281struct file_operations;
282
283int dsi_init_platform_driver(void);
284void dsi_uninit_platform_driver(void);
264 285
265void dsi_dump_clocks(struct seq_file *s); 286void dsi_dump_clocks(struct seq_file *s);
266void dsi_dump_irqs(struct seq_file *s); 287void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
267void dsi_dump_regs(struct seq_file *s); 288 const struct file_operations *debug_fops);
289void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
290 const struct file_operations *debug_fops);
268 291
269void dsi_save_context(void); 292void dsi_save_context(void);
270void dsi_restore_context(void); 293void dsi_restore_context(void);
271 294
272int dsi_init_display(struct omap_dss_device *display); 295int dsi_init_display(struct omap_dss_device *display);
273void dsi_irq_handler(void); 296void dsi_irq_handler(void);
274unsigned long dsi_get_dsi1_pll_rate(void); 297unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
275int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); 298int dsi_pll_set_clock_div(struct platform_device *dsidev,
276int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 299 struct dsi_clock_info *cinfo);
277 struct dsi_clock_info *cinfo, 300int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
301 unsigned long req_pck, struct dsi_clock_info *cinfo,
278 struct dispc_clock_info *dispc_cinfo); 302 struct dispc_clock_info *dispc_cinfo);
279int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, 303int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
280 bool enable_hsdiv); 304 bool enable_hsdiv);
281void dsi_pll_uninit(void); 305void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 306void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
283 u32 fifo_size, enum omap_burst_size *burst_size, 307 u32 fifo_size, enum omap_burst_size *burst_size,
284 u32 *fifo_low, u32 *fifo_high); 308 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void); 309void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
286void dsi_wait_dsi2_pll_active(void); 310void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
311struct platform_device *dsi_get_dsidev_from_id(int module);
287#else 312#else
288static inline int dsi_init(struct platform_device *pdev) 313static inline int dsi_init_platform_driver(void)
289{ 314{
290 return 0; 315 return 0;
291} 316}
292static inline void dsi_exit(void) 317static inline void dsi_uninit_platform_driver(void)
318{
319}
320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
293{ 321{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
323 return 0;
294} 324}
295static inline void dsi_wait_dsi1_pll_active(void) 325static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
326 struct dsi_clock_info *cinfo)
296{ 327{
328 WARN("%s: DSI not compiled in\n", __func__);
329 return -ENODEV;
297} 330}
298static inline void dsi_wait_dsi2_pll_active(void) 331static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
332 bool is_tft, unsigned long req_pck,
333 struct dsi_clock_info *dsi_cinfo,
334 struct dispc_clock_info *dispc_cinfo)
299{ 335{
336 WARN("%s: DSI not compiled in\n", __func__);
337 return -ENODEV;
338}
339static inline int dsi_pll_init(struct platform_device *dsidev,
340 bool enable_hsclk, bool enable_hsdiv)
341{
342 WARN("%s: DSI not compiled in\n", __func__);
343 return -ENODEV;
344}
345static inline void dsi_pll_uninit(struct platform_device *dsidev,
346 bool disconnect_lanes)
347{
348}
349static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
350{
351}
352static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
353{
354}
355static inline struct platform_device *dsi_get_dsidev_from_id(int module)
356{
357 WARN("%s: DSI not compiled in, returning platform device as NULL\n",
358 __func__);
359 return NULL;
300} 360}
301#endif 361#endif
302 362
303/* DPI */ 363/* DPI */
304#ifdef CONFIG_OMAP2_DSS_DPI 364#ifdef CONFIG_OMAP2_DSS_DPI
305int dpi_init(struct platform_device *pdev); 365int dpi_init(void);
306void dpi_exit(void); 366void dpi_exit(void);
307int dpi_init_display(struct omap_dss_device *dssdev); 367int dpi_init_display(struct omap_dss_device *dssdev);
308#else 368#else
309static inline int dpi_init(struct platform_device *pdev) 369static inline int dpi_init(void)
310{ 370{
311 return 0; 371 return 0;
312} 372}
@@ -316,8 +376,8 @@ static inline void dpi_exit(void)
316#endif 376#endif
317 377
318/* DISPC */ 378/* DISPC */
319int dispc_init(void); 379int dispc_init_platform_driver(void);
320void dispc_exit(void); 380void dispc_uninit_platform_driver(void);
321void dispc_dump_clocks(struct seq_file *s); 381void dispc_dump_clocks(struct seq_file *s);
322void dispc_dump_irqs(struct seq_file *s); 382void dispc_dump_irqs(struct seq_file *s);
323void dispc_dump_regs(struct seq_file *s); 383void dispc_dump_regs(struct seq_file *s);
@@ -333,9 +393,9 @@ void dispc_disable_sidle(void);
333void dispc_lcd_enable_signal_polarity(bool act_high); 393void dispc_lcd_enable_signal_polarity(bool act_high);
334void dispc_lcd_enable_signal(bool enable); 394void dispc_lcd_enable_signal(bool enable);
335void dispc_pck_free_enable(bool enable); 395void dispc_pck_free_enable(bool enable);
336void dispc_enable_fifohandcheck(bool enable); 396void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
337 397
338void dispc_set_lcd_size(u16 width, u16 height); 398void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
339void dispc_set_digit_size(u16 width, u16 height); 399void dispc_set_digit_size(u16 width, u16 height);
340u32 dispc_get_plane_fifo_size(enum omap_plane plane); 400u32 dispc_get_plane_fifo_size(enum omap_plane plane);
341void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high); 401void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
@@ -350,6 +410,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
350void dispc_set_channel_out(enum omap_plane plane, 410void dispc_set_channel_out(enum omap_plane plane,
351 enum omap_channel channel_out); 411 enum omap_channel channel_out);
352 412
413void dispc_enable_gamma_table(bool enable);
353int dispc_setup_plane(enum omap_plane plane, 414int dispc_setup_plane(enum omap_plane plane,
354 u32 paddr, u16 screen_width, 415 u32 paddr, u16 screen_width,
355 u16 pos_x, u16 pos_y, 416 u16 pos_x, u16 pos_y,
@@ -359,7 +420,9 @@ int dispc_setup_plane(enum omap_plane plane,
359 bool ilace, 420 bool ilace,
360 enum omap_dss_rotation_type rotation_type, 421 enum omap_dss_rotation_type rotation_type,
361 u8 rotation, bool mirror, 422 u8 rotation, bool mirror,
362 u8 global_alpha); 423 u8 global_alpha, u8 pre_mult_alpha,
424 enum omap_channel channel,
425 u32 puv_addr);
363 426
364bool dispc_go_busy(enum omap_channel channel); 427bool dispc_go_busy(enum omap_channel channel);
365void dispc_go(enum omap_channel channel); 428void dispc_go(enum omap_channel channel);
@@ -368,9 +431,11 @@ bool dispc_is_channel_enabled(enum omap_channel channel);
368int dispc_enable_plane(enum omap_plane plane, bool enable); 431int dispc_enable_plane(enum omap_plane plane, bool enable);
369void dispc_enable_replication(enum omap_plane plane, bool enable); 432void dispc_enable_replication(enum omap_plane plane, bool enable);
370 433
371void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode); 434void dispc_set_parallel_interface_mode(enum omap_channel channel,
372void dispc_set_tft_data_lines(u8 data_lines); 435 enum omap_parallel_interface_mode mode);
373void dispc_set_lcd_display_type(enum omap_lcd_display_type type); 436void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
437void dispc_set_lcd_display_type(enum omap_channel channel,
438 enum omap_lcd_display_type type);
374void dispc_set_loadmode(enum omap_dss_load_mode mode); 439void dispc_set_loadmode(enum omap_dss_load_mode mode);
375 440
376void dispc_set_default_color(enum omap_channel channel, u32 color); 441void dispc_set_default_color(enum omap_channel channel, u32 color);
@@ -387,54 +452,77 @@ bool dispc_trans_key_enabled(enum omap_channel ch);
387bool dispc_alpha_blending_enabled(enum omap_channel ch); 452bool dispc_alpha_blending_enabled(enum omap_channel ch);
388 453
389bool dispc_lcd_timings_ok(struct omap_video_timings *timings); 454bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
390void dispc_set_lcd_timings(struct omap_video_timings *timings); 455void dispc_set_lcd_timings(enum omap_channel channel,
456 struct omap_video_timings *timings);
391unsigned long dispc_fclk_rate(void); 457unsigned long dispc_fclk_rate(void);
392unsigned long dispc_lclk_rate(void); 458unsigned long dispc_lclk_rate(enum omap_channel channel);
393unsigned long dispc_pclk_rate(void); 459unsigned long dispc_pclk_rate(enum omap_channel channel);
394void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb); 460void dispc_set_pol_freq(enum omap_channel channel,
461 enum omap_panel_config config, u8 acbi, u8 acb);
395void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 462void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
396 struct dispc_clock_info *cinfo); 463 struct dispc_clock_info *cinfo);
397int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 464int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
398 struct dispc_clock_info *cinfo); 465 struct dispc_clock_info *cinfo);
399int dispc_set_clock_div(struct dispc_clock_info *cinfo); 466int dispc_set_clock_div(enum omap_channel channel,
400int dispc_get_clock_div(struct dispc_clock_info *cinfo); 467 struct dispc_clock_info *cinfo);
468int dispc_get_clock_div(enum omap_channel channel,
469 struct dispc_clock_info *cinfo);
401 470
402 471
403/* VENC */ 472/* VENC */
404#ifdef CONFIG_OMAP2_DSS_VENC 473#ifdef CONFIG_OMAP2_DSS_VENC
405int venc_init(struct platform_device *pdev); 474int venc_init_platform_driver(void);
406void venc_exit(void); 475void venc_uninit_platform_driver(void);
407void venc_dump_regs(struct seq_file *s); 476void venc_dump_regs(struct seq_file *s);
408int venc_init_display(struct omap_dss_device *display); 477int venc_init_display(struct omap_dss_device *display);
409#else 478#else
410static inline int venc_init(struct platform_device *pdev) 479static inline int venc_init_platform_driver(void)
411{ 480{
412 return 0; 481 return 0;
413} 482}
414static inline void venc_exit(void) 483static inline void venc_uninit_platform_driver(void)
415{ 484{
416} 485}
417#endif 486#endif
418 487
488/* HDMI */
489#ifdef CONFIG_OMAP4_DSS_HDMI
490int hdmi_init_platform_driver(void);
491void hdmi_uninit_platform_driver(void);
492int hdmi_init_display(struct omap_dss_device *dssdev);
493#else
494static inline int hdmi_init_display(struct omap_dss_device *dssdev)
495{
496 return 0;
497}
498static inline int hdmi_init_platform_driver(void)
499{
500 return 0;
501}
502static inline void hdmi_uninit_platform_driver(void)
503{
504}
505#endif
506int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
507void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
508void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
509int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
510 struct omap_video_timings *timings);
511int hdmi_panel_init(void);
512void hdmi_panel_exit(void);
513
419/* RFBI */ 514/* RFBI */
420#ifdef CONFIG_OMAP2_DSS_RFBI 515#ifdef CONFIG_OMAP2_DSS_RFBI
421int rfbi_init(void); 516int rfbi_init_platform_driver(void);
422void rfbi_exit(void); 517void rfbi_uninit_platform_driver(void);
423void rfbi_dump_regs(struct seq_file *s); 518void rfbi_dump_regs(struct seq_file *s);
424
425int rfbi_configure(int rfbi_module, int bpp, int lines);
426void rfbi_enable_rfbi(bool enable);
427void rfbi_transfer_area(u16 width, u16 height,
428 void (callback)(void *data), void *data);
429void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
430unsigned long rfbi_get_max_tx_rate(void);
431int rfbi_init_display(struct omap_dss_device *display); 519int rfbi_init_display(struct omap_dss_device *display);
432#else 520#else
433static inline int rfbi_init(void) 521static inline int rfbi_init_platform_driver(void)
434{ 522{
435 return 0; 523 return 0;
436} 524}
437static inline void rfbi_exit(void) 525static inline void rfbi_uninit_platform_driver(void)
438{ 526{
439} 527}
440#endif 528#endif
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
new file mode 100644
index 000000000000..1c18888e5df3
--- /dev/null
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -0,0 +1,433 @@
1/*
2 * linux/drivers/video/omap2/dss/dss_features.c
3 *
4 * Copyright (C) 2010 Texas Instruments
5 * Author: Archit Taneja <archit@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/types.h>
22#include <linux/err.h>
23#include <linux/slab.h>
24
25#include <video/omapdss.h>
26#include <plat/cpu.h>
27
28#include "dss.h"
29#include "dss_features.h"
30
31/* Defines a generic omap register field */
32struct dss_reg_field {
33 u8 start, end;
34};
35
36struct dss_param_range {
37 int min, max;
38};
39
40struct omap_dss_features {
41 const struct dss_reg_field *reg_fields;
42 const int num_reg_fields;
43
44 const u32 has_feature;
45
46 const int num_mgrs;
47 const int num_ovls;
48 const enum omap_display_type *supported_displays;
49 const enum omap_color_mode *supported_color_modes;
50 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params;
52};
53
54/* This struct is assigned to one of the below during initialization */
55static const struct omap_dss_features *omap_current_dss_features;
56
57static const struct dss_reg_field omap2_dss_reg_fields[] = {
58 [FEAT_REG_FIRHINC] = { 11, 0 },
59 [FEAT_REG_FIRVINC] = { 27, 16 },
60 [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
61 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
62 [FEAT_REG_FIFOSIZE] = { 8, 0 },
63 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
64 [FEAT_REG_VERTICALACCU] = { 25, 16 },
65 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
66 [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
67 [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
68 [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
69 [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
70};
71
72static const struct dss_reg_field omap3_dss_reg_fields[] = {
73 [FEAT_REG_FIRHINC] = { 12, 0 },
74 [FEAT_REG_FIRVINC] = { 28, 16 },
75 [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
76 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
77 [FEAT_REG_FIFOSIZE] = { 10, 0 },
78 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
79 [FEAT_REG_VERTICALACCU] = { 25, 16 },
80 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
81 [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
82 [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
83 [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
84 [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
85};
86
87static const struct dss_reg_field omap4_dss_reg_fields[] = {
88 [FEAT_REG_FIRHINC] = { 12, 0 },
89 [FEAT_REG_FIRVINC] = { 28, 16 },
90 [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
91 [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
92 [FEAT_REG_FIFOSIZE] = { 15, 0 },
93 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
94 [FEAT_REG_VERTICALACCU] = { 26, 16 },
95 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
96 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
97 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
98 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
99 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
100};
101
102static const enum omap_display_type omap2_dss_supported_displays[] = {
103 /* OMAP_DSS_CHANNEL_LCD */
104 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
105
106 /* OMAP_DSS_CHANNEL_DIGIT */
107 OMAP_DISPLAY_TYPE_VENC,
108};
109
110static const enum omap_display_type omap3430_dss_supported_displays[] = {
111 /* OMAP_DSS_CHANNEL_LCD */
112 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
113 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
114
115 /* OMAP_DSS_CHANNEL_DIGIT */
116 OMAP_DISPLAY_TYPE_VENC,
117};
118
119static const enum omap_display_type omap3630_dss_supported_displays[] = {
120 /* OMAP_DSS_CHANNEL_LCD */
121 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
122 OMAP_DISPLAY_TYPE_DSI,
123
124 /* OMAP_DSS_CHANNEL_DIGIT */
125 OMAP_DISPLAY_TYPE_VENC,
126};
127
128static const enum omap_display_type omap4_dss_supported_displays[] = {
129 /* OMAP_DSS_CHANNEL_LCD */
130 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
131
132 /* OMAP_DSS_CHANNEL_DIGIT */
133 OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
134
135 /* OMAP_DSS_CHANNEL_LCD2 */
136 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
137 OMAP_DISPLAY_TYPE_DSI,
138};
139
140static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
141 /* OMAP_DSS_GFX */
142 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
143 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
144 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
145 OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P,
146
147 /* OMAP_DSS_VIDEO1 */
148 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
149 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
150 OMAP_DSS_COLOR_UYVY,
151
152 /* OMAP_DSS_VIDEO2 */
153 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
154 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
155 OMAP_DSS_COLOR_UYVY,
156};
157
158static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
159 /* OMAP_DSS_GFX */
160 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
161 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
162 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
163 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
164 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
165 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
166
167 /* OMAP_DSS_VIDEO1 */
168 OMAP_DSS_COLOR_RGB24U | OMAP_DSS_COLOR_RGB24P |
169 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_RGB16 |
170 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY,
171
172 /* OMAP_DSS_VIDEO2 */
173 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
174 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
175 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_YUV2 |
176 OMAP_DSS_COLOR_UYVY | OMAP_DSS_COLOR_ARGB32 |
177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
178};
179
180static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
181 /* OMAP_DSS_GFX */
182 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
183 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
184 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
185 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
186 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
187 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 |
188 OMAP_DSS_COLOR_ARGB16_1555,
189
190 /* OMAP_DSS_VIDEO1 */
191 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
192 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
193 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
194 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
195 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
196 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
197 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
198 OMAP_DSS_COLOR_RGBX32,
199
200 /* OMAP_DSS_VIDEO2 */
201 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
202 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
203 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
204 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
205 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
206 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
207 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
208 OMAP_DSS_COLOR_RGBX32,
209};
210
211static const char * const omap2_dss_clk_source_names[] = {
212 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
213 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
214 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK1",
215};
216
217static const char * const omap3_dss_clk_source_names[] = {
218 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
219 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
220 [OMAP_DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
221};
222
223static const char * const omap4_dss_clk_source_names[] = {
224 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
225 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
226 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK",
227 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1",
228 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2",
229};
230
231static const struct dss_param_range omap2_dss_param_range[] = {
232 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
233 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
234 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
235 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
236 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
237 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
238 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
239};
240
241static const struct dss_param_range omap3_dss_param_range[] = {
242 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
243 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
244 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
245 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
246 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
247 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
248 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
249};
250
251static const struct dss_param_range omap4_dss_param_range[] = {
252 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
253 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
254 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
255 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
256 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
257 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
258 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
259};
260
261/* OMAP2 DSS Features */
262static const struct omap_dss_features omap2_dss_features = {
263 .reg_fields = omap2_dss_reg_fields,
264 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
265
266 .has_feature =
267 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
268 FEAT_PCKFREEENABLE | FEAT_FUNCGATED |
269 FEAT_ROWREPEATENABLE | FEAT_RESIZECONF,
270
271 .num_mgrs = 2,
272 .num_ovls = 3,
273 .supported_displays = omap2_dss_supported_displays,
274 .supported_color_modes = omap2_dss_supported_color_modes,
275 .clksrc_names = omap2_dss_clk_source_names,
276 .dss_params = omap2_dss_param_range,
277};
278
279/* OMAP3 DSS Features */
280static const struct omap_dss_features omap3430_dss_features = {
281 .reg_fields = omap3_dss_reg_fields,
282 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
283
284 .has_feature =
285 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
286 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
287 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
288 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
289 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC,
290
291 .num_mgrs = 2,
292 .num_ovls = 3,
293 .supported_displays = omap3430_dss_supported_displays,
294 .supported_color_modes = omap3_dss_supported_color_modes,
295 .clksrc_names = omap3_dss_clk_source_names,
296 .dss_params = omap3_dss_param_range,
297};
298
299static const struct omap_dss_features omap3630_dss_features = {
300 .reg_fields = omap3_dss_reg_fields,
301 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
302
303 .has_feature =
304 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
305 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
306 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
307 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
308 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
309 FEAT_DSI_PLL_FREQSEL,
310
311 .num_mgrs = 2,
312 .num_ovls = 3,
313 .supported_displays = omap3630_dss_supported_displays,
314 .supported_color_modes = omap3_dss_supported_color_modes,
315 .clksrc_names = omap3_dss_clk_source_names,
316 .dss_params = omap3_dss_param_range,
317};
318
319/* OMAP4 DSS Features */
320/* For OMAP4430 ES 1.0 revision */
321static const struct omap_dss_features omap4430_es1_0_dss_features = {
322 .reg_fields = omap4_dss_reg_fields,
323 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
324
325 .has_feature =
326 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
327 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
328 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
329 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
330 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
331
332 .num_mgrs = 3,
333 .num_ovls = 3,
334 .supported_displays = omap4_dss_supported_displays,
335 .supported_color_modes = omap4_dss_supported_color_modes,
336 .clksrc_names = omap4_dss_clk_source_names,
337 .dss_params = omap4_dss_param_range,
338};
339
340/* For all the other OMAP4 versions */
341static const struct omap_dss_features omap4_dss_features = {
342 .reg_fields = omap4_dss_reg_fields,
343 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
344
345 .has_feature =
346 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
347 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
348 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
349 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
350 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
351 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
352
353 .num_mgrs = 3,
354 .num_ovls = 3,
355 .supported_displays = omap4_dss_supported_displays,
356 .supported_color_modes = omap4_dss_supported_color_modes,
357 .clksrc_names = omap4_dss_clk_source_names,
358 .dss_params = omap4_dss_param_range,
359};
360
361/* Functions returning values related to a DSS feature */
362int dss_feat_get_num_mgrs(void)
363{
364 return omap_current_dss_features->num_mgrs;
365}
366
367int dss_feat_get_num_ovls(void)
368{
369 return omap_current_dss_features->num_ovls;
370}
371
372unsigned long dss_feat_get_param_min(enum dss_range_param param)
373{
374 return omap_current_dss_features->dss_params[param].min;
375}
376
377unsigned long dss_feat_get_param_max(enum dss_range_param param)
378{
379 return omap_current_dss_features->dss_params[param].max;
380}
381
382enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
383{
384 return omap_current_dss_features->supported_displays[channel];
385}
386
387enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
388{
389 return omap_current_dss_features->supported_color_modes[plane];
390}
391
392bool dss_feat_color_mode_supported(enum omap_plane plane,
393 enum omap_color_mode color_mode)
394{
395 return omap_current_dss_features->supported_color_modes[plane] &
396 color_mode;
397}
398
399const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
400{
401 return omap_current_dss_features->clksrc_names[id];
402}
403
404/* DSS has_feature check */
405bool dss_has_feature(enum dss_feat_id id)
406{
407 return omap_current_dss_features->has_feature & id;
408}
409
410void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
411{
412 if (id >= omap_current_dss_features->num_reg_fields)
413 BUG();
414
415 *start = omap_current_dss_features->reg_fields[id].start;
416 *end = omap_current_dss_features->reg_fields[id].end;
417}
418
419void dss_features_init(void)
420{
421 if (cpu_is_omap24xx())
422 omap_current_dss_features = &omap2_dss_features;
423 else if (cpu_is_omap3630())
424 omap_current_dss_features = &omap3630_dss_features;
425 else if (cpu_is_omap34xx())
426 omap_current_dss_features = &omap3430_dss_features;
427 else if (omap_rev() == OMAP4430_REV_ES1_0)
428 omap_current_dss_features = &omap4430_es1_0_dss_features;
429 else if (cpu_is_omap44xx())
430 omap_current_dss_features = &omap4_dss_features;
431 else
432 DSSWARN("Unsupported OMAP version");
433}
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
new file mode 100644
index 000000000000..07b346f7d916
--- /dev/null
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -0,0 +1,96 @@
1/*
2 * linux/drivers/video/omap2/dss/dss_features.h
3 *
4 * Copyright (C) 2010 Texas Instruments
5 * Author: Archit Taneja <archit@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef __OMAP2_DSS_FEATURES_H
21#define __OMAP2_DSS_FEATURES_H
22
23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2
26#define MAX_NUM_DSI 2
27
28/* DSS has feature id */
29enum dss_feat_id {
30 FEAT_GLOBAL_ALPHA = 1 << 0,
31 FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
32 FEAT_PRE_MULT_ALPHA = 1 << 2,
33 FEAT_LCDENABLEPOL = 1 << 3,
34 FEAT_LCDENABLESIGNAL = 1 << 4,
35 FEAT_PCKFREEENABLE = 1 << 5,
36 FEAT_FUNCGATED = 1 << 6,
37 FEAT_MGR_LCD2 = 1 << 7,
38 FEAT_LINEBUFFERSPLIT = 1 << 8,
39 FEAT_ROWREPEATENABLE = 1 << 9,
40 FEAT_RESIZECONF = 1 << 10,
41 /* Independent core clk divider */
42 FEAT_CORE_CLK_DIV = 1 << 11,
43 FEAT_LCD_CLK_SRC = 1 << 12,
44 /* DSI-PLL power command 0x3 is not working */
45 FEAT_DSI_PLL_PWR_BUG = 1 << 13,
46 FEAT_DSI_PLL_FREQSEL = 1 << 14,
47 FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15,
48 FEAT_DSI_VC_OCP_WIDTH = 1 << 16,
49 FEAT_DSI_REVERSE_TXCLKESC = 1 << 17,
50 FEAT_DSI_GNQ = 1 << 18,
51 FEAT_HDMI_CTS_SWMODE = 1 << 19,
52 FEAT_HANDLE_UV_SEPARATE = 1 << 20,
53 FEAT_ATTR2 = 1 << 21,
54};
55
56/* DSS register field id */
57enum dss_feat_reg_field {
58 FEAT_REG_FIRHINC,
59 FEAT_REG_FIRVINC,
60 FEAT_REG_FIFOHIGHTHRESHOLD,
61 FEAT_REG_FIFOLOWTHRESHOLD,
62 FEAT_REG_FIFOSIZE,
63 FEAT_REG_HORIZONTALACCU,
64 FEAT_REG_VERTICALACCU,
65 FEAT_REG_DISPC_CLK_SWITCH,
66 FEAT_REG_DSIPLL_REGN,
67 FEAT_REG_DSIPLL_REGM,
68 FEAT_REG_DSIPLL_REGM_DISPC,
69 FEAT_REG_DSIPLL_REGM_DSI,
70};
71
72enum dss_range_param {
73 FEAT_PARAM_DSS_FCK,
74 FEAT_PARAM_DSIPLL_REGN,
75 FEAT_PARAM_DSIPLL_REGM,
76 FEAT_PARAM_DSIPLL_REGM_DISPC,
77 FEAT_PARAM_DSIPLL_REGM_DSI,
78 FEAT_PARAM_DSIPLL_FINT,
79 FEAT_PARAM_DSIPLL_LPDIV,
80};
81
82/* DSS Feature Functions */
83int dss_feat_get_num_mgrs(void);
84int dss_feat_get_num_ovls(void);
85unsigned long dss_feat_get_param_min(enum dss_range_param param);
86unsigned long dss_feat_get_param_max(enum dss_range_param param);
87enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
88enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
89bool dss_feat_color_mode_supported(enum omap_plane plane,
90 enum omap_color_mode color_mode);
91const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
92
93bool dss_has_feature(enum dss_feat_id id);
94void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
95void dss_features_init(void);
96#endif
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
new file mode 100644
index 000000000000..b0555f4f0a78
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -0,0 +1,1763 @@
1/*
2 * hdmi.c
3 *
4 * HDMI interface DSS driver setting for TI's OMAP4 family of processor.
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#define DSS_SUBSYS_NAME "HDMI"
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/interrupt.h>
29#include <linux/mutex.h>
30#include <linux/delay.h>
31#include <linux/string.h>
32#include <video/omapdss.h>
33#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
34 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
35#include <sound/soc.h>
36#include <sound/pcm_params.h>
37#endif
38
39#include "dss.h"
40#include "hdmi.h"
41#include "dss_features.h"
42
43static struct {
44 struct mutex lock;
45 struct omap_display_platform_data *pdata;
46 struct platform_device *pdev;
47 void __iomem *base_wp; /* HDMI wrapper */
48 int code;
49 int mode;
50 u8 edid[HDMI_EDID_MAX_LENGTH];
51 u8 edid_set;
52 bool custom_set;
53 struct hdmi_config cfg;
54} hdmi;
55
56/*
57 * Logic for the below structure :
58 * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
59 * There is a correspondence between CEA/VESA timing and code, please
60 * refer to section 6.3 in HDMI 1.3 specification for timing code.
61 *
62 * In the below structure, cea_vesa_timings corresponds to all OMAP4
63 * supported CEA and VESA timing values.code_cea corresponds to the CEA
64 * code, It is used to get the timing from cea_vesa_timing array.Similarly
65 * with code_vesa. Code_index is used for back mapping, that is once EDID
66 * is read from the TV, EDID is parsed to find the timing values and then
67 * map it to corresponding CEA or VESA index.
68 */
69
70static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
71 { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
72 { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
73 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
74 { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
75 { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
76 { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
77 { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
78 { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
79 { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
80 { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
81 { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
82 { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
83 { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
84 { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
85 { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
86 /* VESA From Here */
87 { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
88 { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
89 { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
90 { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
91 { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
92 { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1},
93 { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
94 { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
95 { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
96 { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
97 { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
98 { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
99 { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
100 { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
101 { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
102 { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
103 { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
104 { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
105 { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
106};
107
108/*
109 * This is a static mapping array which maps the timing values
110 * with corresponding CEA / VESA code
111 */
112static const int code_index[OMAP_HDMI_TIMINGS_NB] = {
113 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
114 /* <--15 CEA 17--> vesa*/
115 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
116 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
117};
118
119/*
120 * This is reverse static mapping which maps the CEA / VESA code
121 * to the corresponding timing values
122 */
123static const int code_cea[39] = {
124 -1, 0, 3, 3, 2, 8, 5, 5, -1, -1,
125 -1, -1, -1, -1, -1, -1, 9, 10, 10, 1,
126 7, 6, 6, -1, -1, -1, -1, -1, -1, 11,
127 11, 12, 14, -1, -1, 13, 13, 4, 4
128};
129
130static const int code_vesa[85] = {
131 -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
132 -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
133 -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
134 -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
135 -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
136 -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
137 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
138 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
139 -1, 27, 28, -1, 33};
140
141static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
142
143static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
144{
145 __raw_writel(val, hdmi.base_wp + idx.idx);
146}
147
148static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
149{
150 return __raw_readl(hdmi.base_wp + idx.idx);
151}
152
153static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
154 int b2, int b1, u32 val)
155{
156 u32 t = 0;
157 while (val != REG_GET(idx, b2, b1)) {
158 udelay(1);
159 if (t++ > 10000)
160 return !val;
161 }
162 return val;
163}
164
165int hdmi_init_display(struct omap_dss_device *dssdev)
166{
167 DSSDBG("init_display\n");
168
169 return 0;
170}
171
172static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
173 struct hdmi_pll_info *fmt, u16 sd)
174{
175 u32 r;
176
177 /* PLL start always use manual mode */
178 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
179
180 r = hdmi_read_reg(PLLCTRL_CFG1);
181 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
182 r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
183
184 hdmi_write_reg(PLLCTRL_CFG1, r);
185
186 r = hdmi_read_reg(PLLCTRL_CFG2);
187
188 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
189 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
190 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
191
192 if (dcofreq) {
193 /* divider programming for frequency beyond 1000Mhz */
194 REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
195 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
196 } else {
197 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
198 }
199
200 hdmi_write_reg(PLLCTRL_CFG2, r);
201
202 r = hdmi_read_reg(PLLCTRL_CFG4);
203 r = FLD_MOD(r, fmt->regm2, 24, 18);
204 r = FLD_MOD(r, fmt->regmf, 17, 0);
205
206 hdmi_write_reg(PLLCTRL_CFG4, r);
207
208 /* go now */
209 REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
210
211 /* wait for bit change */
212 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
213 DSSERR("PLL GO bit not set\n");
214 return -ETIMEDOUT;
215 }
216
217 /* Wait till the lock bit is set in PLL status */
218 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
219 DSSWARN("cannot lock PLL\n");
220 DSSWARN("CFG1 0x%x\n",
221 hdmi_read_reg(PLLCTRL_CFG1));
222 DSSWARN("CFG2 0x%x\n",
223 hdmi_read_reg(PLLCTRL_CFG2));
224 DSSWARN("CFG4 0x%x\n",
225 hdmi_read_reg(PLLCTRL_CFG4));
226 return -ETIMEDOUT;
227 }
228
229 DSSDBG("PLL locked!\n");
230
231 return 0;
232}
233
234/* PHY_PWR_CMD */
235static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
236{
237 /* Command for power control of HDMI PHY */
238 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
239
240 /* Status of the power control of HDMI PHY */
241 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
242 DSSERR("Failed to set PHY power mode to %d\n", val);
243 return -ETIMEDOUT;
244 }
245
246 return 0;
247}
248
249/* PLL_PWR_CMD */
250static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
251{
252 /* Command for power control of HDMI PLL */
253 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
254
255 /* wait till PHY_PWR_STATUS is set */
256 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
257 DSSERR("Failed to set PHY_PWR_STATUS\n");
258 return -ETIMEDOUT;
259 }
260
261 return 0;
262}
263
264static int hdmi_pll_reset(void)
265{
266 /* SYSRESET controlled by power FSM */
267 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
268
269 /* READ 0x0 reset is in progress */
270 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
271 DSSERR("Failed to sysreset PLL\n");
272 return -ETIMEDOUT;
273 }
274
275 return 0;
276}
277
278static int hdmi_phy_init(void)
279{
280 u16 r = 0;
281
282 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
283 if (r)
284 return r;
285
286 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
287 if (r)
288 return r;
289
290 /*
291 * Read address 0 in order to get the SCP reset done completed
292 * Dummy access performed to make sure reset is done
293 */
294 hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
295
296 /*
297 * Write to phy address 0 to configure the clock
298 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
299 */
300 REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
301
302 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
303 hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
304
305 /* Setup max LDO voltage */
306 REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
307
308 /* Write to phy address 3 to change the polarity control */
309 REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
310
311 return 0;
312}
313
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)
329{
330 u16 r = 0;
331 enum hdmi_clk_refsel refsel;
332
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);
339 if (r)
340 return r;
341
342 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
343 if (r)
344 return r;
345
346 r = hdmi_pll_reset();
347 if (r)
348 return r;
349
350 refsel = HDMI_REFSEL_SYSCLK;
351
352 r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
353 if (r)
354 return r;
355
356 return 0;
357}
358
359static void hdmi_phy_off(void)
360{
361 hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
362}
363
364static int hdmi_core_ddc_edid(u8 *pedid, int ext)
365{
366 u32 i, j;
367 char checksum = 0;
368 u32 offset = 0;
369
370 /* Turn on CLK for DDC */
371 REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
372
373 /*
374 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
375 * right shifted values( The behavior is not consistent and seen only
376 * with some TV's)
377 */
378 usleep_range(800, 1000);
379
380 if (!ext) {
381 /* Clk SCL Devices */
382 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
383
384 /* HDMI_CORE_DDC_STATUS_IN_PROG */
385 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
386 4, 4, 0) != 0) {
387 DSSERR("Failed to program DDC\n");
388 return -ETIMEDOUT;
389 }
390
391 /* Clear FIFO */
392 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
393
394 /* HDMI_CORE_DDC_STATUS_IN_PROG */
395 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
396 4, 4, 0) != 0) {
397 DSSERR("Failed to program DDC\n");
398 return -ETIMEDOUT;
399 }
400
401 } else {
402 if (ext % 2 != 0)
403 offset = 0x80;
404 }
405
406 /* Load Segment Address Register */
407 REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
408
409 /* Load Slave Address Register */
410 REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
411
412 /* Load Offset Address Register */
413 REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
414
415 /* Load Byte Count */
416 REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
417 REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
418
419 /* Set DDC_CMD */
420 if (ext)
421 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
422 else
423 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
424
425 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
426 if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
427 DSSWARN("I2C Bus Low?\n");
428 return -EIO;
429 }
430 /* HDMI_CORE_DDC_STATUS_NO_ACK */
431 if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
432 DSSWARN("I2C No Ack\n");
433 return -EIO;
434 }
435
436 i = ext * 128;
437 j = 0;
438 while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
439 (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
440 j < 128) {
441
442 if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
443 /* FIFO not empty */
444 pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
445 j++;
446 }
447 }
448
449 for (j = 0; j < 128; j++)
450 checksum += pedid[j];
451
452 if (checksum != 0) {
453 DSSERR("E-EDID checksum failed!!\n");
454 return -EIO;
455 }
456
457 return 0;
458}
459
460static int read_edid(u8 *pedid, u16 max_length)
461{
462 int r = 0, n = 0, i = 0;
463 int max_ext_blocks = (max_length / 128) - 1;
464
465 r = hdmi_core_ddc_edid(pedid, 0);
466 if (r) {
467 return r;
468 } else {
469 n = pedid[0x7e];
470
471 /*
472 * README: need to comply with max_length set by the caller.
473 * Better implementation should be to allocate necessary
474 * memory to store EDID according to nb_block field found
475 * in first block
476 */
477 if (n > max_ext_blocks)
478 n = max_ext_blocks;
479
480 for (i = 1; i <= n; i++) {
481 r = hdmi_core_ddc_edid(pedid, i);
482 if (r)
483 return r;
484 }
485 }
486 return 0;
487}
488
489static int get_timings_index(void)
490{
491 int code;
492
493 if (hdmi.mode == 0)
494 code = code_vesa[hdmi.code];
495 else
496 code = code_cea[hdmi.code];
497
498 if (code == -1) {
499 /* HDMI code 4 corresponds to 640 * 480 VGA */
500 hdmi.code = 4;
501 /* DVI mode 1 corresponds to HDMI 0 to DVI */
502 hdmi.mode = HDMI_DVI;
503
504 code = code_vesa[hdmi.code];
505 }
506 return code;
507}
508
509static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
510{
511 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
512 int timing_vsync = 0, timing_hsync = 0;
513 struct omap_video_timings temp;
514 struct hdmi_cm cm = {-1};
515 DSSDBG("hdmi_get_code\n");
516
517 for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
518 temp = cea_vesa_timings[i].timings;
519 if ((temp.pixel_clock == timing->pixel_clock) &&
520 (temp.x_res == timing->x_res) &&
521 (temp.y_res == timing->y_res)) {
522
523 temp_hsync = temp.hfp + temp.hsw + temp.hbp;
524 timing_hsync = timing->hfp + timing->hsw + timing->hbp;
525 temp_vsync = temp.vfp + temp.vsw + temp.vbp;
526 timing_vsync = timing->vfp + timing->vsw + timing->vbp;
527
528 DSSDBG("temp_hsync = %d , temp_vsync = %d"
529 "timing_hsync = %d, timing_vsync = %d\n",
530 temp_hsync, temp_hsync,
531 timing_hsync, timing_vsync);
532
533 if ((temp_hsync == timing_hsync) &&
534 (temp_vsync == timing_vsync)) {
535 code = i;
536 cm.code = code_index[i];
537 if (code < 14)
538 cm.mode = HDMI_HDMI;
539 else
540 cm.mode = HDMI_DVI;
541 DSSDBG("Hdmi_code = %d mode = %d\n",
542 cm.code, cm.mode);
543 break;
544 }
545 }
546 }
547
548 return cm;
549}
550
551static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
552 struct omap_video_timings *timings)
553{
554 /* X and Y resolution */
555 timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
556 edid[current_descriptor_addrs + 2]);
557 timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
558 edid[current_descriptor_addrs + 5]);
559
560 timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
561 edid[current_descriptor_addrs]);
562
563 timings->pixel_clock = 10 * timings->pixel_clock;
564
565 /* HORIZONTAL FRONT PORCH */
566 timings->hfp = edid[current_descriptor_addrs + 8] |
567 ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
568 /* HORIZONTAL SYNC WIDTH */
569 timings->hsw = edid[current_descriptor_addrs + 9] |
570 ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
571 /* HORIZONTAL BACK PORCH */
572 timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
573 edid[current_descriptor_addrs + 3]) -
574 (timings->hfp + timings->hsw);
575 /* VERTICAL FRONT PORCH */
576 timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
577 ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
578 /* VERTICAL SYNC WIDTH */
579 timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
580 ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
581 /* VERTICAL BACK PORCH */
582 timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
583 edid[current_descriptor_addrs + 6]) -
584 (timings->vfp + timings->vsw);
585
586}
587
588/* Description : This function gets the resolution information from EDID */
589static void get_edid_timing_data(u8 *edid)
590{
591 u8 count;
592 u16 current_descriptor_addrs;
593 struct hdmi_cm cm;
594 struct omap_video_timings edid_timings;
595
596 /* search block 0, there are 4 DTDs arranged in priority order */
597 for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
598 current_descriptor_addrs =
599 EDID_DESCRIPTOR_BLOCK0_ADDRESS +
600 count * EDID_TIMING_DESCRIPTOR_SIZE;
601 get_horz_vert_timing_info(current_descriptor_addrs,
602 edid, &edid_timings);
603 cm = hdmi_get_code(&edid_timings);
604 DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
605 count, cm.code, cm.mode);
606 if (cm.code == -1) {
607 continue;
608 } else {
609 hdmi.code = cm.code;
610 hdmi.mode = cm.mode;
611 DSSDBG("code = %d , mode = %d\n",
612 hdmi.code, hdmi.mode);
613 return;
614 }
615 }
616 if (edid[0x7e] != 0x00) {
617 for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
618 count++) {
619 current_descriptor_addrs =
620 EDID_DESCRIPTOR_BLOCK1_ADDRESS +
621 count * EDID_TIMING_DESCRIPTOR_SIZE;
622 get_horz_vert_timing_info(current_descriptor_addrs,
623 edid, &edid_timings);
624 cm = hdmi_get_code(&edid_timings);
625 DSSDBG("Block1[%d] value matches code = %d, mode = %d",
626 count, cm.code, cm.mode);
627 if (cm.code == -1) {
628 continue;
629 } else {
630 hdmi.code = cm.code;
631 hdmi.mode = cm.mode;
632 DSSDBG("code = %d , mode = %d\n",
633 hdmi.code, hdmi.mode);
634 return;
635 }
636 }
637 }
638
639 DSSINFO("no valid timing found , falling back to VGA\n");
640 hdmi.code = 4; /* setting default value of 640 480 VGA */
641 hdmi.mode = HDMI_DVI;
642}
643
644static void hdmi_read_edid(struct omap_video_timings *dp)
645{
646 int ret = 0, code;
647
648 memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
649
650 if (!hdmi.edid_set)
651 ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
652
653 if (!ret) {
654 if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
655 /* search for timings of default resolution */
656 get_edid_timing_data(hdmi.edid);
657 hdmi.edid_set = true;
658 }
659 } else {
660 DSSWARN("failed to read E-EDID\n");
661 }
662
663 if (!hdmi.edid_set) {
664 DSSINFO("fallback to VGA\n");
665 hdmi.code = 4; /* setting default value of 640 480 VGA */
666 hdmi.mode = HDMI_DVI;
667 }
668
669 code = get_timings_index();
670
671 *dp = cea_vesa_timings[code].timings;
672}
673
674static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
675 struct hdmi_core_infoframe_avi *avi_cfg,
676 struct hdmi_core_packet_enable_repeat *repeat_cfg)
677{
678 DSSDBG("Enter hdmi_core_init\n");
679
680 /* video core */
681 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
682 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
683 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
684 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
685 video_cfg->hdmi_dvi = HDMI_DVI;
686 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
687
688 /* info frame */
689 avi_cfg->db1_format = 0;
690 avi_cfg->db1_active_info = 0;
691 avi_cfg->db1_bar_info_dv = 0;
692 avi_cfg->db1_scan_info = 0;
693 avi_cfg->db2_colorimetry = 0;
694 avi_cfg->db2_aspect_ratio = 0;
695 avi_cfg->db2_active_fmt_ar = 0;
696 avi_cfg->db3_itc = 0;
697 avi_cfg->db3_ec = 0;
698 avi_cfg->db3_q_range = 0;
699 avi_cfg->db3_nup_scaling = 0;
700 avi_cfg->db4_videocode = 0;
701 avi_cfg->db5_pixel_repeat = 0;
702 avi_cfg->db6_7_line_eoftop = 0 ;
703 avi_cfg->db8_9_line_sofbottom = 0;
704 avi_cfg->db10_11_pixel_eofleft = 0;
705 avi_cfg->db12_13_pixel_sofright = 0;
706
707 /* packet enable and repeat */
708 repeat_cfg->audio_pkt = 0;
709 repeat_cfg->audio_pkt_repeat = 0;
710 repeat_cfg->avi_infoframe = 0;
711 repeat_cfg->avi_infoframe_repeat = 0;
712 repeat_cfg->gen_cntrl_pkt = 0;
713 repeat_cfg->gen_cntrl_pkt_repeat = 0;
714 repeat_cfg->generic_pkt = 0;
715 repeat_cfg->generic_pkt_repeat = 0;
716}
717
718static void hdmi_core_powerdown_disable(void)
719{
720 DSSDBG("Enter hdmi_core_powerdown_disable\n");
721 REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
722}
723
724static void hdmi_core_swreset_release(void)
725{
726 DSSDBG("Enter hdmi_core_swreset_release\n");
727 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
728}
729
730static void hdmi_core_swreset_assert(void)
731{
732 DSSDBG("Enter hdmi_core_swreset_assert\n");
733 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
734}
735
736/* DSS_HDMI_CORE_VIDEO_CONFIG */
737static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
738{
739 u32 r = 0;
740
741 /* sys_ctrl1 default configuration not tunable */
742 r = hdmi_read_reg(HDMI_CORE_CTRL1);
743 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
744 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
745 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
746 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
747 hdmi_write_reg(HDMI_CORE_CTRL1, r);
748
749 REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
750
751 /* Vid_Mode */
752 r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
753
754 /* dither truncation configuration */
755 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
756 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
757 r = FLD_MOD(r, 1, 5, 5);
758 } else {
759 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
760 r = FLD_MOD(r, 0, 5, 5);
761 }
762 hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
763
764 /* HDMI_Ctrl */
765 r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
766 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
767 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
768 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
769 hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
770
771 /* TMDS_CTRL */
772 REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
773 cfg->tclk_sel_clkmult, 6, 5);
774}
775
776static void hdmi_core_aux_infoframe_avi_config(
777 struct hdmi_core_infoframe_avi info_avi)
778{
779 u32 val;
780 char sum = 0, checksum = 0;
781
782 sum += 0x82 + 0x002 + 0x00D;
783 hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
784 hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
785 hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
786
787 val = (info_avi.db1_format << 5) |
788 (info_avi.db1_active_info << 4) |
789 (info_avi.db1_bar_info_dv << 2) |
790 (info_avi.db1_scan_info);
791 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
792 sum += val;
793
794 val = (info_avi.db2_colorimetry << 6) |
795 (info_avi.db2_aspect_ratio << 4) |
796 (info_avi.db2_active_fmt_ar);
797 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
798 sum += val;
799
800 val = (info_avi.db3_itc << 7) |
801 (info_avi.db3_ec << 4) |
802 (info_avi.db3_q_range << 2) |
803 (info_avi.db3_nup_scaling);
804 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
805 sum += val;
806
807 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
808 sum += info_avi.db4_videocode;
809
810 val = info_avi.db5_pixel_repeat;
811 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
812 sum += val;
813
814 val = info_avi.db6_7_line_eoftop & 0x00FF;
815 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
816 sum += val;
817
818 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
819 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
820 sum += val;
821
822 val = info_avi.db8_9_line_sofbottom & 0x00FF;
823 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
824 sum += val;
825
826 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
827 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
828 sum += val;
829
830 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
831 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
832 sum += val;
833
834 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
835 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
836 sum += val;
837
838 val = info_avi.db12_13_pixel_sofright & 0x00FF;
839 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
840 sum += val;
841
842 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
843 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
844 sum += val;
845
846 checksum = 0x100 - sum;
847 hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
848}
849
850static void hdmi_core_av_packet_config(
851 struct hdmi_core_packet_enable_repeat repeat_cfg)
852{
853 /* enable/repeat the infoframe */
854 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
855 (repeat_cfg.audio_pkt << 5) |
856 (repeat_cfg.audio_pkt_repeat << 4) |
857 (repeat_cfg.avi_infoframe << 1) |
858 (repeat_cfg.avi_infoframe_repeat));
859
860 /* enable/repeat the packet */
861 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
862 (repeat_cfg.gen_cntrl_pkt << 3) |
863 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
864 (repeat_cfg.generic_pkt << 1) |
865 (repeat_cfg.generic_pkt_repeat));
866}
867
868static void hdmi_wp_init(struct omap_video_timings *timings,
869 struct hdmi_video_format *video_fmt,
870 struct hdmi_video_interface *video_int)
871{
872 DSSDBG("Enter hdmi_wp_init\n");
873
874 timings->hbp = 0;
875 timings->hfp = 0;
876 timings->hsw = 0;
877 timings->vbp = 0;
878 timings->vfp = 0;
879 timings->vsw = 0;
880
881 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
882 video_fmt->y_res = 0;
883 video_fmt->x_res = 0;
884
885 video_int->vsp = 0;
886 video_int->hsp = 0;
887
888 video_int->interlacing = 0;
889 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
890
891}
892
893static void hdmi_wp_video_start(bool start)
894{
895 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
896}
897
898static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
899 struct omap_video_timings *timings, struct hdmi_config *param)
900{
901 DSSDBG("Enter hdmi_wp_video_init_format\n");
902
903 video_fmt->y_res = param->timings.timings.y_res;
904 video_fmt->x_res = param->timings.timings.x_res;
905
906 timings->hbp = param->timings.timings.hbp;
907 timings->hfp = param->timings.timings.hfp;
908 timings->hsw = param->timings.timings.hsw;
909 timings->vbp = param->timings.timings.vbp;
910 timings->vfp = param->timings.timings.vfp;
911 timings->vsw = param->timings.timings.vsw;
912}
913
914static void hdmi_wp_video_config_format(
915 struct hdmi_video_format *video_fmt)
916{
917 u32 l = 0;
918
919 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
920
921 l |= FLD_VAL(video_fmt->y_res, 31, 16);
922 l |= FLD_VAL(video_fmt->x_res, 15, 0);
923 hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
924}
925
926static void hdmi_wp_video_config_interface(
927 struct hdmi_video_interface *video_int)
928{
929 u32 r;
930 DSSDBG("Enter hdmi_wp_video_config_interface\n");
931
932 r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
933 r = FLD_MOD(r, video_int->vsp, 7, 7);
934 r = FLD_MOD(r, video_int->hsp, 6, 6);
935 r = FLD_MOD(r, video_int->interlacing, 3, 3);
936 r = FLD_MOD(r, video_int->tm, 1, 0);
937 hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
938}
939
940static void hdmi_wp_video_config_timing(
941 struct omap_video_timings *timings)
942{
943 u32 timing_h = 0;
944 u32 timing_v = 0;
945
946 DSSDBG("Enter hdmi_wp_video_config_timing\n");
947
948 timing_h |= FLD_VAL(timings->hbp, 31, 20);
949 timing_h |= FLD_VAL(timings->hfp, 19, 8);
950 timing_h |= FLD_VAL(timings->hsw, 7, 0);
951 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
952
953 timing_v |= FLD_VAL(timings->vbp, 31, 20);
954 timing_v |= FLD_VAL(timings->vfp, 19, 8);
955 timing_v |= FLD_VAL(timings->vsw, 7, 0);
956 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
957}
958
959static void hdmi_basic_configure(struct hdmi_config *cfg)
960{
961 /* HDMI */
962 struct omap_video_timings video_timing;
963 struct hdmi_video_format video_format;
964 struct hdmi_video_interface video_interface;
965 /* HDMI core */
966 struct hdmi_core_infoframe_avi avi_cfg;
967 struct hdmi_core_video_config v_core_cfg;
968 struct hdmi_core_packet_enable_repeat repeat_cfg;
969
970 hdmi_wp_init(&video_timing, &video_format,
971 &video_interface);
972
973 hdmi_core_init(&v_core_cfg,
974 &avi_cfg,
975 &repeat_cfg);
976
977 hdmi_wp_video_init_format(&video_format,
978 &video_timing, cfg);
979
980 hdmi_wp_video_config_timing(&video_timing);
981
982 /* video config */
983 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
984
985 hdmi_wp_video_config_format(&video_format);
986
987 video_interface.vsp = cfg->timings.vsync_pol;
988 video_interface.hsp = cfg->timings.hsync_pol;
989 video_interface.interlacing = cfg->interlace;
990 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
991
992 hdmi_wp_video_config_interface(&video_interface);
993
994 /*
995 * configure core video part
996 * set software reset in the core
997 */
998 hdmi_core_swreset_assert();
999
1000 /* power down off */
1001 hdmi_core_powerdown_disable();
1002
1003 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
1004 v_core_cfg.hdmi_dvi = cfg->cm.mode;
1005
1006 hdmi_core_video_config(&v_core_cfg);
1007
1008 /* release software reset in the core */
1009 hdmi_core_swreset_release();
1010
1011 /*
1012 * configure packet
1013 * info frame video see doc CEA861-D page 65
1014 */
1015 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
1016 avi_cfg.db1_active_info =
1017 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
1018 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
1019 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
1020 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
1021 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
1022 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
1023 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
1024 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
1025 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
1026 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
1027 avi_cfg.db4_videocode = cfg->cm.code;
1028 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
1029 avi_cfg.db6_7_line_eoftop = 0;
1030 avi_cfg.db8_9_line_sofbottom = 0;
1031 avi_cfg.db10_11_pixel_eofleft = 0;
1032 avi_cfg.db12_13_pixel_sofright = 0;
1033
1034 hdmi_core_aux_infoframe_avi_config(avi_cfg);
1035
1036 /* enable/repeat the infoframe */
1037 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
1038 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
1039 /* wakeup */
1040 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
1041 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
1042 hdmi_core_av_packet_config(repeat_cfg);
1043}
1044
1045static void update_hdmi_timings(struct hdmi_config *cfg,
1046 struct omap_video_timings *timings, int code)
1047{
1048 cfg->timings.timings.x_res = timings->x_res;
1049 cfg->timings.timings.y_res = timings->y_res;
1050 cfg->timings.timings.hbp = timings->hbp;
1051 cfg->timings.timings.hfp = timings->hfp;
1052 cfg->timings.timings.hsw = timings->hsw;
1053 cfg->timings.timings.vbp = timings->vbp;
1054 cfg->timings.timings.vfp = timings->vfp;
1055 cfg->timings.timings.vsw = timings->vsw;
1056 cfg->timings.timings.pixel_clock = timings->pixel_clock;
1057 cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol;
1058 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1059}
1060
1061static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1062 struct hdmi_pll_info *pi)
1063{
1064 unsigned long clkin, refclk;
1065 u32 mf;
1066
1067 clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000;
1068 /*
1069 * Input clock is predivided by N + 1
1070 * out put of which is reference clk
1071 */
1072 pi->regn = dssdev->clocks.hdmi.regn;
1073 refclk = clkin / (pi->regn + 1);
1074
1075 /*
1076 * multiplier is pixel_clk/ref_clk
1077 * Multiplying by 100 to avoid fractional part removal
1078 */
1079 pi->regm = (phy * 100 / (refclk)) / 100;
1080 pi->regm2 = dssdev->clocks.hdmi.regm2;
1081
1082 /*
1083 * fractional multiplier is remainder of the difference between
1084 * multiplier and actual phy(required pixel clock thus should be
1085 * multiplied by 2^18(262144) divided by the reference clock
1086 */
1087 mf = (phy - pi->regm * refclk) * 262144;
1088 pi->regmf = mf / (refclk);
1089
1090 /*
1091 * Dcofreq should be set to 1 if required pixel clock
1092 * is greater than 1000MHz
1093 */
1094 pi->dcofreq = phy > 1000 * 100;
1095 pi->regsd = ((pi->regm * clkin / 10) / ((pi->regn + 1) * 250) + 5) / 10;
1096
1097 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1098 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
1099}
1100
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)
1112{
1113 int r, code = 0;
1114 struct hdmi_pll_info pll_data;
1115 struct omap_video_timings *p;
1116 unsigned long phy;
1117
1118 hdmi_enable_clocks(1);
1119
1120 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1121
1122 p = &dssdev->panel.timings;
1123
1124 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
1125 dssdev->panel.timings.x_res,
1126 dssdev->panel.timings.y_res);
1127
1128 if (!hdmi.custom_set) {
1129 DSSDBG("Read EDID as no EDID is not set on poweron\n");
1130 hdmi_read_edid(p);
1131 }
1132 code = get_timings_index();
1133 dssdev->panel.timings = cea_vesa_timings[code].timings;
1134 update_hdmi_timings(&hdmi.cfg, p, code);
1135
1136 phy = p->pixel_clock;
1137
1138 hdmi_compute_pll(dssdev, phy, &pll_data);
1139
1140 hdmi_wp_video_start(0);
1141
1142 /* config the PLL and PHY first */
1143 r = hdmi_pll_program(&pll_data);
1144 if (r) {
1145 DSSDBG("Failed to lock PLL\n");
1146 goto err;
1147 }
1148
1149 r = hdmi_phy_init();
1150 if (r) {
1151 DSSDBG("Failed to start PHY\n");
1152 goto err;
1153 }
1154
1155 hdmi.cfg.cm.mode = hdmi.mode;
1156 hdmi.cfg.cm.code = hdmi.code;
1157 hdmi_basic_configure(&hdmi.cfg);
1158
1159 /* Make selection of HDMI in DSS */
1160 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
1161
1162 /* Select the dispc clock source as PRCM clock, to ensure that it is not
1163 * DSI PLL source as the clock selected by DSI PLL might not be
1164 * sufficient for the resolution selected / that can be changed
1165 * dynamically by user. This can be moved to single location , say
1166 * Boardfile.
1167 */
1168 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
1169
1170 /* bypass TV gamma table */
1171 dispc_enable_gamma_table(0);
1172
1173 /* tv size */
1174 dispc_set_digit_size(dssdev->panel.timings.x_res,
1175 dssdev->panel.timings.y_res);
1176
1177 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
1178
1179 hdmi_wp_video_start(1);
1180
1181 return 0;
1182err:
1183 hdmi_enable_clocks(0);
1184 return -EIO;
1185}
1186
1187static void hdmi_power_off(struct omap_dss_device *dssdev)
1188{
1189 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
1190
1191 hdmi_wp_video_start(0);
1192 hdmi_phy_off();
1193 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
1194 hdmi_enable_clocks(0);
1195
1196 hdmi.edid_set = 0;
1197}
1198
1199int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
1200 struct omap_video_timings *timings)
1201{
1202 struct hdmi_cm cm;
1203
1204 cm = hdmi_get_code(timings);
1205 if (cm.code == -1) {
1206 DSSERR("Invalid timing entered\n");
1207 return -EINVAL;
1208 }
1209
1210 return 0;
1211
1212}
1213
1214void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
1215{
1216 struct hdmi_cm cm;
1217
1218 hdmi.custom_set = 1;
1219 cm = hdmi_get_code(&dssdev->panel.timings);
1220 hdmi.code = cm.code;
1221 hdmi.mode = cm.mode;
1222 omapdss_hdmi_display_enable(dssdev);
1223 hdmi.custom_set = 0;
1224}
1225
1226int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
1227{
1228 int r = 0;
1229
1230 DSSDBG("ENTER hdmi_display_enable\n");
1231
1232 mutex_lock(&hdmi.lock);
1233
1234 r = omap_dss_start_device(dssdev);
1235 if (r) {
1236 DSSERR("failed to start device\n");
1237 goto err0;
1238 }
1239
1240 if (dssdev->platform_enable) {
1241 r = dssdev->platform_enable(dssdev);
1242 if (r) {
1243 DSSERR("failed to enable GPIO's\n");
1244 goto err1;
1245 }
1246 }
1247
1248 r = hdmi_power_on(dssdev);
1249 if (r) {
1250 DSSERR("failed to power on device\n");
1251 goto err2;
1252 }
1253
1254 mutex_unlock(&hdmi.lock);
1255 return 0;
1256
1257err2:
1258 if (dssdev->platform_disable)
1259 dssdev->platform_disable(dssdev);
1260err1:
1261 omap_dss_stop_device(dssdev);
1262err0:
1263 mutex_unlock(&hdmi.lock);
1264 return r;
1265}
1266
1267void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1268{
1269 DSSDBG("Enter hdmi_display_disable\n");
1270
1271 mutex_lock(&hdmi.lock);
1272
1273 hdmi_power_off(dssdev);
1274
1275 if (dssdev->platform_disable)
1276 dssdev->platform_disable(dssdev);
1277
1278 omap_dss_stop_device(dssdev);
1279
1280 mutex_unlock(&hdmi.lock);
1281}
1282
1283#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1284 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1285static void hdmi_wp_audio_config_format(
1286 struct hdmi_audio_format *aud_fmt)
1287{
1288 u32 r;
1289
1290 DSSDBG("Enter hdmi_wp_audio_config_format\n");
1291
1292 r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
1293 r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
1294 r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
1295 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
1296 r = FLD_MOD(r, aud_fmt->type, 4, 4);
1297 r = FLD_MOD(r, aud_fmt->justification, 3, 3);
1298 r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
1299 r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
1300 r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
1301 hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
1302}
1303
1304static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
1305{
1306 u32 r;
1307
1308 DSSDBG("Enter hdmi_wp_audio_config_dma\n");
1309
1310 r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
1311 r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
1312 r = FLD_MOD(r, aud_dma->block_size, 7, 0);
1313 hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);
1314
1315 r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
1316 r = FLD_MOD(r, aud_dma->mode, 9, 9);
1317 r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
1318 hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
1319}
1320
1321static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
1322{
1323 u32 r;
1324
1325 /* audio clock recovery parameters */
1326 r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
1327 r = FLD_MOD(r, cfg->use_mclk, 2, 2);
1328 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1329 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1330 hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);
1331
1332 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1333 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1334 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
1335
1336 if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
1337 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
1338 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
1339 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1340 } else {
1341 /*
1342 * HDMI IP uses this configuration to divide the MCLK to
1343 * update CTS value.
1344 */
1345 REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1346
1347 /* Configure clock for audio packets */
1348 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1349 cfg->aud_par_busclk, 7, 0);
1350 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
1351 (cfg->aud_par_busclk >> 8), 7, 0);
1352 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
1353 (cfg->aud_par_busclk >> 16), 7, 0);
1354 }
1355
1356 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1357 REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg->fs_override, 1, 1);
1358
1359 /* I2S parameters */
1360 REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg->freq_sample, 3, 0);
1361
1362 r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
1363 r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
1364 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
1365 r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
1366 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
1367 r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3);
1368 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
1369 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
1370 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
1371 hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);
1372
1373 r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
1374 r = FLD_MOD(r, cfg->freq_sample, 7, 4);
1375 r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
1376 r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
1377 hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);
1378
1379 REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg->i2s_cfg.in_length_bits, 3, 0);
1380
1381 /* Audio channels and mode parameters */
1382 REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
1383 r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
1384 r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
1385 r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
1386 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
1387 r = FLD_MOD(r, cfg->en_spdif, 1, 1);
1388 hdmi_write_reg(HDMI_CORE_AV_AUD_MODE, r);
1389}
1390
1391static void hdmi_core_audio_infoframe_config(
1392 struct hdmi_core_infoframe_audio *info_aud)
1393{
1394 u8 val;
1395 u8 sum = 0, checksum = 0;
1396
1397 /*
1398 * Set audio info frame type, version and length as
1399 * described in HDMI 1.4a Section 8.2.2 specification.
1400 * Checksum calculation is defined in Section 5.3.5.
1401 */
1402 hdmi_write_reg(HDMI_CORE_AV_AUDIO_TYPE, 0x84);
1403 hdmi_write_reg(HDMI_CORE_AV_AUDIO_VERS, 0x01);
1404 hdmi_write_reg(HDMI_CORE_AV_AUDIO_LEN, 0x0a);
1405 sum += 0x84 + 0x001 + 0x00a;
1406
1407 val = (info_aud->db1_coding_type << 4)
1408 | (info_aud->db1_channel_count - 1);
1409 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(0), val);
1410 sum += val;
1411
1412 val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
1413 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(1), val);
1414 sum += val;
1415
1416 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
1417
1418 val = info_aud->db4_channel_alloc;
1419 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(3), val);
1420 sum += val;
1421
1422 val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
1423 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(4), val);
1424 sum += val;
1425
1426 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
1427 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
1428 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
1429 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
1430 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
1431
1432 checksum = 0x100 - sum;
1433 hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum);
1434
1435 /*
1436 * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
1437 * is available.
1438 */
1439}
1440
1441static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
1442{
1443 u32 r;
1444 u32 deep_color = 0;
1445 u32 pclk = hdmi.cfg.timings.timings.pixel_clock;
1446
1447 if (n == NULL || cts == NULL)
1448 return -EINVAL;
1449 /*
1450 * Obtain current deep color configuration. This needed
1451 * to calculate the TMDS clock based on the pixel clock.
1452 */
1453 r = REG_GET(HDMI_WP_VIDEO_CFG, 1, 0);
1454 switch (r) {
1455 case 1: /* No deep color selected */
1456 deep_color = 100;
1457 break;
1458 case 2: /* 10-bit deep color selected */
1459 deep_color = 125;
1460 break;
1461 case 3: /* 12-bit deep color selected */
1462 deep_color = 150;
1463 break;
1464 default:
1465 return -EINVAL;
1466 }
1467
1468 switch (sample_freq) {
1469 case 32000:
1470 if ((deep_color == 125) && ((pclk == 54054)
1471 || (pclk == 74250)))
1472 *n = 8192;
1473 else
1474 *n = 4096;
1475 break;
1476 case 44100:
1477 *n = 6272;
1478 break;
1479 case 48000:
1480 if ((deep_color == 125) && ((pclk == 54054)
1481 || (pclk == 74250)))
1482 *n = 8192;
1483 else
1484 *n = 6144;
1485 break;
1486 default:
1487 *n = 0;
1488 return -EINVAL;
1489 }
1490
1491 /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
1492 *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
1493
1494 return 0;
1495}
1496
1497static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
1498 struct snd_pcm_hw_params *params,
1499 struct snd_soc_dai *dai)
1500{
1501 struct hdmi_audio_format audio_format;
1502 struct hdmi_audio_dma audio_dma;
1503 struct hdmi_core_audio_config core_cfg;
1504 struct hdmi_core_infoframe_audio aud_if_cfg;
1505 int err, n, cts;
1506 enum hdmi_core_audio_sample_freq sample_freq;
1507
1508 switch (params_format(params)) {
1509 case SNDRV_PCM_FORMAT_S16_LE:
1510 core_cfg.i2s_cfg.word_max_length =
1511 HDMI_AUDIO_I2S_MAX_WORD_20BITS;
1512 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
1513 core_cfg.i2s_cfg.in_length_bits =
1514 HDMI_AUDIO_I2S_INPUT_LENGTH_16;
1515 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
1516 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
1517 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
1518 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
1519 audio_dma.transfer_size = 0x10;
1520 break;
1521 case SNDRV_PCM_FORMAT_S24_LE:
1522 core_cfg.i2s_cfg.word_max_length =
1523 HDMI_AUDIO_I2S_MAX_WORD_24BITS;
1524 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
1525 core_cfg.i2s_cfg.in_length_bits =
1526 HDMI_AUDIO_I2S_INPUT_LENGTH_24;
1527 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
1528 audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
1529 audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
1530 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
1531 audio_dma.transfer_size = 0x20;
1532 break;
1533 default:
1534 return -EINVAL;
1535 }
1536
1537 switch (params_rate(params)) {
1538 case 32000:
1539 sample_freq = HDMI_AUDIO_FS_32000;
1540 break;
1541 case 44100:
1542 sample_freq = HDMI_AUDIO_FS_44100;
1543 break;
1544 case 48000:
1545 sample_freq = HDMI_AUDIO_FS_48000;
1546 break;
1547 default:
1548 return -EINVAL;
1549 }
1550
1551 err = hdmi_config_audio_acr(params_rate(params), &n, &cts);
1552 if (err < 0)
1553 return err;
1554
1555 /* Audio wrapper config */
1556 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
1557 audio_format.active_chnnls_msk = 0x03;
1558 audio_format.type = HDMI_AUDIO_TYPE_LPCM;
1559 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
1560 /* Disable start/stop signals of IEC 60958 blocks */
1561 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;
1562
1563 audio_dma.block_size = 0xC0;
1564 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
1565 audio_dma.fifo_threshold = 0x20; /* in number of samples */
1566
1567 hdmi_wp_audio_config_dma(&audio_dma);
1568 hdmi_wp_audio_config_format(&audio_format);
1569
1570 /*
1571 * I2S config
1572 */
1573 core_cfg.i2s_cfg.en_high_bitrate_aud = false;
1574 /* Only used with high bitrate audio */
1575 core_cfg.i2s_cfg.cbit_order = false;
1576 /* Serial data and word select should change on sck rising edge */
1577 core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
1578 core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
1579 /* Set I2S word select polarity */
1580 core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
1581 core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
1582 /* Set serial data to word select shift. See Phillips spec. */
1583 core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
1584 /* Enable one of the four available serial data channels */
1585 core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
1586
1587 /* Core audio config */
1588 core_cfg.freq_sample = sample_freq;
1589 core_cfg.n = n;
1590 core_cfg.cts = cts;
1591 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
1592 core_cfg.aud_par_busclk = 0;
1593 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
1594 core_cfg.use_mclk = false;
1595 } else {
1596 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
1597 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
1598 core_cfg.use_mclk = true;
1599 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
1600 }
1601 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
1602 core_cfg.en_spdif = false;
1603 /* Use sample frequency from channel status word */
1604 core_cfg.fs_override = true;
1605 /* Enable ACR packets */
1606 core_cfg.en_acr_pkt = true;
1607 /* Disable direct streaming digital audio */
1608 core_cfg.en_dsd_audio = false;
1609 /* Use parallel audio interface */
1610 core_cfg.en_parallel_aud_input = true;
1611
1612 hdmi_core_audio_config(&core_cfg);
1613
1614 /*
1615 * Configure packet
1616 * info frame audio see doc CEA861-D page 74
1617 */
1618 aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM;
1619 aud_if_cfg.db1_channel_count = 2;
1620 aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM;
1621 aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM;
1622 aud_if_cfg.db4_channel_alloc = 0x00;
1623 aud_if_cfg.db5_downmix_inh = false;
1624 aud_if_cfg.db5_lsv = 0;
1625
1626 hdmi_core_audio_infoframe_config(&aud_if_cfg);
1627 return 0;
1628}
1629
1630static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
1631 struct snd_soc_dai *dai)
1632{
1633 int err = 0;
1634 switch (cmd) {
1635 case SNDRV_PCM_TRIGGER_START:
1636 case SNDRV_PCM_TRIGGER_RESUME:
1637 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1638 REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
1639 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 31, 31);
1640 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 30, 30);
1641 break;
1642
1643 case SNDRV_PCM_TRIGGER_STOP:
1644 case SNDRV_PCM_TRIGGER_SUSPEND:
1645 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1646 REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
1647 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 30, 30);
1648 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 31, 31);
1649 break;
1650 default:
1651 err = -EINVAL;
1652 }
1653 return err;
1654}
1655
1656static int hdmi_audio_startup(struct snd_pcm_substream *substream,
1657 struct snd_soc_dai *dai)
1658{
1659 if (!hdmi.mode) {
1660 pr_err("Current video settings do not support audio.\n");
1661 return -EIO;
1662 }
1663 return 0;
1664}
1665
1666static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
1667};
1668
1669static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
1670 .hw_params = hdmi_audio_hw_params,
1671 .trigger = hdmi_audio_trigger,
1672 .startup = hdmi_audio_startup,
1673};
1674
1675static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
1676 .name = "hdmi-audio-codec",
1677 .playback = {
1678 .channels_min = 2,
1679 .channels_max = 2,
1680 .rates = SNDRV_PCM_RATE_32000 |
1681 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
1682 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1683 SNDRV_PCM_FMTBIT_S24_LE,
1684 },
1685 .ops = &hdmi_audio_codec_ops,
1686};
1687#endif
1688
1689/* HDMI HW IP initialisation */
1690static int omapdss_hdmihw_probe(struct platform_device *pdev)
1691{
1692 struct resource *hdmi_mem;
1693#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1694 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1695 int ret;
1696#endif
1697
1698 hdmi.pdata = pdev->dev.platform_data;
1699 hdmi.pdev = pdev;
1700
1701 mutex_init(&hdmi.lock);
1702
1703 hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
1704 if (!hdmi_mem) {
1705 DSSERR("can't get IORESOURCE_MEM HDMI\n");
1706 return -EINVAL;
1707 }
1708
1709 /* Base address taken from platform */
1710 hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
1711 if (!hdmi.base_wp) {
1712 DSSERR("can't ioremap WP\n");
1713 return -ENOMEM;
1714 }
1715
1716 hdmi_panel_init();
1717
1718#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1719 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1720
1721 /* Register ASoC codec DAI */
1722 ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
1723 &hdmi_codec_dai_drv, 1);
1724 if (ret) {
1725 DSSERR("can't register ASoC HDMI audio codec\n");
1726 return ret;
1727 }
1728#endif
1729 return 0;
1730}
1731
1732static int omapdss_hdmihw_remove(struct platform_device *pdev)
1733{
1734 hdmi_panel_exit();
1735
1736#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1737 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1738 snd_soc_unregister_codec(&pdev->dev);
1739#endif
1740
1741 iounmap(hdmi.base_wp);
1742
1743 return 0;
1744}
1745
1746static struct platform_driver omapdss_hdmihw_driver = {
1747 .probe = omapdss_hdmihw_probe,
1748 .remove = omapdss_hdmihw_remove,
1749 .driver = {
1750 .name = "omapdss_hdmi",
1751 .owner = THIS_MODULE,
1752 },
1753};
1754
1755int hdmi_init_platform_driver(void)
1756{
1757 return platform_driver_register(&omapdss_hdmihw_driver);
1758}
1759
1760void hdmi_uninit_platform_driver(void)
1761{
1762 return platform_driver_unregister(&omapdss_hdmihw_driver);
1763}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
new file mode 100644
index 000000000000..c885f9cb0659
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -0,0 +1,631 @@
1/*
2 * hdmi.h
3 *
4 * HDMI driver definition for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef _OMAP4_DSS_HDMI_H_
22#define _OMAP4_DSS_HDMI_H_
23
24#include <linux/string.h>
25#include <video/omapdss.h>
26
27#define HDMI_WP 0x0
28#define HDMI_CORE_SYS 0x400
29#define HDMI_CORE_AV 0x900
30#define HDMI_PLLCTRL 0x200
31#define HDMI_PHY 0x300
32
33struct hdmi_reg { u16 idx; };
34
35#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
36
37/* HDMI Wrapper */
38#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx)
39
40#define HDMI_WP_REVISION HDMI_WP_REG(0x0)
41#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10)
42#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24)
43#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28)
44#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40)
45#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C)
46#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50)
47#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60)
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
51#define HDMI_WP_AUDIO_CFG HDMI_WP_REG(0x80)
52#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84)
53#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88)
54#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
55
56/* HDMI IP Core System */
57#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
58
59#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0)
60#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8)
61#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC)
62#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10)
63#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14)
64#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20)
65#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24)
66#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124)
67#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128)
68#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0)
69#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4)
70#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8)
71#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC)
72#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0)
73#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4)
74#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208)
75#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8)
76#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC)
77#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0)
78#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8)
79#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC)
80#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0)
81#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
82#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
83#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
84#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
85#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
86
87/* HDMI DDC E-DID */
88#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC)
89#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8)
90#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4)
91#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC)
92#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0)
93#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4)
94#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0)
95#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8)
96
97/* HDMI IP Core Audio Video */
98#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx)
99
100#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
101#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
102#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
103#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
104#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
105#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
106#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
107#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
108#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110)
109#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
110#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
111#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
112#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x210)
113#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_CORE_AV_REG(10)
114#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
115#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
116#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
117#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
118#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380)
119#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31)
120#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4)
121#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8)
122#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC)
123#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10)
124#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14)
125#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18)
126#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C)
127#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20)
128#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24)
129#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28)
130#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C)
131#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50)
132#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54)
133#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60)
134#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64)
135#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C)
136#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70)
137#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74)
138#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78)
139#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C)
140#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80)
141#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84)
142#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88)
143#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C)
144#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90)
145#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC)
146#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0)
147#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC)
148#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0)
149#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4)
150#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0)
151#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4)
152#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8)
153#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC)
154#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100)
155#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104)
156#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108)
157#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C)
158#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180)
159#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
160#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
161#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
162#define HDMI_CORE_AV_AUDIO_TYPE HDMI_CORE_AV_REG(0x200)
163#define HDMI_CORE_AV_AUDIO_VERS HDMI_CORE_AV_REG(0x204)
164#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208)
165#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_CORE_AV_REG(0x20C)
166#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
167#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
168#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
169#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C)
170#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C)
171#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
172#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
173#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
174#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
175#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
176
177/* PLL */
178#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
179
180#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0)
181#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4)
182#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8)
183#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC)
184#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10)
185#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14)
186#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20)
187
188/* HDMI PHY */
189#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
190
191#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
192#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
193#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
194#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
195
196/* HDMI EDID Length */
197#define HDMI_EDID_MAX_LENGTH 256
198#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
199#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
200#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
201#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
202#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
203
204#define OMAP_HDMI_TIMINGS_NB 34
205
206#define REG_FLD_MOD(idx, val, start, end) \
207 hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
208#define REG_GET(idx, start, end) \
209 FLD_GET(hdmi_read_reg(idx), start, end)
210
211/* HDMI timing structure */
212struct hdmi_timings {
213 struct omap_video_timings timings;
214 int vsync_pol;
215 int hsync_pol;
216};
217
218enum hdmi_phy_pwr {
219 HDMI_PHYPWRCMD_OFF = 0,
220 HDMI_PHYPWRCMD_LDOON = 1,
221 HDMI_PHYPWRCMD_TXON = 2
222};
223
224enum hdmi_pll_pwr {
225 HDMI_PLLPWRCMD_ALLOFF = 0,
226 HDMI_PLLPWRCMD_PLLONLY = 1,
227 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
228 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
229};
230
231enum hdmi_clk_refsel {
232 HDMI_REFSEL_PCLK = 0,
233 HDMI_REFSEL_REF1 = 1,
234 HDMI_REFSEL_REF2 = 2,
235 HDMI_REFSEL_SYSCLK = 3
236};
237
238enum hdmi_core_inputbus_width {
239 HDMI_INPUT_8BIT = 0,
240 HDMI_INPUT_10BIT = 1,
241 HDMI_INPUT_12BIT = 2
242};
243
244enum hdmi_core_dither_trunc {
245 HDMI_OUTPUTTRUNCATION_8BIT = 0,
246 HDMI_OUTPUTTRUNCATION_10BIT = 1,
247 HDMI_OUTPUTTRUNCATION_12BIT = 2,
248 HDMI_OUTPUTDITHER_8BIT = 3,
249 HDMI_OUTPUTDITHER_10BIT = 4,
250 HDMI_OUTPUTDITHER_12BIT = 5
251};
252
253enum hdmi_core_deepcolor_ed {
254 HDMI_DEEPCOLORPACKECTDISABLE = 0,
255 HDMI_DEEPCOLORPACKECTENABLE = 1
256};
257
258enum hdmi_core_packet_mode {
259 HDMI_PACKETMODERESERVEDVALUE = 0,
260 HDMI_PACKETMODE24BITPERPIXEL = 4,
261 HDMI_PACKETMODE30BITPERPIXEL = 5,
262 HDMI_PACKETMODE36BITPERPIXEL = 6,
263 HDMI_PACKETMODE48BITPERPIXEL = 7
264};
265
266enum hdmi_core_hdmi_dvi {
267 HDMI_DVI = 0,
268 HDMI_HDMI = 1
269};
270
271enum hdmi_core_tclkselclkmult {
272 HDMI_FPLL05IDCK = 0,
273 HDMI_FPLL10IDCK = 1,
274 HDMI_FPLL20IDCK = 2,
275 HDMI_FPLL40IDCK = 3
276};
277
278enum hdmi_core_packet_ctrl {
279 HDMI_PACKETENABLE = 1,
280 HDMI_PACKETDISABLE = 0,
281 HDMI_PACKETREPEATON = 1,
282 HDMI_PACKETREPEATOFF = 0
283};
284
285/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
286enum hdmi_core_infoframe {
287 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
288 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
289 HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
290 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
291 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
292 HDMI_INFOFRAME_AVI_DB1B_NO = 0,
293 HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
294 HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
295 HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
296 HDMI_INFOFRAME_AVI_DB1S_0 = 0,
297 HDMI_INFOFRAME_AVI_DB1S_1 = 1,
298 HDMI_INFOFRAME_AVI_DB1S_2 = 2,
299 HDMI_INFOFRAME_AVI_DB2C_NO = 0,
300 HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
301 HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
302 HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
303 HDMI_INFOFRAME_AVI_DB2M_NO = 0,
304 HDMI_INFOFRAME_AVI_DB2M_43 = 1,
305 HDMI_INFOFRAME_AVI_DB2M_169 = 2,
306 HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
307 HDMI_INFOFRAME_AVI_DB2R_43 = 9,
308 HDMI_INFOFRAME_AVI_DB2R_169 = 10,
309 HDMI_INFOFRAME_AVI_DB2R_149 = 11,
310 HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
311 HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
312 HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
313 HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
314 HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
315 HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
316 HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
317 HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
318 HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
319 HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
320 HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
321 HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
322 HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
323 HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
324 HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
325 HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
326 HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
327 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
328 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
329 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
330 HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
331 HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0,
332 HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1,
333 HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2,
334 HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3,
335 HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4,
336 HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5,
337 HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6,
338 HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7,
339 HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8,
340 HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9,
341 HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10,
342 HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11,
343 HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12,
344 HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13,
345 HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14,
346 HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0,
347 HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1,
348 HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2,
349 HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3,
350 HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4,
351 HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5,
352 HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6,
353 HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7,
354 HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0,
355 HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1,
356 HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2,
357 HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3,
358 HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0,
359 HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1
360};
361
362enum hdmi_packing_mode {
363 HDMI_PACK_10b_RGB_YUV444 = 0,
364 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
365 HDMI_PACK_20b_YUV422 = 2,
366 HDMI_PACK_ALREADYPACKED = 7
367};
368
369enum hdmi_core_audio_sample_freq {
370 HDMI_AUDIO_FS_32000 = 0x3,
371 HDMI_AUDIO_FS_44100 = 0x0,
372 HDMI_AUDIO_FS_48000 = 0x2,
373 HDMI_AUDIO_FS_88200 = 0x8,
374 HDMI_AUDIO_FS_96000 = 0xA,
375 HDMI_AUDIO_FS_176400 = 0xC,
376 HDMI_AUDIO_FS_192000 = 0xE,
377 HDMI_AUDIO_FS_NOT_INDICATED = 0x1
378};
379
380enum hdmi_core_audio_layout {
381 HDMI_AUDIO_LAYOUT_2CH = 0,
382 HDMI_AUDIO_LAYOUT_8CH = 1
383};
384
385enum hdmi_core_cts_mode {
386 HDMI_AUDIO_CTS_MODE_HW = 0,
387 HDMI_AUDIO_CTS_MODE_SW = 1
388};
389
390enum hdmi_stereo_channels {
391 HDMI_AUDIO_STEREO_NOCHANNELS = 0,
392 HDMI_AUDIO_STEREO_ONECHANNEL = 1,
393 HDMI_AUDIO_STEREO_TWOCHANNELS = 2,
394 HDMI_AUDIO_STEREO_THREECHANNELS = 3,
395 HDMI_AUDIO_STEREO_FOURCHANNELS = 4
396};
397
398enum hdmi_audio_type {
399 HDMI_AUDIO_TYPE_LPCM = 0,
400 HDMI_AUDIO_TYPE_IEC = 1
401};
402
403enum hdmi_audio_justify {
404 HDMI_AUDIO_JUSTIFY_LEFT = 0,
405 HDMI_AUDIO_JUSTIFY_RIGHT = 1
406};
407
408enum hdmi_audio_sample_order {
409 HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0,
410 HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1
411};
412
413enum hdmi_audio_samples_perword {
414 HDMI_AUDIO_ONEWORD_ONESAMPLE = 0,
415 HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
416};
417
418enum hdmi_audio_sample_size {
419 HDMI_AUDIO_SAMPLE_16BITS = 0,
420 HDMI_AUDIO_SAMPLE_24BITS = 1
421};
422
423enum hdmi_audio_transf_mode {
424 HDMI_AUDIO_TRANSF_DMA = 0,
425 HDMI_AUDIO_TRANSF_IRQ = 1
426};
427
428enum hdmi_audio_blk_strt_end_sig {
429 HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0,
430 HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1
431};
432
433enum hdmi_audio_i2s_config {
434 HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT = 0,
435 HDMI_AUDIO_I2S_WS_POLARIT_YLOW_IS_RIGHT = 1,
436 HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0,
437 HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1,
438 HDMI_AUDIO_I2S_MAX_WORD_20BITS = 0,
439 HDMI_AUDIO_I2S_MAX_WORD_24BITS = 1,
440 HDMI_AUDIO_I2S_CHST_WORD_NOT_SPECIFIED = 0,
441 HDMI_AUDIO_I2S_CHST_WORD_16_BITS = 1,
442 HDMI_AUDIO_I2S_CHST_WORD_17_BITS = 6,
443 HDMI_AUDIO_I2S_CHST_WORD_18_BITS = 2,
444 HDMI_AUDIO_I2S_CHST_WORD_19_BITS = 4,
445 HDMI_AUDIO_I2S_CHST_WORD_20_BITS_20MAX = 5,
446 HDMI_AUDIO_I2S_CHST_WORD_20_BITS_24MAX = 1,
447 HDMI_AUDIO_I2S_CHST_WORD_21_BITS = 6,
448 HDMI_AUDIO_I2S_CHST_WORD_22_BITS = 2,
449 HDMI_AUDIO_I2S_CHST_WORD_23_BITS = 4,
450 HDMI_AUDIO_I2S_CHST_WORD_24_BITS = 5,
451 HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0,
452 HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1,
453 HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0,
454 HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1,
455 HDMI_AUDIO_I2S_INPUT_LENGTH_NA = 0,
456 HDMI_AUDIO_I2S_INPUT_LENGTH_16 = 2,
457 HDMI_AUDIO_I2S_INPUT_LENGTH_17 = 12,
458 HDMI_AUDIO_I2S_INPUT_LENGTH_18 = 4,
459 HDMI_AUDIO_I2S_INPUT_LENGTH_19 = 8,
460 HDMI_AUDIO_I2S_INPUT_LENGTH_20 = 10,
461 HDMI_AUDIO_I2S_INPUT_LENGTH_21 = 13,
462 HDMI_AUDIO_I2S_INPUT_LENGTH_22 = 5,
463 HDMI_AUDIO_I2S_INPUT_LENGTH_23 = 9,
464 HDMI_AUDIO_I2S_INPUT_LENGTH_24 = 11,
465 HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0,
466 HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1,
467 HDMI_AUDIO_I2S_SD0_EN = 1,
468 HDMI_AUDIO_I2S_SD1_EN = 1 << 1,
469 HDMI_AUDIO_I2S_SD2_EN = 1 << 2,
470 HDMI_AUDIO_I2S_SD3_EN = 1 << 3,
471};
472
473enum hdmi_audio_mclk_mode {
474 HDMI_AUDIO_MCLK_128FS = 0,
475 HDMI_AUDIO_MCLK_256FS = 1,
476 HDMI_AUDIO_MCLK_384FS = 2,
477 HDMI_AUDIO_MCLK_512FS = 3,
478 HDMI_AUDIO_MCLK_768FS = 4,
479 HDMI_AUDIO_MCLK_1024FS = 5,
480 HDMI_AUDIO_MCLK_1152FS = 6,
481 HDMI_AUDIO_MCLK_192FS = 7
482};
483
484struct hdmi_core_video_config {
485 enum hdmi_core_inputbus_width ip_bus_width;
486 enum hdmi_core_dither_trunc op_dither_truc;
487 enum hdmi_core_deepcolor_ed deep_color_pkt;
488 enum hdmi_core_packet_mode pkt_mode;
489 enum hdmi_core_hdmi_dvi hdmi_dvi;
490 enum hdmi_core_tclkselclkmult tclk_sel_clkmult;
491};
492
493/*
494 * Refer to section 8.2 in HDMI 1.3 specification for
495 * details about infoframe databytes
496 */
497struct hdmi_core_infoframe_avi {
498 u8 db1_format;
499 /* Y0, Y1 rgb,yCbCr */
500 u8 db1_active_info;
501 /* A0 Active information Present */
502 u8 db1_bar_info_dv;
503 /* B0, B1 Bar info data valid */
504 u8 db1_scan_info;
505 /* S0, S1 scan information */
506 u8 db2_colorimetry;
507 /* C0, C1 colorimetry */
508 u8 db2_aspect_ratio;
509 /* M0, M1 Aspect ratio (4:3, 16:9) */
510 u8 db2_active_fmt_ar;
511 /* R0...R3 Active format aspect ratio */
512 u8 db3_itc;
513 /* ITC IT content. */
514 u8 db3_ec;
515 /* EC0, EC1, EC2 Extended colorimetry */
516 u8 db3_q_range;
517 /* Q1, Q0 Quantization range */
518 u8 db3_nup_scaling;
519 /* SC1, SC0 Non-uniform picture scaling */
520 u8 db4_videocode;
521 /* VIC0..6 Video format identification */
522 u8 db5_pixel_repeat;
523 /* PR0..PR3 Pixel repetition factor */
524 u16 db6_7_line_eoftop;
525 /* Line number end of top bar */
526 u16 db8_9_line_sofbottom;
527 /* Line number start of bottom bar */
528 u16 db10_11_pixel_eofleft;
529 /* Pixel number end of left bar */
530 u16 db12_13_pixel_sofright;
531 /* Pixel number start of right bar */
532};
533/*
534 * Refer to section 8.2 in HDMI 1.3 specification for
535 * details about infoframe databytes
536 */
537struct hdmi_core_infoframe_audio {
538 u8 db1_coding_type;
539 u8 db1_channel_count;
540 u8 db2_sample_freq;
541 u8 db2_sample_size;
542 u8 db4_channel_alloc;
543 bool db5_downmix_inh;
544 u8 db5_lsv; /* Level shift values for downmix */
545};
546
547struct hdmi_core_packet_enable_repeat {
548 u32 audio_pkt;
549 u32 audio_pkt_repeat;
550 u32 avi_infoframe;
551 u32 avi_infoframe_repeat;
552 u32 gen_cntrl_pkt;
553 u32 gen_cntrl_pkt_repeat;
554 u32 generic_pkt;
555 u32 generic_pkt_repeat;
556};
557
558struct hdmi_video_format {
559 enum hdmi_packing_mode packing_mode;
560 u32 y_res; /* Line per panel */
561 u32 x_res; /* pixel per line */
562};
563
564struct hdmi_video_interface {
565 int vsp; /* Vsync polarity */
566 int hsp; /* Hsync polarity */
567 int interlacing;
568 int tm; /* Timing mode */
569};
570
571struct hdmi_cm {
572 int code;
573 int mode;
574};
575
576struct hdmi_config {
577 struct hdmi_timings timings;
578 u16 interlace;
579 struct hdmi_cm cm;
580};
581
582struct hdmi_audio_format {
583 enum hdmi_stereo_channels stereo_channels;
584 u8 active_chnnls_msk;
585 enum hdmi_audio_type type;
586 enum hdmi_audio_justify justification;
587 enum hdmi_audio_sample_order sample_order;
588 enum hdmi_audio_samples_perword samples_per_word;
589 enum hdmi_audio_sample_size sample_size;
590 enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
591};
592
593struct hdmi_audio_dma {
594 u8 transfer_size;
595 u8 block_size;
596 enum hdmi_audio_transf_mode mode;
597 u16 fifo_threshold;
598};
599
600struct hdmi_core_audio_i2s_config {
601 u8 word_max_length;
602 u8 word_length;
603 u8 in_length_bits;
604 u8 justification;
605 u8 en_high_bitrate_aud;
606 u8 sck_edge_mode;
607 u8 cbit_order;
608 u8 vbit;
609 u8 ws_polarity;
610 u8 direction;
611 u8 shift;
612 u8 active_sds;
613};
614
615struct hdmi_core_audio_config {
616 struct hdmi_core_audio_i2s_config i2s_cfg;
617 enum hdmi_core_audio_sample_freq freq_sample;
618 bool fs_override;
619 u32 n;
620 u32 cts;
621 u32 aud_par_busclk;
622 enum hdmi_core_audio_layout layout;
623 enum hdmi_core_cts_mode cts_mode;
624 bool use_mclk;
625 enum hdmi_audio_mclk_mode mclk_mode;
626 bool en_acr_pkt;
627 bool en_dsd_audio;
628 bool en_parallel_aud_input;
629 bool en_spdif;
630};
631#endif
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
new file mode 100644
index 000000000000..7d4f2bd7c506
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -0,0 +1,222 @@
1/*
2 * hdmi_omap4_panel.c
3 *
4 * HDMI library support functions for TI OMAP4 processors.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * Authors: Mythri P k <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27#include <video/omapdss.h>
28
29#include "dss.h"
30
31static struct {
32 struct mutex hdmi_lock;
33} hdmi;
34
35
36static int hdmi_panel_probe(struct omap_dss_device *dssdev)
37{
38 DSSDBG("ENTER hdmi_panel_probe\n");
39
40 dssdev->panel.config = OMAP_DSS_LCD_TFT |
41 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
42
43 /*
44 * Initialize the timings to 640 * 480
45 * This is only for framebuffer update not for TV timing setting
46 * Setting TV timing will be done only on enable
47 */
48 dssdev->panel.timings.x_res = 640;
49 dssdev->panel.timings.y_res = 480;
50
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res,
53 dssdev->panel.timings.y_res);
54 return 0;
55}
56
57static void hdmi_panel_remove(struct omap_dss_device *dssdev)
58{
59
60}
61
62static int hdmi_panel_enable(struct omap_dss_device *dssdev)
63{
64 int r = 0;
65 DSSDBG("ENTER hdmi_panel_enable\n");
66
67 mutex_lock(&hdmi.hdmi_lock);
68
69 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
70 r = -EINVAL;
71 goto err;
72 }
73
74 r = omapdss_hdmi_display_enable(dssdev);
75 if (r) {
76 DSSERR("failed to power on\n");
77 goto err;
78 }
79
80 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
81
82err:
83 mutex_unlock(&hdmi.hdmi_lock);
84
85 return r;
86}
87
88static void hdmi_panel_disable(struct omap_dss_device *dssdev)
89{
90 mutex_lock(&hdmi.hdmi_lock);
91
92 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
93 omapdss_hdmi_display_disable(dssdev);
94
95 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
96
97 mutex_unlock(&hdmi.hdmi_lock);
98}
99
100static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
101{
102 int r = 0;
103
104 mutex_lock(&hdmi.hdmi_lock);
105
106 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
107 r = -EINVAL;
108 goto err;
109 }
110
111 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
112
113 omapdss_hdmi_display_disable(dssdev);
114
115err:
116 mutex_unlock(&hdmi.hdmi_lock);
117
118 return r;
119}
120
121static int hdmi_panel_resume(struct omap_dss_device *dssdev)
122{
123 int r = 0;
124
125 mutex_lock(&hdmi.hdmi_lock);
126
127 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
128 r = -EINVAL;
129 goto err;
130 }
131
132 r = omapdss_hdmi_display_enable(dssdev);
133 if (r) {
134 DSSERR("failed to power on\n");
135 goto err;
136 }
137
138 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
139
140err:
141 mutex_unlock(&hdmi.hdmi_lock);
142
143 return r;
144}
145
146static void hdmi_get_timings(struct omap_dss_device *dssdev,
147 struct omap_video_timings *timings)
148{
149 mutex_lock(&hdmi.hdmi_lock);
150
151 *timings = dssdev->panel.timings;
152
153 mutex_unlock(&hdmi.hdmi_lock);
154}
155
156static void hdmi_set_timings(struct omap_dss_device *dssdev,
157 struct omap_video_timings *timings)
158{
159 DSSDBG("hdmi_set_timings\n");
160
161 mutex_lock(&hdmi.hdmi_lock);
162
163 dssdev->panel.timings = *timings;
164
165 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
166 /* turn the hdmi off and on to get new timings to use */
167 omapdss_hdmi_display_disable(dssdev);
168 omapdss_hdmi_display_set_timing(dssdev);
169 }
170
171 mutex_unlock(&hdmi.hdmi_lock);
172}
173
174static int hdmi_check_timings(struct omap_dss_device *dssdev,
175 struct omap_video_timings *timings)
176{
177 int r = 0;
178
179 DSSDBG("hdmi_check_timings\n");
180
181 mutex_lock(&hdmi.hdmi_lock);
182
183 r = omapdss_hdmi_display_check_timing(dssdev, timings);
184 if (r) {
185 DSSERR("Timing cannot be applied\n");
186 goto err;
187 }
188err:
189 mutex_unlock(&hdmi.hdmi_lock);
190 return r;
191}
192
193static struct omap_dss_driver hdmi_driver = {
194 .probe = hdmi_panel_probe,
195 .remove = hdmi_panel_remove,
196 .enable = hdmi_panel_enable,
197 .disable = hdmi_panel_disable,
198 .suspend = hdmi_panel_suspend,
199 .resume = hdmi_panel_resume,
200 .get_timings = hdmi_get_timings,
201 .set_timings = hdmi_set_timings,
202 .check_timings = hdmi_check_timings,
203 .driver = {
204 .name = "hdmi_panel",
205 .owner = THIS_MODULE,
206 },
207};
208
209int hdmi_panel_init(void)
210{
211 mutex_init(&hdmi.hdmi_lock);
212
213 omap_dss_register_driver(&hdmi_driver);
214
215 return 0;
216}
217
218void hdmi_panel_exit(void)
219{
220 omap_dss_unregister_driver(&hdmi_driver);
221
222}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 6a649ab5539e..9aeea50e33ff 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -29,10 +29,11 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/jiffies.h> 30#include <linux/jiffies.h>
31 31
32#include <plat/display.h> 32#include <video/omapdss.h>
33#include <plat/cpu.h> 33#include <plat/cpu.h>
34 34
35#include "dss.h" 35#include "dss.h"
36#include "dss_features.h"
36 37
37static int num_managers; 38static int num_managers;
38static struct list_head manager_list; 39static struct list_head manager_list;
@@ -392,6 +393,7 @@ struct overlay_cache_data {
392 393
393 u32 paddr; 394 u32 paddr;
394 void __iomem *vaddr; 395 void __iomem *vaddr;
396 u32 p_uv_addr; /* relevant for NV12 format only */
395 u16 screen_width; 397 u16 screen_width;
396 u16 width; 398 u16 width;
397 u16 height; 399 u16 height;
@@ -405,6 +407,7 @@ struct overlay_cache_data {
405 u16 out_width; /* if 0, out_width == width */ 407 u16 out_width; /* if 0, out_width == width */
406 u16 out_height; /* if 0, out_height == height */ 408 u16 out_height; /* if 0, out_height == height */
407 u8 global_alpha; 409 u8 global_alpha;
410 u8 pre_mult_alpha;
408 411
409 enum omap_channel channel; 412 enum omap_channel channel;
410 bool replication; 413 bool replication;
@@ -448,8 +451,8 @@ struct manager_cache_data {
448 451
449static struct { 452static struct {
450 spinlock_t lock; 453 spinlock_t lock;
451 struct overlay_cache_data overlay_cache[3]; 454 struct overlay_cache_data overlay_cache[MAX_DSS_OVERLAYS];
452 struct manager_cache_data manager_cache[2]; 455 struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
453 456
454 bool irq_enabled; 457 bool irq_enabled;
455} dss_cache; 458} dss_cache;
@@ -511,11 +514,16 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
511 unsigned long timeout = msecs_to_jiffies(500); 514 unsigned long timeout = msecs_to_jiffies(500);
512 u32 irq; 515 u32 irq;
513 516
514 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) 517 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
515 irq = DISPC_IRQ_EVSYNC_ODD; 518 irq = DISPC_IRQ_EVSYNC_ODD;
516 else 519 } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
517 irq = DISPC_IRQ_VSYNC; 520 irq = DISPC_IRQ_EVSYNC_EVEN;
518 521 } else {
522 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
523 irq = DISPC_IRQ_VSYNC;
524 else
525 irq = DISPC_IRQ_VSYNC2;
526 }
519 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 527 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
520} 528}
521 529
@@ -523,7 +531,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
523{ 531{
524 unsigned long timeout = msecs_to_jiffies(500); 532 unsigned long timeout = msecs_to_jiffies(500);
525 struct manager_cache_data *mc; 533 struct manager_cache_data *mc;
526 enum omap_channel channel;
527 u32 irq; 534 u32 irq;
528 int r; 535 int r;
529 int i; 536 int i;
@@ -532,9 +539,9 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
532 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 539 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
533 return 0; 540 return 0;
534 541
535 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 542 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
543 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
536 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 544 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
537 channel = OMAP_DSS_CHANNEL_DIGIT;
538 } else { 545 } else {
539 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 546 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
540 enum omap_dss_update_mode mode; 547 enum omap_dss_update_mode mode;
@@ -542,11 +549,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
542 if (mode != OMAP_DSS_UPDATE_AUTO) 549 if (mode != OMAP_DSS_UPDATE_AUTO)
543 return 0; 550 return 0;
544 551
545 irq = DISPC_IRQ_FRAMEDONE; 552 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
553 DISPC_IRQ_FRAMEDONE
554 : DISPC_IRQ_FRAMEDONE2;
546 } else { 555 } else {
547 irq = DISPC_IRQ_VSYNC; 556 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
557 DISPC_IRQ_VSYNC
558 : DISPC_IRQ_VSYNC2;
548 } 559 }
549 channel = OMAP_DSS_CHANNEL_LCD;
550 } 560 }
551 561
552 mc = &dss_cache.manager_cache[mgr->id]; 562 mc = &dss_cache.manager_cache[mgr->id];
@@ -593,7 +603,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
593int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) 603int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
594{ 604{
595 unsigned long timeout = msecs_to_jiffies(500); 605 unsigned long timeout = msecs_to_jiffies(500);
596 enum omap_channel channel;
597 struct overlay_cache_data *oc; 606 struct overlay_cache_data *oc;
598 struct omap_dss_device *dssdev; 607 struct omap_dss_device *dssdev;
599 u32 irq; 608 u32 irq;
@@ -608,9 +617,9 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
608 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 617 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
609 return 0; 618 return 0;
610 619
611 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 620 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
621 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
612 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 622 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
613 channel = OMAP_DSS_CHANNEL_DIGIT;
614 } else { 623 } else {
615 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 624 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
616 enum omap_dss_update_mode mode; 625 enum omap_dss_update_mode mode;
@@ -618,11 +627,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
618 if (mode != OMAP_DSS_UPDATE_AUTO) 627 if (mode != OMAP_DSS_UPDATE_AUTO)
619 return 0; 628 return 0;
620 629
621 irq = DISPC_IRQ_FRAMEDONE; 630 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
631 DISPC_IRQ_FRAMEDONE
632 : DISPC_IRQ_FRAMEDONE2;
622 } else { 633 } else {
623 irq = DISPC_IRQ_VSYNC; 634 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
635 DISPC_IRQ_VSYNC
636 : DISPC_IRQ_VSYNC2;
624 } 637 }
625 channel = OMAP_DSS_CHANNEL_LCD;
626 } 638 }
627 639
628 oc = &dss_cache.overlay_cache[ovl->id]; 640 oc = &dss_cache.overlay_cache[ovl->id];
@@ -764,10 +776,17 @@ static int configure_overlay(enum omap_plane plane)
764 } 776 }
765 777
766 switch (c->color_mode) { 778 switch (c->color_mode) {
779 case OMAP_DSS_COLOR_NV12:
780 bpp = 8;
781 break;
767 case OMAP_DSS_COLOR_RGB16: 782 case OMAP_DSS_COLOR_RGB16:
768 case OMAP_DSS_COLOR_ARGB16: 783 case OMAP_DSS_COLOR_ARGB16:
769 case OMAP_DSS_COLOR_YUV2: 784 case OMAP_DSS_COLOR_YUV2:
770 case OMAP_DSS_COLOR_UYVY: 785 case OMAP_DSS_COLOR_UYVY:
786 case OMAP_DSS_COLOR_RGBA16:
787 case OMAP_DSS_COLOR_RGBX16:
788 case OMAP_DSS_COLOR_ARGB16_1555:
789 case OMAP_DSS_COLOR_XRGB16_1555:
771 bpp = 16; 790 bpp = 16;
772 break; 791 break;
773 792
@@ -841,7 +860,10 @@ static int configure_overlay(enum omap_plane plane)
841 c->rotation_type, 860 c->rotation_type,
842 c->rotation, 861 c->rotation,
843 c->mirror, 862 c->mirror,
844 c->global_alpha); 863 c->global_alpha,
864 c->pre_mult_alpha,
865 c->channel,
866 c->p_uv_addr);
845 867
846 if (r) { 868 if (r) {
847 /* this shouldn't happen */ 869 /* this shouldn't happen */
@@ -882,21 +904,21 @@ static int configure_dispc(void)
882{ 904{
883 struct overlay_cache_data *oc; 905 struct overlay_cache_data *oc;
884 struct manager_cache_data *mc; 906 struct manager_cache_data *mc;
885 const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); 907 const int num_ovls = dss_feat_get_num_ovls();
886 const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache); 908 const int num_mgrs = dss_feat_get_num_mgrs();
887 int i; 909 int i;
888 int r; 910 int r;
889 bool mgr_busy[2]; 911 bool mgr_busy[MAX_DSS_MANAGERS];
890 bool mgr_go[2]; 912 bool mgr_go[MAX_DSS_MANAGERS];
891 bool busy; 913 bool busy;
892 914
893 r = 0; 915 r = 0;
894 busy = false; 916 busy = false;
895 917
896 mgr_busy[0] = dispc_go_busy(0); 918 for (i = 0; i < num_mgrs; i++) {
897 mgr_busy[1] = dispc_go_busy(1); 919 mgr_busy[i] = dispc_go_busy(i);
898 mgr_go[0] = false; 920 mgr_go[i] = false;
899 mgr_go[1] = false; 921 }
900 922
901 /* Commit overlay settings */ 923 /* Commit overlay settings */
902 for (i = 0; i < num_ovls; ++i) { 924 for (i = 0; i < num_ovls; ++i) {
@@ -989,7 +1011,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
989{ 1011{
990 struct overlay_cache_data *oc; 1012 struct overlay_cache_data *oc;
991 struct manager_cache_data *mc; 1013 struct manager_cache_data *mc;
992 const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); 1014 const int num_ovls = dss_feat_get_num_ovls();
993 struct omap_overlay_manager *mgr; 1015 struct omap_overlay_manager *mgr;
994 int i; 1016 int i;
995 u16 x, y, w, h; 1017 u16 x, y, w, h;
@@ -1121,8 +1143,8 @@ void dss_start_update(struct omap_dss_device *dssdev)
1121{ 1143{
1122 struct manager_cache_data *mc; 1144 struct manager_cache_data *mc;
1123 struct overlay_cache_data *oc; 1145 struct overlay_cache_data *oc;
1124 const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); 1146 const int num_ovls = dss_feat_get_num_ovls();
1125 const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache); 1147 const int num_mgrs = dss_feat_get_num_mgrs();
1126 struct omap_overlay_manager *mgr; 1148 struct omap_overlay_manager *mgr;
1127 int i; 1149 int i;
1128 1150
@@ -1151,13 +1173,14 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1151{ 1173{
1152 struct manager_cache_data *mc; 1174 struct manager_cache_data *mc;
1153 struct overlay_cache_data *oc; 1175 struct overlay_cache_data *oc;
1154 const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); 1176 const int num_ovls = dss_feat_get_num_ovls();
1155 const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache); 1177 const int num_mgrs = dss_feat_get_num_mgrs();
1156 int i, r; 1178 int i, r;
1157 bool mgr_busy[2]; 1179 bool mgr_busy[MAX_DSS_MANAGERS];
1180 u32 irq_mask;
1158 1181
1159 mgr_busy[0] = dispc_go_busy(0); 1182 for (i = 0; i < num_mgrs; i++)
1160 mgr_busy[1] = dispc_go_busy(1); 1183 mgr_busy[i] = dispc_go_busy(i);
1161 1184
1162 spin_lock(&dss_cache.lock); 1185 spin_lock(&dss_cache.lock);
1163 1186
@@ -1178,8 +1201,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1178 goto end; 1201 goto end;
1179 1202
1180 /* re-read busy flags */ 1203 /* re-read busy flags */
1181 mgr_busy[0] = dispc_go_busy(0); 1204 for (i = 0; i < num_mgrs; i++)
1182 mgr_busy[1] = dispc_go_busy(1); 1205 mgr_busy[i] = dispc_go_busy(i);
1183 1206
1184 /* keep running as long as there are busy managers, so that 1207 /* keep running as long as there are busy managers, so that
1185 * we can collect overlay-applied information */ 1208 * we can collect overlay-applied information */
@@ -1188,9 +1211,12 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1188 goto end; 1211 goto end;
1189 } 1212 }
1190 1213
1191 omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, 1214 irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
1192 DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | 1215 DISPC_IRQ_EVSYNC_EVEN;
1193 DISPC_IRQ_EVSYNC_EVEN); 1216 if (dss_has_feature(FEAT_MGR_LCD2))
1217 irq_mask |= DISPC_IRQ_VSYNC2;
1218
1219 omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
1194 dss_cache.irq_enabled = false; 1220 dss_cache.irq_enabled = false;
1195 1221
1196end: 1222end:
@@ -1252,6 +1278,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1252 1278
1253 oc->paddr = ovl->info.paddr; 1279 oc->paddr = ovl->info.paddr;
1254 oc->vaddr = ovl->info.vaddr; 1280 oc->vaddr = ovl->info.vaddr;
1281 oc->p_uv_addr = ovl->info.p_uv_addr;
1255 oc->screen_width = ovl->info.screen_width; 1282 oc->screen_width = ovl->info.screen_width;
1256 oc->width = ovl->info.width; 1283 oc->width = ovl->info.width;
1257 oc->height = ovl->info.height; 1284 oc->height = ovl->info.height;
@@ -1264,6 +1291,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1264 oc->out_width = ovl->info.out_width; 1291 oc->out_width = ovl->info.out_width;
1265 oc->out_height = ovl->info.out_height; 1292 oc->out_height = ovl->info.out_height;
1266 oc->global_alpha = ovl->info.global_alpha; 1293 oc->global_alpha = ovl->info.global_alpha;
1294 oc->pre_mult_alpha = ovl->info.pre_mult_alpha;
1267 1295
1268 oc->replication = 1296 oc->replication =
1269 dss_use_replication(dssdev, ovl->info.color_mode); 1297 dss_use_replication(dssdev, ovl->info.color_mode);
@@ -1363,6 +1391,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1363 case OMAP_DISPLAY_TYPE_DBI: 1391 case OMAP_DISPLAY_TYPE_DBI:
1364 case OMAP_DISPLAY_TYPE_SDI: 1392 case OMAP_DISPLAY_TYPE_SDI:
1365 case OMAP_DISPLAY_TYPE_VENC: 1393 case OMAP_DISPLAY_TYPE_VENC:
1394 case OMAP_DISPLAY_TYPE_HDMI:
1366 default_get_overlay_fifo_thresholds(ovl->id, size, 1395 default_get_overlay_fifo_thresholds(ovl->id, size,
1367 &oc->burst_size, &oc->fifo_low, 1396 &oc->burst_size, &oc->fifo_low,
1368 &oc->fifo_high); 1397 &oc->fifo_high);
@@ -1380,15 +1409,20 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1380 } 1409 }
1381 1410
1382 r = 0; 1411 r = 0;
1383 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1412 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1384 if (!dss_cache.irq_enabled) { 1413 if (!dss_cache.irq_enabled) {
1385 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, 1414 u32 mask;
1386 DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | 1415
1387 DISPC_IRQ_EVSYNC_EVEN); 1416 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
1417 DISPC_IRQ_EVSYNC_EVEN;
1418 if (dss_has_feature(FEAT_MGR_LCD2))
1419 mask |= DISPC_IRQ_VSYNC2;
1420
1421 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
1388 dss_cache.irq_enabled = true; 1422 dss_cache.irq_enabled = true;
1389 } 1423 }
1390 configure_dispc(); 1424 configure_dispc();
1391 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 1425 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1392 1426
1393 spin_unlock_irqrestore(&dss_cache.lock, flags); 1427 spin_unlock_irqrestore(&dss_cache.lock, flags);
1394 1428
@@ -1461,7 +1495,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1461 1495
1462 num_managers = 0; 1496 num_managers = 0;
1463 1497
1464 for (i = 0; i < 2; ++i) { 1498 for (i = 0; i < dss_feat_get_num_mgrs(); ++i) {
1465 struct omap_overlay_manager *mgr; 1499 struct omap_overlay_manager *mgr;
1466 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 1500 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
1467 1501
@@ -1471,14 +1505,14 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1471 case 0: 1505 case 0:
1472 mgr->name = "lcd"; 1506 mgr->name = "lcd";
1473 mgr->id = OMAP_DSS_CHANNEL_LCD; 1507 mgr->id = OMAP_DSS_CHANNEL_LCD;
1474 mgr->supported_displays =
1475 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
1476 OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI;
1477 break; 1508 break;
1478 case 1: 1509 case 1:
1479 mgr->name = "tv"; 1510 mgr->name = "tv";
1480 mgr->id = OMAP_DSS_CHANNEL_DIGIT; 1511 mgr->id = OMAP_DSS_CHANNEL_DIGIT;
1481 mgr->supported_displays = OMAP_DISPLAY_TYPE_VENC; 1512 break;
1513 case 2:
1514 mgr->name = "lcd2";
1515 mgr->id = OMAP_DSS_CHANNEL_LCD2;
1482 break; 1516 break;
1483 } 1517 }
1484 1518
@@ -1494,6 +1528,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1494 mgr->disable = &dss_mgr_disable; 1528 mgr->disable = &dss_mgr_disable;
1495 1529
1496 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; 1530 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
1531 mgr->supported_displays =
1532 dss_feat_get_supported_displays(mgr->id);
1497 1533
1498 dss_overlay_setup_dispc_manager(mgr); 1534 dss_overlay_setup_dispc_manager(mgr);
1499 1535
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 244dca81a399..0f08025b1f0e 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -31,10 +31,11 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include <plat/display.h> 34#include <video/omapdss.h>
35#include <plat/cpu.h> 35#include <plat/cpu.h>
36 36
37#include "dss.h" 37#include "dss.h"
38#include "dss_features.h"
38 39
39static int num_overlays; 40static int num_overlays;
40static struct list_head overlay_list; 41static struct list_head overlay_list;
@@ -200,12 +201,16 @@ static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
200static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, 201static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
201 size_t size) 202 size_t size)
202{ 203{
203 int r; 204 int r, enable;
204 struct omap_overlay_info info; 205 struct omap_overlay_info info;
205 206
206 ovl->get_overlay_info(ovl, &info); 207 ovl->get_overlay_info(ovl, &info);
207 208
208 info.enabled = simple_strtoul(buf, NULL, 10); 209 r = kstrtoint(buf, 0, &enable);
210 if (r)
211 return r;
212
213 info.enabled = !!enable;
209 214
210 r = ovl->set_overlay_info(ovl, &info); 215 r = ovl->set_overlay_info(ovl, &info);
211 if (r) 216 if (r)
@@ -230,17 +235,65 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
230 const char *buf, size_t size) 235 const char *buf, size_t size)
231{ 236{
232 int r; 237 int r;
238 u8 alpha;
233 struct omap_overlay_info info; 239 struct omap_overlay_info info;
234 240
241 r = kstrtou8(buf, 0, &alpha);
242 if (r)
243 return r;
244
235 ovl->get_overlay_info(ovl, &info); 245 ovl->get_overlay_info(ovl, &info);
236 246
237 /* Video1 plane does not support global alpha 247 /* Video1 plane does not support global alpha
238 * to always make it 255 completely opaque 248 * to always make it 255 completely opaque
239 */ 249 */
240 if (ovl->id == OMAP_DSS_VIDEO1) 250 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
251 ovl->id == OMAP_DSS_VIDEO1)
241 info.global_alpha = 255; 252 info.global_alpha = 255;
242 else 253 else
243 info.global_alpha = simple_strtoul(buf, NULL, 10); 254 info.global_alpha = alpha;
255
256 r = ovl->set_overlay_info(ovl, &info);
257 if (r)
258 return r;
259
260 if (ovl->manager) {
261 r = ovl->manager->apply(ovl->manager);
262 if (r)
263 return r;
264 }
265
266 return size;
267}
268
269static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
270 char *buf)
271{
272 return snprintf(buf, PAGE_SIZE, "%d\n",
273 ovl->info.pre_mult_alpha);
274}
275
276static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
277 const char *buf, size_t size)
278{
279 int r;
280 u8 alpha;
281 struct omap_overlay_info info;
282
283 r = kstrtou8(buf, 0, &alpha);
284 if (r)
285 return r;
286
287 ovl->get_overlay_info(ovl, &info);
288
289 /* only GFX and Video2 plane support pre alpha multiplied
290 * set zero for Video1 plane
291 */
292 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
293 ovl->id == OMAP_DSS_VIDEO1)
294 info.pre_mult_alpha = 0;
295 else
296 info.pre_mult_alpha = alpha;
244 297
245 r = ovl->set_overlay_info(ovl, &info); 298 r = ovl->set_overlay_info(ovl, &info);
246 if (r) 299 if (r)
@@ -278,6 +331,9 @@ static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
278 overlay_enabled_show, overlay_enabled_store); 331 overlay_enabled_show, overlay_enabled_store);
279static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, 332static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
280 overlay_global_alpha_show, overlay_global_alpha_store); 333 overlay_global_alpha_show, overlay_global_alpha_store);
334static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
335 overlay_pre_mult_alpha_show,
336 overlay_pre_mult_alpha_store);
281 337
282static struct attribute *overlay_sysfs_attrs[] = { 338static struct attribute *overlay_sysfs_attrs[] = {
283 &overlay_attr_name.attr, 339 &overlay_attr_name.attr,
@@ -288,6 +344,7 @@ static struct attribute *overlay_sysfs_attrs[] = {
288 &overlay_attr_output_size.attr, 344 &overlay_attr_output_size.attr,
289 &overlay_attr_enabled.attr, 345 &overlay_attr_enabled.attr,
290 &overlay_attr_global_alpha.attr, 346 &overlay_attr_global_alpha.attr,
347 &overlay_attr_pre_mult_alpha.attr,
291 NULL 348 NULL
292}; 349};
293 350
@@ -447,16 +504,21 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
447 504
448 ovl->manager = mgr; 505 ovl->manager = mgr;
449 506
450 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 507 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
451 /* XXX: on manual update display, in auto update mode, a bug happens 508 /* XXX: When there is an overlay on a DSI manual update display, and
452 * here. When an overlay is first enabled on LCD, then it's disabled, 509 * the overlay is first disabled, then moved to tv, and enabled, we
453 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT 510 * seem to get SYNC_LOST_DIGIT error.
454 * errors. Waiting before changing the channel_out fixes it. I'm 511 *
455 * guessing that the overlay is still somehow being used for the LCD, 512 * Waiting doesn't seem to help, but updating the manual update display
456 * but I don't understand how or why. */ 513 * after disabling the overlay seems to fix this. This hints that the
457 msleep(40); 514 * overlay is perhaps somehow tied to the LCD output until the output
515 * is updated.
516 *
517 * Userspace workaround for this is to update the LCD after disabling
518 * the overlay, but before moving the overlay to TV.
519 */
458 dispc_set_channel_out(ovl->id, mgr->id); 520 dispc_set_channel_out(ovl->id, mgr->id);
459 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 521 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
460 522
461 return 0; 523 return 0;
462} 524}
@@ -510,11 +572,11 @@ static void omap_dss_add_overlay(struct omap_overlay *overlay)
510 list_add_tail(&overlay->list, &overlay_list); 572 list_add_tail(&overlay->list, &overlay_list);
511} 573}
512 574
513static struct omap_overlay *dispc_overlays[3]; 575static struct omap_overlay *dispc_overlays[MAX_DSS_OVERLAYS];
514 576
515void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr) 577void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
516{ 578{
517 mgr->num_overlays = 3; 579 mgr->num_overlays = dss_feat_get_num_ovls();
518 mgr->overlays = dispc_overlays; 580 mgr->overlays = dispc_overlays;
519} 581}
520 582
@@ -535,7 +597,7 @@ void dss_init_overlays(struct platform_device *pdev)
535 597
536 num_overlays = 0; 598 num_overlays = 0;
537 599
538 for (i = 0; i < 3; ++i) { 600 for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
539 struct omap_overlay *ovl; 601 struct omap_overlay *ovl;
540 ovl = kzalloc(sizeof(*ovl), GFP_KERNEL); 602 ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
541 603
@@ -545,18 +607,12 @@ void dss_init_overlays(struct platform_device *pdev)
545 case 0: 607 case 0:
546 ovl->name = "gfx"; 608 ovl->name = "gfx";
547 ovl->id = OMAP_DSS_GFX; 609 ovl->id = OMAP_DSS_GFX;
548 ovl->supported_modes = cpu_is_omap34xx() ?
549 OMAP_DSS_COLOR_GFX_OMAP3 :
550 OMAP_DSS_COLOR_GFX_OMAP2;
551 ovl->caps = OMAP_DSS_OVL_CAP_DISPC; 610 ovl->caps = OMAP_DSS_OVL_CAP_DISPC;
552 ovl->info.global_alpha = 255; 611 ovl->info.global_alpha = 255;
553 break; 612 break;
554 case 1: 613 case 1:
555 ovl->name = "vid1"; 614 ovl->name = "vid1";
556 ovl->id = OMAP_DSS_VIDEO1; 615 ovl->id = OMAP_DSS_VIDEO1;
557 ovl->supported_modes = cpu_is_omap34xx() ?
558 OMAP_DSS_COLOR_VID1_OMAP3 :
559 OMAP_DSS_COLOR_VID_OMAP2;
560 ovl->caps = OMAP_DSS_OVL_CAP_SCALE | 616 ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
561 OMAP_DSS_OVL_CAP_DISPC; 617 OMAP_DSS_OVL_CAP_DISPC;
562 ovl->info.global_alpha = 255; 618 ovl->info.global_alpha = 255;
@@ -564,9 +620,6 @@ void dss_init_overlays(struct platform_device *pdev)
564 case 2: 620 case 2:
565 ovl->name = "vid2"; 621 ovl->name = "vid2";
566 ovl->id = OMAP_DSS_VIDEO2; 622 ovl->id = OMAP_DSS_VIDEO2;
567 ovl->supported_modes = cpu_is_omap34xx() ?
568 OMAP_DSS_COLOR_VID2_OMAP3 :
569 OMAP_DSS_COLOR_VID_OMAP2;
570 ovl->caps = OMAP_DSS_OVL_CAP_SCALE | 623 ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
571 OMAP_DSS_OVL_CAP_DISPC; 624 OMAP_DSS_OVL_CAP_DISPC;
572 ovl->info.global_alpha = 255; 625 ovl->info.global_alpha = 255;
@@ -579,6 +632,9 @@ void dss_init_overlays(struct platform_device *pdev)
579 ovl->get_overlay_info = &dss_ovl_get_overlay_info; 632 ovl->get_overlay_info = &dss_ovl_get_overlay_info;
580 ovl->wait_for_go = &dss_ovl_wait_for_go; 633 ovl->wait_for_go = &dss_ovl_wait_for_go;
581 634
635 ovl->supported_modes =
636 dss_feat_get_supported_color_modes(ovl->id);
637
582 omap_dss_add_overlay(ovl); 638 omap_dss_add_overlay(ovl);
583 639
584 r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, 640 r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
@@ -627,12 +683,23 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
627 int i; 683 int i;
628 struct omap_overlay_manager *lcd_mgr; 684 struct omap_overlay_manager *lcd_mgr;
629 struct omap_overlay_manager *tv_mgr; 685 struct omap_overlay_manager *tv_mgr;
686 struct omap_overlay_manager *lcd2_mgr = NULL;
630 struct omap_overlay_manager *mgr = NULL; 687 struct omap_overlay_manager *mgr = NULL;
631 688
632 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); 689 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
633 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); 690 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
634 691 if (dss_has_feature(FEAT_MGR_LCD2))
635 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 692 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);
693
694 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
695 if (!lcd2_mgr->device || force) {
696 if (lcd2_mgr->device)
697 lcd2_mgr->unset_device(lcd2_mgr);
698 lcd2_mgr->set_device(lcd2_mgr, dssdev);
699 mgr = lcd2_mgr;
700 }
701 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
702 && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
636 if (!lcd_mgr->device || force) { 703 if (!lcd_mgr->device || force) {
637 if (lcd_mgr->device) 704 if (lcd_mgr->device)
638 lcd_mgr->unset_device(lcd_mgr); 705 lcd_mgr->unset_device(lcd_mgr);
@@ -641,7 +708,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
641 } 708 }
642 } 709 }
643 710
644 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 711 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
712 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
645 if (!tv_mgr->device || force) { 713 if (!tv_mgr->device || force) {
646 if (tv_mgr->device) 714 if (tv_mgr->device)
647 tv_mgr->unset_device(tv_mgr); 715 tv_mgr->unset_device(tv_mgr);
@@ -651,7 +719,7 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
651 } 719 }
652 720
653 if (mgr) { 721 if (mgr) {
654 for (i = 0; i < 3; i++) { 722 for (i = 0; i < dss_feat_get_num_ovls(); i++) {
655 struct omap_overlay *ovl; 723 struct omap_overlay *ovl;
656 ovl = omap_dss_get_overlay(i); 724 ovl = omap_dss_get_overlay(i);
657 if (!ovl->manager || force) { 725 if (!ovl->manager || force) {
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index bbe62464e92d..c06fbe0bc678 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -32,12 +32,11 @@
32#include <linux/ktime.h> 32#include <linux/ktime.h>
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 36
36#include <plat/display.h> 37#include <video/omapdss.h>
37#include "dss.h" 38#include "dss.h"
38 39
39#define RFBI_BASE 0x48050800
40
41struct rfbi_reg { u16 idx; }; 40struct rfbi_reg { u16 idx; };
42 41
43#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) 42#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
@@ -67,9 +66,6 @@ struct rfbi_reg { u16 idx; };
67#define REG_FLD_MOD(idx, val, start, end) \ 66#define REG_FLD_MOD(idx, val, start, end) \
68 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) 67 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
69 68
70/* To work around an RFBI transfer rate limitation */
71#define OMAP_RFBI_RATE_LIMIT 1
72
73enum omap_rfbi_cycleformat { 69enum omap_rfbi_cycleformat {
74 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0, 70 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
75 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1, 71 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
@@ -91,15 +87,11 @@ enum omap_rfbi_parallelmode {
91 OMAP_DSS_RFBI_PARALLELMODE_16 = 3, 87 OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
92}; 88};
93 89
94enum update_cmd {
95 RFBI_CMD_UPDATE = 0,
96 RFBI_CMD_SYNC = 1,
97};
98
99static int rfbi_convert_timings(struct rfbi_timings *t); 90static int rfbi_convert_timings(struct rfbi_timings *t);
100static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 91static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
101 92
102static struct { 93static struct {
94 struct platform_device *pdev;
103 void __iomem *base; 95 void __iomem *base;
104 96
105 unsigned long l4_khz; 97 unsigned long l4_khz;
@@ -115,20 +107,9 @@ static struct {
115 107
116 struct omap_dss_device *dssdev[2]; 108 struct omap_dss_device *dssdev[2];
117 109
118 struct kfifo cmd_fifo; 110 struct semaphore bus_lock;
119 spinlock_t cmd_lock;
120 struct completion cmd_done;
121 atomic_t cmd_fifo_full;
122 atomic_t cmd_pending;
123} rfbi; 111} rfbi;
124 112
125struct update_region {
126 u16 x;
127 u16 y;
128 u16 w;
129 u16 h;
130};
131
132static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 113static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
133{ 114{
134 __raw_writel(val, rfbi.base + idx.idx); 115 __raw_writel(val, rfbi.base + idx.idx);
@@ -142,14 +123,25 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
142static void rfbi_enable_clocks(bool enable) 123static void rfbi_enable_clocks(bool enable)
143{ 124{
144 if (enable) 125 if (enable)
145 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 126 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
146 else 127 else
147 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 128 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
129}
130
131void rfbi_bus_lock(void)
132{
133 down(&rfbi.bus_lock);
134}
135EXPORT_SYMBOL(rfbi_bus_lock);
136
137void rfbi_bus_unlock(void)
138{
139 up(&rfbi.bus_lock);
148} 140}
141EXPORT_SYMBOL(rfbi_bus_unlock);
149 142
150void omap_rfbi_write_command(const void *buf, u32 len) 143void omap_rfbi_write_command(const void *buf, u32 len)
151{ 144{
152 rfbi_enable_clocks(1);
153 switch (rfbi.parallelmode) { 145 switch (rfbi.parallelmode) {
154 case OMAP_DSS_RFBI_PARALLELMODE_8: 146 case OMAP_DSS_RFBI_PARALLELMODE_8:
155 { 147 {
@@ -173,13 +165,11 @@ void omap_rfbi_write_command(const void *buf, u32 len)
173 default: 165 default:
174 BUG(); 166 BUG();
175 } 167 }
176 rfbi_enable_clocks(0);
177} 168}
178EXPORT_SYMBOL(omap_rfbi_write_command); 169EXPORT_SYMBOL(omap_rfbi_write_command);
179 170
180void omap_rfbi_read_data(void *buf, u32 len) 171void omap_rfbi_read_data(void *buf, u32 len)
181{ 172{
182 rfbi_enable_clocks(1);
183 switch (rfbi.parallelmode) { 173 switch (rfbi.parallelmode) {
184 case OMAP_DSS_RFBI_PARALLELMODE_8: 174 case OMAP_DSS_RFBI_PARALLELMODE_8:
185 { 175 {
@@ -207,13 +197,11 @@ void omap_rfbi_read_data(void *buf, u32 len)
207 default: 197 default:
208 BUG(); 198 BUG();
209 } 199 }
210 rfbi_enable_clocks(0);
211} 200}
212EXPORT_SYMBOL(omap_rfbi_read_data); 201EXPORT_SYMBOL(omap_rfbi_read_data);
213 202
214void omap_rfbi_write_data(const void *buf, u32 len) 203void omap_rfbi_write_data(const void *buf, u32 len)
215{ 204{
216 rfbi_enable_clocks(1);
217 switch (rfbi.parallelmode) { 205 switch (rfbi.parallelmode) {
218 case OMAP_DSS_RFBI_PARALLELMODE_8: 206 case OMAP_DSS_RFBI_PARALLELMODE_8:
219 { 207 {
@@ -238,7 +226,6 @@ void omap_rfbi_write_data(const void *buf, u32 len)
238 BUG(); 226 BUG();
239 227
240 } 228 }
241 rfbi_enable_clocks(0);
242} 229}
243EXPORT_SYMBOL(omap_rfbi_write_data); 230EXPORT_SYMBOL(omap_rfbi_write_data);
244 231
@@ -250,8 +237,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
250 int horiz_offset = scr_width - w; 237 int horiz_offset = scr_width - w;
251 int i; 238 int i;
252 239
253 rfbi_enable_clocks(1);
254
255 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && 240 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
256 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { 241 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
257 const u16 __iomem *pd = buf; 242 const u16 __iomem *pd = buf;
@@ -296,13 +281,11 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
296 } else { 281 } else {
297 BUG(); 282 BUG();
298 } 283 }
299
300 rfbi_enable_clocks(0);
301} 284}
302EXPORT_SYMBOL(omap_rfbi_write_pixels); 285EXPORT_SYMBOL(omap_rfbi_write_pixels);
303 286
304void rfbi_transfer_area(u16 width, u16 height, 287static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
305 void (callback)(void *data), void *data) 288 u16 height, void (*callback)(void *data), void *data)
306{ 289{
307 u32 l; 290 u32 l;
308 291
@@ -311,15 +294,13 @@ void rfbi_transfer_area(u16 width, u16 height,
311 294
312 DSSDBG("rfbi_transfer_area %dx%d\n", width, height); 295 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
313 296
314 dispc_set_lcd_size(width, height); 297 dispc_set_lcd_size(dssdev->manager->id, width, height);
315 298
316 dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true); 299 dispc_enable_channel(dssdev->manager->id, true);
317 300
318 rfbi.framedone_callback = callback; 301 rfbi.framedone_callback = callback;
319 rfbi.framedone_callback_data = data; 302 rfbi.framedone_callback_data = data;
320 303
321 rfbi_enable_clocks(1);
322
323 rfbi_write_reg(RFBI_PIXEL_CNT, width * height); 304 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
324 305
325 l = rfbi_read_reg(RFBI_CONTROL); 306 l = rfbi_read_reg(RFBI_CONTROL);
@@ -338,15 +319,11 @@ static void framedone_callback(void *data, u32 mask)
338 319
339 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); 320 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
340 321
341 rfbi_enable_clocks(0);
342
343 callback = rfbi.framedone_callback; 322 callback = rfbi.framedone_callback;
344 rfbi.framedone_callback = NULL; 323 rfbi.framedone_callback = NULL;
345 324
346 if (callback != NULL) 325 if (callback != NULL)
347 callback(rfbi.framedone_callback_data); 326 callback(rfbi.framedone_callback_data);
348
349 atomic_set(&rfbi.cmd_pending, 0);
350} 327}
351 328
352#if 1 /* VERBOSE */ 329#if 1 /* VERBOSE */
@@ -436,7 +413,7 @@ static int calc_extif_timings(struct rfbi_timings *t)
436} 413}
437 414
438 415
439void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t) 416static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
440{ 417{
441 int r; 418 int r;
442 419
@@ -448,7 +425,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
448 425
449 BUG_ON(!t->converted); 426 BUG_ON(!t->converted);
450 427
451 rfbi_enable_clocks(1);
452 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]); 428 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
453 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]); 429 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
454 430
@@ -457,7 +433,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
457 (t->tim[2] ? 1 : 0), 4, 4); 433 (t->tim[2] ? 1 : 0), 4, 4);
458 434
459 rfbi_print_timings(); 435 rfbi_print_timings();
460 rfbi_enable_clocks(0);
461} 436}
462 437
463static int ps_to_rfbi_ticks(int time, int div) 438static int ps_to_rfbi_ticks(int time, int div)
@@ -473,59 +448,6 @@ static int ps_to_rfbi_ticks(int time, int div)
473 return ret; 448 return ret;
474} 449}
475 450
476#ifdef OMAP_RFBI_RATE_LIMIT
477unsigned long rfbi_get_max_tx_rate(void)
478{
479 unsigned long l4_rate, dss1_rate;
480 int min_l4_ticks = 0;
481 int i;
482
483 /* According to TI this can't be calculated so make the
484 * adjustments for a couple of known frequencies and warn for
485 * others.
486 */
487 static const struct {
488 unsigned long l4_clk; /* HZ */
489 unsigned long dss1_clk; /* HZ */
490 unsigned long min_l4_ticks;
491 } ftab[] = {
492 { 55, 132, 7, }, /* 7.86 MPix/s */
493 { 110, 110, 12, }, /* 9.16 MPix/s */
494 { 110, 132, 10, }, /* 11 Mpix/s */
495 { 120, 120, 10, }, /* 12 Mpix/s */
496 { 133, 133, 10, }, /* 13.3 Mpix/s */
497 };
498
499 l4_rate = rfbi.l4_khz / 1000;
500 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000;
501
502 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
503 /* Use a window instead of an exact match, to account
504 * for different DPLL multiplier / divider pairs.
505 */
506 if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
507 abs(ftab[i].dss1_clk - dss1_rate) < 3) {
508 min_l4_ticks = ftab[i].min_l4_ticks;
509 break;
510 }
511 }
512 if (i == ARRAY_SIZE(ftab)) {
513 /* Can't be sure, return anyway the maximum not
514 * rate-limited. This might cause a problem only for the
515 * tearing synchronisation.
516 */
517 DSSERR("can't determine maximum RFBI transfer rate\n");
518 return rfbi.l4_khz * 1000;
519 }
520 return rfbi.l4_khz * 1000 / min_l4_ticks;
521}
522#else
523int rfbi_get_max_tx_rate(void)
524{
525 return rfbi.l4_khz * 1000;
526}
527#endif
528
529static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div) 451static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
530{ 452{
531 *clk_period = 1000000000 / rfbi.l4_khz; 453 *clk_period = 1000000000 / rfbi.l4_khz;
@@ -645,7 +567,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
645 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n", 567 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
646 mode, hs, vs, hs_pol_inv, vs_pol_inv); 568 mode, hs, vs, hs_pol_inv, vs_pol_inv);
647 569
648 rfbi_enable_clocks(1);
649 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs); 570 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
650 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs); 571 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
651 572
@@ -658,7 +579,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
658 l &= ~(1 << 20); 579 l &= ~(1 << 20);
659 else 580 else
660 l |= 1 << 20; 581 l |= 1 << 20;
661 rfbi_enable_clocks(0);
662 582
663 return 0; 583 return 0;
664} 584}
@@ -673,7 +593,6 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
673 if (line > (1 << 11) - 1) 593 if (line > (1 << 11) - 1)
674 return -EINVAL; 594 return -EINVAL;
675 595
676 rfbi_enable_clocks(1);
677 l = rfbi_read_reg(RFBI_CONFIG(0)); 596 l = rfbi_read_reg(RFBI_CONFIG(0));
678 l &= ~(0x3 << 2); 597 l &= ~(0x3 << 2);
679 if (enable) { 598 if (enable) {
@@ -683,50 +602,12 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
683 rfbi.te_enabled = 0; 602 rfbi.te_enabled = 0;
684 rfbi_write_reg(RFBI_CONFIG(0), l); 603 rfbi_write_reg(RFBI_CONFIG(0), l);
685 rfbi_write_reg(RFBI_LINE_NUMBER, line); 604 rfbi_write_reg(RFBI_LINE_NUMBER, line);
686 rfbi_enable_clocks(0);
687 605
688 return 0; 606 return 0;
689} 607}
690EXPORT_SYMBOL(omap_rfbi_enable_te); 608EXPORT_SYMBOL(omap_rfbi_enable_te);
691 609
692#if 0 610static int rfbi_configure(int rfbi_module, int bpp, int lines)
693static void rfbi_enable_config(int enable1, int enable2)
694{
695 u32 l;
696 int cs = 0;
697
698 if (enable1)
699 cs |= 1<<0;
700 if (enable2)
701 cs |= 1<<1;
702
703 rfbi_enable_clocks(1);
704
705 l = rfbi_read_reg(RFBI_CONTROL);
706
707 l = FLD_MOD(l, cs, 3, 2);
708 l = FLD_MOD(l, 0, 1, 1);
709
710 rfbi_write_reg(RFBI_CONTROL, l);
711
712
713 l = rfbi_read_reg(RFBI_CONFIG(0));
714 l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
715 /*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
716 /*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
717
718 l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
719 l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
720 l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
721
722 l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
723 rfbi_write_reg(RFBI_CONFIG(0), l);
724
725 rfbi_enable_clocks(0);
726}
727#endif
728
729int rfbi_configure(int rfbi_module, int bpp, int lines)
730{ 611{
731 u32 l; 612 u32 l;
732 int cycle1 = 0, cycle2 = 0, cycle3 = 0; 613 int cycle1 = 0, cycle2 = 0, cycle3 = 0;
@@ -822,8 +703,6 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
822 break; 703 break;
823 } 704 }
824 705
825 rfbi_enable_clocks(1);
826
827 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */ 706 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
828 707
829 l = 0; 708 l = 0;
@@ -857,11 +736,15 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
857 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n", 736 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
858 bpp, lines, cycle1, cycle2, cycle3); 737 bpp, lines, cycle1, cycle2, cycle3);
859 738
860 rfbi_enable_clocks(0);
861
862 return 0; 739 return 0;
863} 740}
864EXPORT_SYMBOL(rfbi_configure); 741
742int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
743 int data_lines)
744{
745 return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
746}
747EXPORT_SYMBOL(omap_rfbi_configure);
865 748
866int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, 749int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
867 u16 *x, u16 *y, u16 *w, u16 *h) 750 u16 *x, u16 *y, u16 *w, u16 *h)
@@ -887,7 +770,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
887 770
888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 771 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
889 dss_setup_partial_planes(dssdev, x, y, w, h, true); 772 dss_setup_partial_planes(dssdev, x, y, w, h, true);
890 dispc_set_lcd_size(*w, *h); 773 dispc_set_lcd_size(dssdev->manager->id, *w, *h);
891 } 774 }
892 775
893 return 0; 776 return 0;
@@ -899,7 +782,7 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
899 void (*callback)(void *), void *data) 782 void (*callback)(void *), void *data)
900{ 783{
901 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 784 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
902 rfbi_transfer_area(w, h, callback, data); 785 rfbi_transfer_area(dssdev, w, h, callback, data);
903 } else { 786 } else {
904 struct omap_overlay *ovl; 787 struct omap_overlay *ovl;
905 void __iomem *addr; 788 void __iomem *addr;
@@ -922,7 +805,7 @@ void rfbi_dump_regs(struct seq_file *s)
922{ 805{
923#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) 806#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
924 807
925 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 808 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
926 809
927 DUMPREG(RFBI_REVISION); 810 DUMPREG(RFBI_REVISION);
928 DUMPREG(RFBI_SYSCONFIG); 811 DUMPREG(RFBI_SYSCONFIG);
@@ -953,58 +836,16 @@ void rfbi_dump_regs(struct seq_file *s)
953 DUMPREG(RFBI_VSYNC_WIDTH); 836 DUMPREG(RFBI_VSYNC_WIDTH);
954 DUMPREG(RFBI_HSYNC_WIDTH); 837 DUMPREG(RFBI_HSYNC_WIDTH);
955 838
956 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 839 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
957#undef DUMPREG 840#undef DUMPREG
958} 841}
959 842
960int rfbi_init(void)
961{
962 u32 rev;
963 u32 l;
964
965 spin_lock_init(&rfbi.cmd_lock);
966
967 init_completion(&rfbi.cmd_done);
968 atomic_set(&rfbi.cmd_fifo_full, 0);
969 atomic_set(&rfbi.cmd_pending, 0);
970
971 rfbi.base = ioremap(RFBI_BASE, SZ_256);
972 if (!rfbi.base) {
973 DSSERR("can't ioremap RFBI\n");
974 return -ENOMEM;
975 }
976
977 rfbi_enable_clocks(1);
978
979 msleep(10);
980
981 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
982
983 /* Enable autoidle and smart-idle */
984 l = rfbi_read_reg(RFBI_SYSCONFIG);
985 l |= (1 << 0) | (2 << 3);
986 rfbi_write_reg(RFBI_SYSCONFIG, l);
987
988 rev = rfbi_read_reg(RFBI_REVISION);
989 printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
990 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
991
992 rfbi_enable_clocks(0);
993
994 return 0;
995}
996
997void rfbi_exit(void)
998{
999 DSSDBG("rfbi_exit\n");
1000
1001 iounmap(rfbi.base);
1002}
1003
1004int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) 843int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1005{ 844{
1006 int r; 845 int r;
1007 846
847 rfbi_enable_clocks(1);
848
1008 r = omap_dss_start_device(dssdev); 849 r = omap_dss_start_device(dssdev);
1009 if (r) { 850 if (r) {
1010 DSSERR("failed to start device\n"); 851 DSSERR("failed to start device\n");
@@ -1018,11 +859,13 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1018 goto err1; 859 goto err1;
1019 } 860 }
1020 861
1021 dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); 862 dispc_set_lcd_display_type(dssdev->manager->id,
863 OMAP_DSS_LCD_DISPLAY_TFT);
1022 864
1023 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI); 865 dispc_set_parallel_interface_mode(dssdev->manager->id,
866 OMAP_DSS_PARALLELMODE_RFBI);
1024 867
1025 dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); 868 dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
1026 869
1027 rfbi_configure(dssdev->phy.rfbi.channel, 870 rfbi_configure(dssdev->phy.rfbi.channel,
1028 dssdev->ctrl.pixel_size, 871 dssdev->ctrl.pixel_size,
@@ -1045,6 +888,8 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
1045 omap_dispc_unregister_isr(framedone_callback, NULL, 888 omap_dispc_unregister_isr(framedone_callback, NULL,
1046 DISPC_IRQ_FRAMEDONE); 889 DISPC_IRQ_FRAMEDONE);
1047 omap_dss_stop_device(dssdev); 890 omap_dss_stop_device(dssdev);
891
892 rfbi_enable_clocks(0);
1048} 893}
1049EXPORT_SYMBOL(omapdss_rfbi_display_disable); 894EXPORT_SYMBOL(omapdss_rfbi_display_disable);
1050 895
@@ -1054,3 +899,70 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
1054 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 899 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
1055 return 0; 900 return 0;
1056} 901}
902
903/* RFBI HW IP initialisation */
904static int omap_rfbihw_probe(struct platform_device *pdev)
905{
906 u32 rev;
907 u32 l;
908 struct resource *rfbi_mem;
909
910 rfbi.pdev = pdev;
911
912 sema_init(&rfbi.bus_lock, 1);
913
914 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
915 if (!rfbi_mem) {
916 DSSERR("can't get IORESOURCE_MEM RFBI\n");
917 return -EINVAL;
918 }
919 rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
920 if (!rfbi.base) {
921 DSSERR("can't ioremap RFBI\n");
922 return -ENOMEM;
923 }
924
925 rfbi_enable_clocks(1);
926
927 msleep(10);
928
929 rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
930
931 /* Enable autoidle and smart-idle */
932 l = rfbi_read_reg(RFBI_SYSCONFIG);
933 l |= (1 << 0) | (2 << 3);
934 rfbi_write_reg(RFBI_SYSCONFIG, l);
935
936 rev = rfbi_read_reg(RFBI_REVISION);
937 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
938 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
939
940 rfbi_enable_clocks(0);
941
942 return 0;
943}
944
945static int omap_rfbihw_remove(struct platform_device *pdev)
946{
947 iounmap(rfbi.base);
948 return 0;
949}
950
951static struct platform_driver omap_rfbihw_driver = {
952 .probe = omap_rfbihw_probe,
953 .remove = omap_rfbihw_remove,
954 .driver = {
955 .name = "omapdss_rfbi",
956 .owner = THIS_MODULE,
957 },
958};
959
960int rfbi_init_platform_driver(void)
961{
962 return platform_driver_register(&omap_rfbihw_driver);
963}
964
965void rfbi_uninit_platform_driver(void)
966{
967 return platform_driver_unregister(&omap_rfbihw_driver);
968}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index ee07a3cc22ef..0bd4b0350f80 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -25,22 +25,25 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/regulator/consumer.h> 26#include <linux/regulator/consumer.h>
27 27
28#include <plat/display.h> 28#include <video/omapdss.h>
29#include <plat/cpu.h> 29#include <plat/cpu.h>
30#include "dss.h" 30#include "dss.h"
31 31
32static struct { 32static struct {
33 bool skip_init;
34 bool update_enabled; 33 bool update_enabled;
35 struct regulator *vdds_sdi_reg; 34 struct regulator *vdds_sdi_reg;
36} sdi; 35} sdi;
37 36
38static void sdi_basic_init(void) 37static void sdi_basic_init(struct omap_dss_device *dssdev)
38
39{ 39{
40 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); 40 dispc_set_parallel_interface_mode(dssdev->manager->id,
41 OMAP_DSS_PARALLELMODE_BYPASS);
42
43 dispc_set_lcd_display_type(dssdev->manager->id,
44 OMAP_DSS_LCD_DISPLAY_TFT);
41 45
42 dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); 46 dispc_set_tft_data_lines(dssdev->manager->id, 24);
43 dispc_set_tft_data_lines(24);
44 dispc_lcd_enable_signal_polarity(1); 47 dispc_lcd_enable_signal_polarity(1);
45} 48}
46 49
@@ -64,26 +67,18 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
64 if (r) 67 if (r)
65 goto err1; 68 goto err1;
66 69
67 /* In case of skip_init sdi_init has already enabled the clocks */ 70 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
68 if (!sdi.skip_init)
69 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
70 71
71 sdi_basic_init(); 72 sdi_basic_init(dssdev);
72 73
73 /* 15.5.9.1.2 */ 74 /* 15.5.9.1.2 */
74 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; 75 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
75 76
76 dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, 77 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
77 dssdev->panel.acb); 78 dssdev->panel.acbi, dssdev->panel.acb);
78
79 if (!sdi.skip_init) {
80 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
81 &dss_cinfo, &dispc_cinfo);
82 } else {
83 r = dss_get_clock_div(&dss_cinfo);
84 r = dispc_get_clock_div(&dispc_cinfo);
85 }
86 79
80 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
81 &dss_cinfo, &dispc_cinfo);
87 if (r) 82 if (r)
88 goto err2; 83 goto err2;
89 84
@@ -102,31 +97,27 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
102 } 97 }
103 98
104 99
105 dispc_set_lcd_timings(t); 100 dispc_set_lcd_timings(dssdev->manager->id, t);
106 101
107 r = dss_set_clock_div(&dss_cinfo); 102 r = dss_set_clock_div(&dss_cinfo);
108 if (r) 103 if (r)
109 goto err2; 104 goto err2;
110 105
111 r = dispc_set_clock_div(&dispc_cinfo); 106 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
112 if (r) 107 if (r)
113 goto err2; 108 goto err2;
114 109
115 if (!sdi.skip_init) { 110 dss_sdi_init(dssdev->phy.sdi.datapairs);
116 dss_sdi_init(dssdev->phy.sdi.datapairs); 111 r = dss_sdi_enable();
117 r = dss_sdi_enable(); 112 if (r)
118 if (r) 113 goto err1;
119 goto err1; 114 mdelay(2);
120 mdelay(2);
121 }
122 115
123 dssdev->manager->enable(dssdev->manager); 116 dssdev->manager->enable(dssdev->manager);
124 117
125 sdi.skip_init = 0;
126
127 return 0; 118 return 0;
128err2: 119err2:
129 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 120 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
130 regulator_disable(sdi.vdds_sdi_reg); 121 regulator_disable(sdi.vdds_sdi_reg);
131err1: 122err1:
132 omap_dss_stop_device(dssdev); 123 omap_dss_stop_device(dssdev);
@@ -141,7 +132,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
141 132
142 dss_sdi_disable(); 133 dss_sdi_disable();
143 134
144 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 135 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
145 136
146 regulator_disable(sdi.vdds_sdi_reg); 137 regulator_disable(sdi.vdds_sdi_reg);
147 138
@@ -153,25 +144,24 @@ int sdi_init_display(struct omap_dss_device *dssdev)
153{ 144{
154 DSSDBG("SDI init\n"); 145 DSSDBG("SDI init\n");
155 146
147 if (sdi.vdds_sdi_reg == NULL) {
148 struct regulator *vdds_sdi;
149
150 vdds_sdi = dss_get_vdds_sdi();
151
152 if (IS_ERR(vdds_sdi)) {
153 DSSERR("can't get VDDS_SDI regulator\n");
154 return PTR_ERR(vdds_sdi);
155 }
156
157 sdi.vdds_sdi_reg = vdds_sdi;
158 }
159
156 return 0; 160 return 0;
157} 161}
158 162
159int sdi_init(bool skip_init) 163int sdi_init(void)
160{ 164{
161 /* we store this for first display enable, then clear it */
162 sdi.skip_init = skip_init;
163
164 sdi.vdds_sdi_reg = dss_get_vdds_sdi();
165 if (IS_ERR(sdi.vdds_sdi_reg)) {
166 DSSERR("can't get VDDS_SDI regulator\n");
167 return PTR_ERR(sdi.vdds_sdi_reg);
168 }
169 /*
170 * Enable clocks already here, otherwise there would be a toggle
171 * of them until sdi_display_enable is called.
172 */
173 if (skip_init)
174 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
175 return 0; 165 return 0;
176} 166}
177 167
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff35050e28a..980f919ed987 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -34,13 +34,11 @@
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 36
37#include <plat/display.h> 37#include <video/omapdss.h>
38#include <plat/cpu.h> 38#include <plat/cpu.h>
39 39
40#include "dss.h" 40#include "dss.h"
41 41
42#define VENC_BASE 0x48050C00
43
44/* Venc registers */ 42/* Venc registers */
45#define VENC_REV_ID 0x00 43#define VENC_REV_ID 0x00
46#define VENC_STATUS 0x04 44#define VENC_STATUS 0x04
@@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
289EXPORT_SYMBOL(omap_dss_ntsc_timings); 287EXPORT_SYMBOL(omap_dss_ntsc_timings);
290 288
291static struct { 289static struct {
290 struct platform_device *pdev;
292 void __iomem *base; 291 void __iomem *base;
293 struct mutex venc_lock; 292 struct mutex venc_lock;
294 u32 wss_data; 293 u32 wss_data;
@@ -374,18 +373,21 @@ static void venc_reset(void)
374 } 373 }
375 } 374 }
376 375
376#ifdef CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET
377 /* the magical sleep that makes things work */ 377 /* the magical sleep that makes things work */
378 /* XXX more info? What bug this circumvents? */
378 msleep(20); 379 msleep(20);
380#endif
379} 381}
380 382
381static void venc_enable_clocks(int enable) 383static void venc_enable_clocks(int enable)
382{ 384{
383 if (enable) 385 if (enable)
384 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 386 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
385 DSS_CLK_96M); 387 DSS_CLK_VIDFCK);
386 else 388 else
387 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | 389 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
388 DSS_CLK_96M); 390 DSS_CLK_VIDFCK);
389} 391}
390 392
391static const struct venc_config *venc_timings_to_config( 393static const struct venc_config *venc_timings_to_config(
@@ -474,6 +476,12 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
474 476
475 mutex_lock(&venc.venc_lock); 477 mutex_lock(&venc.venc_lock);
476 478
479 r = omap_dss_start_device(dssdev);
480 if (r) {
481 DSSERR("failed to start device\n");
482 goto err0;
483 }
484
477 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 485 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
478 r = -EINVAL; 486 r = -EINVAL;
479 goto err1; 487 goto err1;
@@ -485,10 +493,11 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
485 493
486 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 494 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
487 495
488 /* wait couple of vsyncs until enabling the LCD */ 496 mutex_unlock(&venc.venc_lock);
489 msleep(50); 497 return 0;
490
491err1: 498err1:
499 omap_dss_stop_device(dssdev);
500err0:
492 mutex_unlock(&venc.venc_lock); 501 mutex_unlock(&venc.venc_lock);
493 502
494 return r; 503 return r;
@@ -511,10 +520,9 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
511 520
512 venc_power_off(dssdev); 521 venc_power_off(dssdev);
513 522
514 /* wait at least 5 vsyncs after disabling the LCD */
515 msleep(100);
516
517 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 523 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
524
525 omap_dss_stop_device(dssdev);
518end: 526end:
519 mutex_unlock(&venc.venc_lock); 527 mutex_unlock(&venc.venc_lock);
520} 528}
@@ -641,50 +649,23 @@ static struct omap_dss_driver venc_driver = {
641}; 649};
642/* driver end */ 650/* driver end */
643 651
644 652int venc_init_display(struct omap_dss_device *dssdev)
645
646int venc_init(struct platform_device *pdev)
647{ 653{
648 u8 rev_id; 654 DSSDBG("init_display\n");
649 655
650 mutex_init(&venc.venc_lock); 656 if (venc.vdda_dac_reg == NULL) {
657 struct regulator *vdda_dac;
651 658
652 venc.wss_data = 0; 659 vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac");
653 660
654 venc.base = ioremap(VENC_BASE, SZ_1K); 661 if (IS_ERR(vdda_dac)) {
655 if (!venc.base) { 662 DSSERR("can't get VDDA_DAC regulator\n");
656 DSSERR("can't ioremap VENC\n"); 663 return PTR_ERR(vdda_dac);
657 return -ENOMEM; 664 }
658 }
659 665
660 venc.vdda_dac_reg = dss_get_vdda_dac(); 666 venc.vdda_dac_reg = vdda_dac;
661 if (IS_ERR(venc.vdda_dac_reg)) {
662 iounmap(venc.base);
663 DSSERR("can't get VDDA_DAC regulator\n");
664 return PTR_ERR(venc.vdda_dac_reg);
665 } 667 }
666 668
667 venc_enable_clocks(1);
668
669 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
670 printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
671
672 venc_enable_clocks(0);
673
674 return omap_dss_register_driver(&venc_driver);
675}
676
677void venc_exit(void)
678{
679 omap_dss_unregister_driver(&venc_driver);
680
681 iounmap(venc.base);
682}
683
684int venc_init_display(struct omap_dss_device *dssdev)
685{
686 DSSDBG("init_display\n");
687
688 return 0; 669 return 0;
689} 670}
690 671
@@ -740,3 +721,73 @@ void venc_dump_regs(struct seq_file *s)
740 721
741#undef DUMPREG 722#undef DUMPREG
742} 723}
724
725/* VENC HW IP initialisation */
726static int omap_venchw_probe(struct platform_device *pdev)
727{
728 u8 rev_id;
729 struct resource *venc_mem;
730
731 venc.pdev = pdev;
732
733 mutex_init(&venc.venc_lock);
734
735 venc.wss_data = 0;
736
737 venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
738 if (!venc_mem) {
739 DSSERR("can't get IORESOURCE_MEM VENC\n");
740 return -EINVAL;
741 }
742 venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
743 if (!venc.base) {
744 DSSERR("can't ioremap VENC\n");
745 return -ENOMEM;
746 }
747
748 venc_enable_clocks(1);
749
750 rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
751 dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
752
753 venc_enable_clocks(0);
754
755 return omap_dss_register_driver(&venc_driver);
756}
757
758static int omap_venchw_remove(struct platform_device *pdev)
759{
760 if (venc.vdda_dac_reg != NULL) {
761 regulator_put(venc.vdda_dac_reg);
762 venc.vdda_dac_reg = NULL;
763 }
764 omap_dss_unregister_driver(&venc_driver);
765
766 iounmap(venc.base);
767 return 0;
768}
769
770static struct platform_driver omap_venchw_driver = {
771 .probe = omap_venchw_probe,
772 .remove = omap_venchw_remove,
773 .driver = {
774 .name = "omapdss_venc",
775 .owner = THIS_MODULE,
776 },
777};
778
779int venc_init_platform_driver(void)
780{
781 if (cpu_is_omap44xx())
782 return 0;
783
784 return platform_driver_register(&omap_venchw_driver);
785}
786
787void venc_uninit_platform_driver(void)
788{
789 if (cpu_is_omap44xx())
790 return;
791
792 return platform_driver_unregister(&omap_venchw_driver);
793}