aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c8
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c8
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c14
-rw-r--r--drivers/video/omap2/dss/core.c343
-rw-r--r--drivers/video/omap2/dss/dss.c334
-rw-r--r--drivers/video/omap2/dss/dss.h13
6 files changed, 360 insertions, 360 deletions
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 0a992bc8d0d8..9ece62a44a3f 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1786,10 +1786,10 @@ static struct omap_clk omap2420_clks[] = {
1786 CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X), 1786 CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X),
1787 CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), 1787 CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
1788 /* DSS domain clocks */ 1788 /* DSS domain clocks */
1789 CLK("omapdss", "ick", &dss_ick, CK_242X), 1789 CLK("omapdss_dss", "ick", &dss_ick, CK_242X),
1790 CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X), 1790 CLK("omapdss_dss", "dss1_fck", &dss1_fck, CK_242X),
1791 CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X), 1791 CLK("omapdss_dss", "dss2_fck", &dss2_fck, CK_242X),
1792 CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X), 1792 CLK("omapdss_dss", "tv_fck", &dss_54m_fck, CK_242X),
1793 /* L3 domain clocks */ 1793 /* L3 domain clocks */
1794 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), 1794 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X),
1795 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), 1795 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 5c647ce05b04..61006ae7eac4 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1890,10 +1890,10 @@ static struct omap_clk omap2430_clks[] = {
1890 CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), 1890 CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
1891 CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), 1891 CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
1892 /* DSS domain clocks */ 1892 /* DSS domain clocks */
1893 CLK("omapdss", "ick", &dss_ick, CK_243X), 1893 CLK("omapdss_dss", "ick", &dss_ick, CK_243X),
1894 CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X), 1894 CLK("omapdss_dss", "dss1_fck", &dss1_fck, CK_243X),
1895 CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X), 1895 CLK("omapdss_dss", "dss2_fck", &dss2_fck, CK_243X),
1896 CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X), 1896 CLK("omapdss_dss", "tv_fck", &dss_54m_fck, CK_243X),
1897 /* L3 domain clocks */ 1897 /* L3 domain clocks */
1898 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), 1898 CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X),
1899 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), 1899 CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 052ac329282f..2e47d16fce77 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3357,13 +3357,13 @@ static struct omap_clk omap3xxx_clks[] = {
3357 CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), 3357 CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
3358 CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), 3358 CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
3359 CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), 3359 CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
3360 CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), 3360 CLK("omapdss_dss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
3361 CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3361 CLK("omapdss_dss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3362 CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX), 3362 CLK("omapdss_dss", "tv_fck", &dss_tv_fck, CK_3XXX),
3363 CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX), 3363 CLK("omapdss_dss", "video_fck", &dss_96m_fck, CK_3XXX),
3364 CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX), 3364 CLK("omapdss_dss", "dss2_fck", &dss2_alwon_fck, CK_3XXX),
3365 CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1), 3365 CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
3366 CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3366 CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3367 CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), 3367 CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
3368 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), 3368 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
3369 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), 3369 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index e399ca22e514..255935541d0d 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -34,32 +34,18 @@
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/clock.h>
38 37
39#include "dss.h" 38#include "dss.h"
40#include "dss_features.h" 39#include "dss_features.h"
41 40
42static struct { 41static struct {
43 struct platform_device *pdev; 42 struct platform_device *pdev;
44 int ctx_id;
45
46 struct clk *dss_ick;
47 struct clk *dss1_fck;
48 struct clk *dss2_fck;
49 struct clk *dss_54m_fck;
50 struct clk *dss_96m_fck;
51 unsigned num_clks_enabled;
52 43
53 struct regulator *vdds_dsi_reg; 44 struct regulator *vdds_dsi_reg;
54 struct regulator *vdds_sdi_reg; 45 struct regulator *vdds_sdi_reg;
55 struct regulator *vdda_dac_reg; 46 struct regulator *vdda_dac_reg;
56} core; 47} core;
57 48
58static void dss_clk_enable_all_no_ctx(void);
59static void dss_clk_disable_all_no_ctx(void);
60static void dss_clk_enable_no_ctx(enum dss_clock clks);
61static void dss_clk_disable_no_ctx(enum dss_clock clks);
62
63static char *def_disp_name; 49static char *def_disp_name;
64module_param_named(def_disp, def_disp_name, charp, 0); 50module_param_named(def_disp, def_disp_name, charp, 0);
65MODULE_PARM_DESC(def_disp_name, "default display name"); 51MODULE_PARM_DESC(def_disp_name, "default display name");
@@ -69,297 +55,6 @@ unsigned int dss_debug;
69module_param_named(debug, dss_debug, bool, 0644); 55module_param_named(debug, dss_debug, bool, 0644);
70#endif 56#endif
71 57
72/* CONTEXT */
73static int dss_get_ctx_id(void)
74{
75 struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
76 int r;
77
78 if (!pdata->get_last_off_on_transaction_id)
79 return 0;
80 r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
81 if (r < 0) {
82 dev_err(&core.pdev->dev, "getting transaction ID failed, "
83 "will force context restore\n");
84 r = -1;
85 }
86 return r;
87}
88
89int dss_need_ctx_restore(void)
90{
91 int id = dss_get_ctx_id();
92
93 if (id < 0 || id != core.ctx_id) {
94 DSSDBG("ctx id %d -> id %d\n",
95 core.ctx_id, id);
96 core.ctx_id = id;
97 return 1;
98 } else {
99 return 0;
100 }
101}
102
103static void save_all_ctx(void)
104{
105 DSSDBG("save context\n");
106
107 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
108
109 dss_save_context();
110 dispc_save_context();
111#ifdef CONFIG_OMAP2_DSS_DSI
112 dsi_save_context();
113#endif
114
115 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
116}
117
118static void restore_all_ctx(void)
119{
120 DSSDBG("restore context\n");
121
122 dss_clk_enable_all_no_ctx();
123
124 dss_restore_context();
125 dispc_restore_context();
126#ifdef CONFIG_OMAP2_DSS_DSI
127 dsi_restore_context();
128#endif
129
130 dss_clk_disable_all_no_ctx();
131}
132
133#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
134/* CLOCKS */
135static void core_dump_clocks(struct seq_file *s)
136{
137 int i;
138 struct clk *clocks[5] = {
139 core.dss_ick,
140 core.dss1_fck,
141 core.dss2_fck,
142 core.dss_54m_fck,
143 core.dss_96m_fck
144 };
145
146 seq_printf(s, "- CORE -\n");
147
148 seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
149
150 for (i = 0; i < 5; i++) {
151 if (!clocks[i])
152 continue;
153 seq_printf(s, "%-15s\t%lu\t%d\n",
154 clocks[i]->name,
155 clk_get_rate(clocks[i]),
156 clocks[i]->usecount);
157 }
158}
159#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
160
161static int dss_get_clock(struct clk **clock, const char *clk_name)
162{
163 struct clk *clk;
164
165 clk = clk_get(&core.pdev->dev, clk_name);
166
167 if (IS_ERR(clk)) {
168 DSSERR("can't get clock %s", clk_name);
169 return PTR_ERR(clk);
170 }
171
172 *clock = clk;
173
174 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
175
176 return 0;
177}
178
179static int dss_get_clocks(void)
180{
181 int r;
182
183 core.dss_ick = NULL;
184 core.dss1_fck = NULL;
185 core.dss2_fck = NULL;
186 core.dss_54m_fck = NULL;
187 core.dss_96m_fck = NULL;
188
189 r = dss_get_clock(&core.dss_ick, "ick");
190 if (r)
191 goto err;
192
193 r = dss_get_clock(&core.dss1_fck, "dss1_fck");
194 if (r)
195 goto err;
196
197 r = dss_get_clock(&core.dss2_fck, "dss2_fck");
198 if (r)
199 goto err;
200
201 r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
202 if (r)
203 goto err;
204
205 r = dss_get_clock(&core.dss_96m_fck, "video_fck");
206 if (r)
207 goto err;
208
209 return 0;
210
211err:
212 if (core.dss_ick)
213 clk_put(core.dss_ick);
214 if (core.dss1_fck)
215 clk_put(core.dss1_fck);
216 if (core.dss2_fck)
217 clk_put(core.dss2_fck);
218 if (core.dss_54m_fck)
219 clk_put(core.dss_54m_fck);
220 if (core.dss_96m_fck)
221 clk_put(core.dss_96m_fck);
222
223 return r;
224}
225
226static void dss_put_clocks(void)
227{
228 if (core.dss_96m_fck)
229 clk_put(core.dss_96m_fck);
230 clk_put(core.dss_54m_fck);
231 clk_put(core.dss1_fck);
232 clk_put(core.dss2_fck);
233 clk_put(core.dss_ick);
234}
235
236unsigned long dss_clk_get_rate(enum dss_clock clk)
237{
238 switch (clk) {
239 case DSS_CLK_ICK:
240 return clk_get_rate(core.dss_ick);
241 case DSS_CLK_FCK1:
242 return clk_get_rate(core.dss1_fck);
243 case DSS_CLK_FCK2:
244 return clk_get_rate(core.dss2_fck);
245 case DSS_CLK_54M:
246 return clk_get_rate(core.dss_54m_fck);
247 case DSS_CLK_96M:
248 return clk_get_rate(core.dss_96m_fck);
249 }
250
251 BUG();
252 return 0;
253}
254
255static unsigned count_clk_bits(enum dss_clock clks)
256{
257 unsigned num_clks = 0;
258
259 if (clks & DSS_CLK_ICK)
260 ++num_clks;
261 if (clks & DSS_CLK_FCK1)
262 ++num_clks;
263 if (clks & DSS_CLK_FCK2)
264 ++num_clks;
265 if (clks & DSS_CLK_54M)
266 ++num_clks;
267 if (clks & DSS_CLK_96M)
268 ++num_clks;
269
270 return num_clks;
271}
272
273static void dss_clk_enable_no_ctx(enum dss_clock clks)
274{
275 unsigned num_clks = count_clk_bits(clks);
276
277 if (clks & DSS_CLK_ICK)
278 clk_enable(core.dss_ick);
279 if (clks & DSS_CLK_FCK1)
280 clk_enable(core.dss1_fck);
281 if (clks & DSS_CLK_FCK2)
282 clk_enable(core.dss2_fck);
283 if (clks & DSS_CLK_54M)
284 clk_enable(core.dss_54m_fck);
285 if (clks & DSS_CLK_96M)
286 clk_enable(core.dss_96m_fck);
287
288 core.num_clks_enabled += num_clks;
289}
290
291void dss_clk_enable(enum dss_clock clks)
292{
293 bool check_ctx = core.num_clks_enabled == 0;
294
295 dss_clk_enable_no_ctx(clks);
296
297 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
298 restore_all_ctx();
299}
300
301static void dss_clk_disable_no_ctx(enum dss_clock clks)
302{
303 unsigned num_clks = count_clk_bits(clks);
304
305 if (clks & DSS_CLK_ICK)
306 clk_disable(core.dss_ick);
307 if (clks & DSS_CLK_FCK1)
308 clk_disable(core.dss1_fck);
309 if (clks & DSS_CLK_FCK2)
310 clk_disable(core.dss2_fck);
311 if (clks & DSS_CLK_54M)
312 clk_disable(core.dss_54m_fck);
313 if (clks & DSS_CLK_96M)
314 clk_disable(core.dss_96m_fck);
315
316 core.num_clks_enabled -= num_clks;
317}
318
319void dss_clk_disable(enum dss_clock clks)
320{
321 if (cpu_is_omap34xx()) {
322 unsigned num_clks = count_clk_bits(clks);
323
324 BUG_ON(core.num_clks_enabled < num_clks);
325
326 if (core.num_clks_enabled == num_clks)
327 save_all_ctx();
328 }
329
330 dss_clk_disable_no_ctx(clks);
331}
332
333static void dss_clk_enable_all_no_ctx(void)
334{
335 enum dss_clock clks;
336
337 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
338 if (cpu_is_omap34xx())
339 clks |= DSS_CLK_96M;
340 dss_clk_enable_no_ctx(clks);
341}
342
343static void dss_clk_disable_all_no_ctx(void)
344{
345 enum dss_clock clks;
346
347 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
348 if (cpu_is_omap34xx())
349 clks |= DSS_CLK_96M;
350 dss_clk_disable_no_ctx(clks);
351}
352
353static void dss_clk_disable_all(void)
354{
355 enum dss_clock clks;
356
357 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
358 if (cpu_is_omap34xx())
359 clks |= DSS_CLK_96M;
360 dss_clk_disable(clks);
361}
362
363/* REGULATORS */ 58/* REGULATORS */
364 59
365struct regulator *dss_get_vdds_dsi(void) 60struct regulator *dss_get_vdds_dsi(void)
@@ -404,18 +99,7 @@ struct regulator *dss_get_vdda_dac(void)
404 return reg; 99 return reg;
405} 100}
406 101
407/* DEBUGFS */
408#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) 102#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
409static void dss_debug_dump_clocks(struct seq_file *s)
410{
411 core_dump_clocks(s);
412 dss_dump_clocks(s);
413 dispc_dump_clocks(s);
414#ifdef CONFIG_OMAP2_DSS_DSI
415 dsi_dump_clocks(s);
416#endif
417}
418
419static int dss_debug_show(struct seq_file *s, void *unused) 103static int dss_debug_show(struct seq_file *s, void *unused)
420{ 104{
421 void (*func)(struct seq_file *) = s->private; 105 void (*func)(struct seq_file *) = s->private;
@@ -508,21 +192,15 @@ static int omap_dss_probe(struct platform_device *pdev)
508 dss_init_overlay_managers(pdev); 192 dss_init_overlay_managers(pdev);
509 dss_init_overlays(pdev); 193 dss_init_overlays(pdev);
510 194
511 r = dss_get_clocks();
512 if (r)
513 goto err_clocks;
514
515 dss_clk_enable_all_no_ctx();
516
517 core.ctx_id = dss_get_ctx_id();
518 DSSDBG("initial ctx id %u\n", core.ctx_id);
519
520 r = dss_init_platform_driver(); 195 r = dss_init_platform_driver();
521 if (r) { 196 if (r) {
522 DSSERR("Failed to initialize DSS platform driver\n"); 197 DSSERR("Failed to initialize DSS platform driver\n");
523 goto err_dss; 198 goto err_dss;
524 } 199 }
525 200
201 /* keep clocks enabled to prevent context saves/restores during init */
202 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
203
526 r = rfbi_init(); 204 r = rfbi_init();
527 if (r) { 205 if (r) {
528 DSSERR("Failed to initialize rfbi\n"); 206 DSSERR("Failed to initialize rfbi\n");
@@ -588,7 +266,7 @@ static int omap_dss_probe(struct platform_device *pdev)
588 pdata->default_device = dssdev; 266 pdata->default_device = dssdev;
589 } 267 }
590 268
591 dss_clk_disable_all(); 269 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
592 270
593 return 0; 271 return 0;
594 272
@@ -611,9 +289,6 @@ err_dpi:
611err_rfbi: 289err_rfbi:
612 dss_uninit_platform_driver(); 290 dss_uninit_platform_driver();
613err_dss: 291err_dss:
614 dss_clk_disable_all_no_ctx();
615 dss_put_clocks();
616err_clocks:
617 292
618 return r; 293 return r;
619} 294}
@@ -636,16 +311,6 @@ static int omap_dss_remove(struct platform_device *pdev)
636 311
637 dss_uninit_platform_driver(); 312 dss_uninit_platform_driver();
638 313
639 /*
640 * As part of hwmod changes, DSS is not the only controller of dss
641 * clocks; hwmod framework itself will also enable clocks during hwmod
642 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
643 * need to disable clocks if their usecounts > 1.
644 */
645 WARN_ON(core.num_clks_enabled > 0);
646
647 dss_put_clocks();
648
649 dss_uninit_overlays(pdev); 314 dss_uninit_overlays(pdev);
650 dss_uninit_overlay_managers(pdev); 315 dss_uninit_overlay_managers(pdev);
651 316
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 01406f48f438..72b395d69aae 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,6 +31,7 @@
31#include <linux/clk.h> 31#include <linux/clk.h>
32 32
33#include <plat/display.h> 33#include <plat/display.h>
34#include <plat/clock.h>
34#include "dss.h" 35#include "dss.h"
35 36
36#define DSS_BASE 0x48050000 37#define DSS_BASE 0x48050000
@@ -61,8 +62,15 @@ struct dss_reg {
61static struct { 62static struct {
62 struct platform_device *pdev; 63 struct platform_device *pdev;
63 void __iomem *base; 64 void __iomem *base;
65 int ctx_id;
64 66
65 struct clk *dpll4_m4_ck; 67 struct clk *dpll4_m4_ck;
68 struct clk *dss_ick;
69 struct clk *dss1_fck;
70 struct clk *dss2_fck;
71 struct clk *dss_54m_fck;
72 struct clk *dss_96m_fck;
73 unsigned num_clks_enabled;
66 74
67 unsigned long cache_req_pck; 75 unsigned long cache_req_pck;
68 unsigned long cache_prate; 76 unsigned long cache_prate;
@@ -75,6 +83,11 @@ static struct {
75 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 83 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
76} dss; 84} dss;
77 85
86static void dss_clk_enable_all_no_ctx(void);
87static void dss_clk_disable_all_no_ctx(void);
88static void dss_clk_enable_no_ctx(enum dss_clock clks);
89static void dss_clk_disable_no_ctx(enum dss_clock clks);
90
78static int _omap_dss_wait_reset(void); 91static int _omap_dss_wait_reset(void);
79 92
80static inline void dss_write_reg(const struct dss_reg idx, u32 val) 93static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -640,6 +653,301 @@ static void dss_exit(void)
640 iounmap(dss.base); 653 iounmap(dss.base);
641} 654}
642 655
656/* CONTEXT */
657static int dss_get_ctx_id(void)
658{
659 struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
660 int r;
661
662 if (!pdata->board_data->get_last_off_on_transaction_id)
663 return 0;
664 r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
665 if (r < 0) {
666 dev_err(&dss.pdev->dev, "getting transaction ID failed, "
667 "will force context restore\n");
668 r = -1;
669 }
670 return r;
671}
672
673int dss_need_ctx_restore(void)
674{
675 int id = dss_get_ctx_id();
676
677 if (id < 0 || id != dss.ctx_id) {
678 DSSDBG("ctx id %d -> id %d\n",
679 dss.ctx_id, id);
680 dss.ctx_id = id;
681 return 1;
682 } else {
683 return 0;
684 }
685}
686
687static void save_all_ctx(void)
688{
689 DSSDBG("save context\n");
690
691 dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
692
693 dss_save_context();
694 dispc_save_context();
695#ifdef CONFIG_OMAP2_DSS_DSI
696 dsi_save_context();
697#endif
698
699 dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
700}
701
702static void restore_all_ctx(void)
703{
704 DSSDBG("restore context\n");
705
706 dss_clk_enable_all_no_ctx();
707
708 dss_restore_context();
709 dispc_restore_context();
710#ifdef CONFIG_OMAP2_DSS_DSI
711 dsi_restore_context();
712#endif
713
714 dss_clk_disable_all_no_ctx();
715}
716
717static int dss_get_clock(struct clk **clock, const char *clk_name)
718{
719 struct clk *clk;
720
721 clk = clk_get(&dss.pdev->dev, clk_name);
722
723 if (IS_ERR(clk)) {
724 DSSERR("can't get clock %s", clk_name);
725 return PTR_ERR(clk);
726 }
727
728 *clock = clk;
729
730 DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
731
732 return 0;
733}
734
735static int dss_get_clocks(void)
736{
737 int r;
738
739 dss.dss_ick = NULL;
740 dss.dss1_fck = NULL;
741 dss.dss2_fck = NULL;
742 dss.dss_54m_fck = NULL;
743 dss.dss_96m_fck = NULL;
744
745 r = dss_get_clock(&dss.dss_ick, "ick");
746 if (r)
747 goto err;
748
749 r = dss_get_clock(&dss.dss1_fck, "dss1_fck");
750 if (r)
751 goto err;
752
753 r = dss_get_clock(&dss.dss2_fck, "dss2_fck");
754 if (r)
755 goto err;
756
757 r = dss_get_clock(&dss.dss_54m_fck, "tv_fck");
758 if (r)
759 goto err;
760
761 r = dss_get_clock(&dss.dss_96m_fck, "video_fck");
762 if (r)
763 goto err;
764
765 return 0;
766
767err:
768 if (dss.dss_ick)
769 clk_put(dss.dss_ick);
770 if (dss.dss1_fck)
771 clk_put(dss.dss1_fck);
772 if (dss.dss2_fck)
773 clk_put(dss.dss2_fck);
774 if (dss.dss_54m_fck)
775 clk_put(dss.dss_54m_fck);
776 if (dss.dss_96m_fck)
777 clk_put(dss.dss_96m_fck);
778
779 return r;
780}
781
782static void dss_put_clocks(void)
783{
784 if (dss.dss_96m_fck)
785 clk_put(dss.dss_96m_fck);
786 clk_put(dss.dss_54m_fck);
787 clk_put(dss.dss1_fck);
788 clk_put(dss.dss2_fck);
789 clk_put(dss.dss_ick);
790}
791
792unsigned long dss_clk_get_rate(enum dss_clock clk)
793{
794 switch (clk) {
795 case DSS_CLK_ICK:
796 return clk_get_rate(dss.dss_ick);
797 case DSS_CLK_FCK1:
798 return clk_get_rate(dss.dss1_fck);
799 case DSS_CLK_FCK2:
800 return clk_get_rate(dss.dss2_fck);
801 case DSS_CLK_54M:
802 return clk_get_rate(dss.dss_54m_fck);
803 case DSS_CLK_96M:
804 return clk_get_rate(dss.dss_96m_fck);
805 }
806
807 BUG();
808 return 0;
809}
810
811static unsigned count_clk_bits(enum dss_clock clks)
812{
813 unsigned num_clks = 0;
814
815 if (clks & DSS_CLK_ICK)
816 ++num_clks;
817 if (clks & DSS_CLK_FCK1)
818 ++num_clks;
819 if (clks & DSS_CLK_FCK2)
820 ++num_clks;
821 if (clks & DSS_CLK_54M)
822 ++num_clks;
823 if (clks & DSS_CLK_96M)
824 ++num_clks;
825
826 return num_clks;
827}
828
829static void dss_clk_enable_no_ctx(enum dss_clock clks)
830{
831 unsigned num_clks = count_clk_bits(clks);
832
833 if (clks & DSS_CLK_ICK)
834 clk_enable(dss.dss_ick);
835 if (clks & DSS_CLK_FCK1)
836 clk_enable(dss.dss1_fck);
837 if (clks & DSS_CLK_FCK2)
838 clk_enable(dss.dss2_fck);
839 if (clks & DSS_CLK_54M)
840 clk_enable(dss.dss_54m_fck);
841 if (clks & DSS_CLK_96M)
842 clk_enable(dss.dss_96m_fck);
843
844 dss.num_clks_enabled += num_clks;
845}
846
847void dss_clk_enable(enum dss_clock clks)
848{
849 bool check_ctx = dss.num_clks_enabled == 0;
850
851 dss_clk_enable_no_ctx(clks);
852
853 if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
854 restore_all_ctx();
855}
856
857static void dss_clk_disable_no_ctx(enum dss_clock clks)
858{
859 unsigned num_clks = count_clk_bits(clks);
860
861 if (clks & DSS_CLK_ICK)
862 clk_disable(dss.dss_ick);
863 if (clks & DSS_CLK_FCK1)
864 clk_disable(dss.dss1_fck);
865 if (clks & DSS_CLK_FCK2)
866 clk_disable(dss.dss2_fck);
867 if (clks & DSS_CLK_54M)
868 clk_disable(dss.dss_54m_fck);
869 if (clks & DSS_CLK_96M)
870 clk_disable(dss.dss_96m_fck);
871
872 dss.num_clks_enabled -= num_clks;
873}
874
875void dss_clk_disable(enum dss_clock clks)
876{
877 if (cpu_is_omap34xx()) {
878 unsigned num_clks = count_clk_bits(clks);
879
880 BUG_ON(dss.num_clks_enabled < num_clks);
881
882 if (dss.num_clks_enabled == num_clks)
883 save_all_ctx();
884 }
885
886 dss_clk_disable_no_ctx(clks);
887}
888
889static void dss_clk_enable_all_no_ctx(void)
890{
891 enum dss_clock clks;
892
893 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
894 if (cpu_is_omap34xx())
895 clks |= DSS_CLK_96M;
896 dss_clk_enable_no_ctx(clks);
897}
898
899static void dss_clk_disable_all_no_ctx(void)
900{
901 enum dss_clock clks;
902
903 clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
904 if (cpu_is_omap34xx())
905 clks |= DSS_CLK_96M;
906 dss_clk_disable_no_ctx(clks);
907}
908
909#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
910/* CLOCKS */
911static void core_dump_clocks(struct seq_file *s)
912{
913 int i;
914 struct clk *clocks[5] = {
915 dss.dss_ick,
916 dss.dss1_fck,
917 dss.dss2_fck,
918 dss.dss_54m_fck,
919 dss.dss_96m_fck
920 };
921
922 seq_printf(s, "- CORE -\n");
923
924 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
925
926 for (i = 0; i < 5; i++) {
927 if (!clocks[i])
928 continue;
929 seq_printf(s, "%-15s\t%lu\t%d\n",
930 clocks[i]->name,
931 clk_get_rate(clocks[i]),
932 clocks[i]->usecount);
933 }
934}
935#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
936
937/* DEBUGFS */
938#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
939void dss_debug_dump_clocks(struct seq_file *s)
940{
941 core_dump_clocks(s);
942 dss_dump_clocks(s);
943 dispc_dump_clocks(s);
944#ifdef CONFIG_OMAP2_DSS_DSI
945 dsi_dump_clocks(s);
946#endif
947}
948#endif
949
950
643/* DSS HW IP initialisation */ 951/* DSS HW IP initialisation */
644static int omap_dsshw_probe(struct platform_device *pdev) 952static int omap_dsshw_probe(struct platform_device *pdev)
645{ 953{
@@ -648,6 +956,15 @@ static int omap_dsshw_probe(struct platform_device *pdev)
648 956
649 dss.pdev = pdev; 957 dss.pdev = pdev;
650 958
959 r = dss_get_clocks();
960 if (r)
961 goto err_clocks;
962
963 dss_clk_enable_all_no_ctx();
964
965 dss.ctx_id = dss_get_ctx_id();
966 DSSDBG("initial ctx id %u\n", dss.ctx_id);
967
651#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT 968#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
652 /* DISPC_CONTROL */ 969 /* DISPC_CONTROL */
653 if (omap_readl(0x48050440) & 1) /* LCD enabled? */ 970 if (omap_readl(0x48050440) & 1) /* LCD enabled? */
@@ -660,15 +977,30 @@ static int omap_dsshw_probe(struct platform_device *pdev)
660 goto err_dss; 977 goto err_dss;
661 } 978 }
662 979
663err_dss: 980 dss_clk_disable_all_no_ctx();
981 return 0;
664 982
983err_dss:
984 dss_clk_disable_all_no_ctx();
985 dss_put_clocks();
986err_clocks:
665 return r; 987 return r;
666} 988}
667 989
668static int omap_dsshw_remove(struct platform_device *pdev) 990static int omap_dsshw_remove(struct platform_device *pdev)
669{ 991{
992
670 dss_exit(); 993 dss_exit();
671 994
995 /*
996 * As part of hwmod changes, DSS is not the only controller of dss
997 * clocks; hwmod framework itself will also enable clocks during hwmod
998 * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
999 * need to disable clocks if their usecounts > 1.
1000 */
1001 WARN_ON(dss.num_clks_enabled > 0);
1002
1003 dss_put_clocks();
672 return 0; 1004 return 0;
673} 1005}
674 1006
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 37c4544e8907..c535ee1db3ee 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -169,11 +169,6 @@ struct seq_file;
169struct platform_device; 169struct platform_device;
170 170
171/* core */ 171/* 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); 172struct bus_type *dss_get_bus(void);
178struct regulator *dss_get_vdds_dsi(void); 173struct regulator *dss_get_vdds_dsi(void);
179struct regulator *dss_get_vdds_sdi(void); 174struct regulator *dss_get_vdds_sdi(void);
@@ -219,8 +214,16 @@ void dss_uninit_platform_driver(void);
219 214
220void dss_save_context(void); 215void dss_save_context(void);
221void dss_restore_context(void); 216void dss_restore_context(void);
217void dss_clk_enable(enum dss_clock clks);
218void dss_clk_disable(enum dss_clock clks);
219unsigned long dss_clk_get_rate(enum dss_clock clk);
220int dss_need_ctx_restore(void);
221void dss_dump_clocks(struct seq_file *s);
222 222
223void dss_dump_regs(struct seq_file *s); 223void dss_dump_regs(struct seq_file *s);
224#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
225void dss_debug_dump_clocks(struct seq_file *s);
226#endif
224 227
225void dss_sdi_init(u8 datapairs); 228void dss_sdi_init(u8 datapairs);
226int dss_sdi_enable(void); 229int dss_sdi_enable(void);