]> Git Repo - linux.git/blob - drivers/gpu/drm/omapdrm/dss/dss.c
Merge branch '4.8/omapdrm-pll' (omapdrm PLL work)
[linux.git] / drivers / gpu / drm / omapdrm / dss / dss.c
1 /*
2  * linux/drivers/video/omap2/dss/dss.c
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  * Author: Tomi Valkeinen <[email protected]>
6  *
7  * Some code and ideas taken from drivers/video/omap/ driver
8  * by Imre Deak.
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published by
12  * the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #define DSS_SUBSYS_NAME "DSS"
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/io.h>
28 #include <linux/export.h>
29 #include <linux/err.h>
30 #include <linux/delay.h>
31 #include <linux/seq_file.h>
32 #include <linux/clk.h>
33 #include <linux/pinctrl/consumer.h>
34 #include <linux/platform_device.h>
35 #include <linux/pm_runtime.h>
36 #include <linux/gfp.h>
37 #include <linux/sizes.h>
38 #include <linux/mfd/syscon.h>
39 #include <linux/regmap.h>
40 #include <linux/of.h>
41 #include <linux/regulator/consumer.h>
42 #include <linux/suspend.h>
43 #include <linux/component.h>
44
45 #include <video/omapdss.h>
46
47 #include "dss.h"
48 #include "dss_features.h"
49
50 #define DSS_SZ_REGS                     SZ_512
51
52 struct dss_reg {
53         u16 idx;
54 };
55
56 #define DSS_REG(idx)                    ((const struct dss_reg) { idx })
57
58 #define DSS_REVISION                    DSS_REG(0x0000)
59 #define DSS_SYSCONFIG                   DSS_REG(0x0010)
60 #define DSS_SYSSTATUS                   DSS_REG(0x0014)
61 #define DSS_CONTROL                     DSS_REG(0x0040)
62 #define DSS_SDI_CONTROL                 DSS_REG(0x0044)
63 #define DSS_PLL_CONTROL                 DSS_REG(0x0048)
64 #define DSS_SDI_STATUS                  DSS_REG(0x005C)
65
66 #define REG_GET(idx, start, end) \
67         FLD_GET(dss_read_reg(idx), start, end)
68
69 #define REG_FLD_MOD(idx, val, start, end) \
70         dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
71
72 struct dss_features {
73         u8 fck_div_max;
74         u8 dss_fck_multiplier;
75         const char *parent_clk_name;
76         const enum omap_display_type *ports;
77         int num_ports;
78         int (*dpi_select_source)(int port, enum omap_channel channel);
79         int (*select_lcd_source)(enum omap_channel channel,
80                 enum dss_clk_source clk_src);
81 };
82
83 static struct {
84         struct platform_device *pdev;
85         void __iomem    *base;
86         struct regmap   *syscon_pll_ctrl;
87         u32             syscon_pll_ctrl_offset;
88
89         struct clk      *parent_clk;
90         struct clk      *dss_clk;
91         unsigned long   dss_clk_rate;
92
93         unsigned long   cache_req_pck;
94         unsigned long   cache_prate;
95         struct dispc_clock_info cache_dispc_cinfo;
96
97         enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
98         enum dss_clk_source dispc_clk_source;
99         enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
100
101         bool            ctx_valid;
102         u32             ctx[DSS_SZ_REGS / sizeof(u32)];
103
104         const struct dss_features *feat;
105
106         struct dss_pll  *video1_pll;
107         struct dss_pll  *video2_pll;
108 } dss;
109
110 static const char * const dss_generic_clk_source_names[] = {
111         [DSS_CLK_SRC_FCK]       = "FCK",
112         [DSS_CLK_SRC_PLL1_1]    = "PLL1:1",
113         [DSS_CLK_SRC_PLL1_2]    = "PLL1:2",
114         [DSS_CLK_SRC_PLL1_3]    = "PLL1:3",
115         [DSS_CLK_SRC_PLL2_1]    = "PLL2:1",
116         [DSS_CLK_SRC_PLL2_2]    = "PLL2:2",
117         [DSS_CLK_SRC_PLL2_3]    = "PLL2:3",
118         [DSS_CLK_SRC_HDMI_PLL]  = "HDMI PLL",
119 };
120
121 static bool dss_initialized;
122
123 bool omapdss_is_initialized(void)
124 {
125         return dss_initialized;
126 }
127 EXPORT_SYMBOL(omapdss_is_initialized);
128
129 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
130 {
131         __raw_writel(val, dss.base + idx.idx);
132 }
133
134 static inline u32 dss_read_reg(const struct dss_reg idx)
135 {
136         return __raw_readl(dss.base + idx.idx);
137 }
138
139 #define SR(reg) \
140         dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
141 #define RR(reg) \
142         dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
143
144 static void dss_save_context(void)
145 {
146         DSSDBG("dss_save_context\n");
147
148         SR(CONTROL);
149
150         if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
151                         OMAP_DISPLAY_TYPE_SDI) {
152                 SR(SDI_CONTROL);
153                 SR(PLL_CONTROL);
154         }
155
156         dss.ctx_valid = true;
157
158         DSSDBG("context saved\n");
159 }
160
161 static void dss_restore_context(void)
162 {
163         DSSDBG("dss_restore_context\n");
164
165         if (!dss.ctx_valid)
166                 return;
167
168         RR(CONTROL);
169
170         if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
171                         OMAP_DISPLAY_TYPE_SDI) {
172                 RR(SDI_CONTROL);
173                 RR(PLL_CONTROL);
174         }
175
176         DSSDBG("context restored\n");
177 }
178
179 #undef SR
180 #undef RR
181
182 void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
183 {
184         unsigned shift;
185         unsigned val;
186
187         if (!dss.syscon_pll_ctrl)
188                 return;
189
190         val = !enable;
191
192         switch (pll_id) {
193         case DSS_PLL_VIDEO1:
194                 shift = 0;
195                 break;
196         case DSS_PLL_VIDEO2:
197                 shift = 1;
198                 break;
199         case DSS_PLL_HDMI:
200                 shift = 2;
201                 break;
202         default:
203                 DSSERR("illegal DSS PLL ID %d\n", pll_id);
204                 return;
205         }
206
207         regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
208                 1 << shift, val << shift);
209 }
210
211 static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src,
212         enum omap_channel channel)
213 {
214         unsigned shift, val;
215
216         if (!dss.syscon_pll_ctrl)
217                 return -EINVAL;
218
219         switch (channel) {
220         case OMAP_DSS_CHANNEL_LCD:
221                 shift = 3;
222
223                 switch (clk_src) {
224                 case DSS_CLK_SRC_PLL1_1:
225                         val = 0; break;
226                 case DSS_CLK_SRC_HDMI_PLL:
227                         val = 1; break;
228                 default:
229                         DSSERR("error in PLL mux config for LCD\n");
230                         return -EINVAL;
231                 }
232
233                 break;
234         case OMAP_DSS_CHANNEL_LCD2:
235                 shift = 5;
236
237                 switch (clk_src) {
238                 case DSS_CLK_SRC_PLL1_3:
239                         val = 0; break;
240                 case DSS_CLK_SRC_PLL2_3:
241                         val = 1; break;
242                 case DSS_CLK_SRC_HDMI_PLL:
243                         val = 2; break;
244                 default:
245                         DSSERR("error in PLL mux config for LCD2\n");
246                         return -EINVAL;
247                 }
248
249                 break;
250         case OMAP_DSS_CHANNEL_LCD3:
251                 shift = 7;
252
253                 switch (clk_src) {
254                 case DSS_CLK_SRC_PLL2_1:
255                         val = 0; break;
256                 case DSS_CLK_SRC_PLL1_3:
257                         val = 1; break;
258                 case DSS_CLK_SRC_HDMI_PLL:
259                         val = 2; break;
260                 default:
261                         DSSERR("error in PLL mux config for LCD3\n");
262                         return -EINVAL;
263                 }
264
265                 break;
266         default:
267                 DSSERR("error in PLL mux config\n");
268                 return -EINVAL;
269         }
270
271         regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
272                 0x3 << shift, val << shift);
273
274         return 0;
275 }
276
277 void dss_sdi_init(int datapairs)
278 {
279         u32 l;
280
281         BUG_ON(datapairs > 3 || datapairs < 1);
282
283         l = dss_read_reg(DSS_SDI_CONTROL);
284         l = FLD_MOD(l, 0xf, 19, 15);            /* SDI_PDIV */
285         l = FLD_MOD(l, datapairs-1, 3, 2);      /* SDI_PRSEL */
286         l = FLD_MOD(l, 2, 1, 0);                /* SDI_BWSEL */
287         dss_write_reg(DSS_SDI_CONTROL, l);
288
289         l = dss_read_reg(DSS_PLL_CONTROL);
290         l = FLD_MOD(l, 0x7, 25, 22);    /* SDI_PLL_FREQSEL */
291         l = FLD_MOD(l, 0xb, 16, 11);    /* SDI_PLL_REGN */
292         l = FLD_MOD(l, 0xb4, 10, 1);    /* SDI_PLL_REGM */
293         dss_write_reg(DSS_PLL_CONTROL, l);
294 }
295
296 int dss_sdi_enable(void)
297 {
298         unsigned long timeout;
299
300         dispc_pck_free_enable(1);
301
302         /* Reset SDI PLL */
303         REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
304         udelay(1);      /* wait 2x PCLK */
305
306         /* Lock SDI PLL */
307         REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
308
309         /* Waiting for PLL lock request to complete */
310         timeout = jiffies + msecs_to_jiffies(500);
311         while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
312                 if (time_after_eq(jiffies, timeout)) {
313                         DSSERR("PLL lock request timed out\n");
314                         goto err1;
315                 }
316         }
317
318         /* Clearing PLL_GO bit */
319         REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
320
321         /* Waiting for PLL to lock */
322         timeout = jiffies + msecs_to_jiffies(500);
323         while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
324                 if (time_after_eq(jiffies, timeout)) {
325                         DSSERR("PLL lock timed out\n");
326                         goto err1;
327                 }
328         }
329
330         dispc_lcd_enable_signal(1);
331
332         /* Waiting for SDI reset to complete */
333         timeout = jiffies + msecs_to_jiffies(500);
334         while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
335                 if (time_after_eq(jiffies, timeout)) {
336                         DSSERR("SDI reset timed out\n");
337                         goto err2;
338                 }
339         }
340
341         return 0;
342
343  err2:
344         dispc_lcd_enable_signal(0);
345  err1:
346         /* Reset SDI PLL */
347         REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
348
349         dispc_pck_free_enable(0);
350
351         return -ETIMEDOUT;
352 }
353
354 void dss_sdi_disable(void)
355 {
356         dispc_lcd_enable_signal(0);
357
358         dispc_pck_free_enable(0);
359
360         /* Reset SDI PLL */
361         REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
362 }
363
364 const char *dss_get_clk_source_name(enum dss_clk_source clk_src)
365 {
366         return dss_generic_clk_source_names[clk_src];
367 }
368
369 void dss_dump_clocks(struct seq_file *s)
370 {
371         const char *fclk_name;
372         unsigned long fclk_rate;
373
374         if (dss_runtime_get())
375                 return;
376
377         seq_printf(s, "- DSS -\n");
378
379         fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK);
380         fclk_rate = clk_get_rate(dss.dss_clk);
381
382         seq_printf(s, "%s = %lu\n",
383                         fclk_name,
384                         fclk_rate);
385
386         dss_runtime_put();
387 }
388
389 static void dss_dump_regs(struct seq_file *s)
390 {
391 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
392
393         if (dss_runtime_get())
394                 return;
395
396         DUMPREG(DSS_REVISION);
397         DUMPREG(DSS_SYSCONFIG);
398         DUMPREG(DSS_SYSSTATUS);
399         DUMPREG(DSS_CONTROL);
400
401         if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
402                         OMAP_DISPLAY_TYPE_SDI) {
403                 DUMPREG(DSS_SDI_CONTROL);
404                 DUMPREG(DSS_PLL_CONTROL);
405                 DUMPREG(DSS_SDI_STATUS);
406         }
407
408         dss_runtime_put();
409 #undef DUMPREG
410 }
411
412 static int dss_get_channel_index(enum omap_channel channel)
413 {
414         switch (channel) {
415         case OMAP_DSS_CHANNEL_LCD:
416                 return 0;
417         case OMAP_DSS_CHANNEL_LCD2:
418                 return 1;
419         case OMAP_DSS_CHANNEL_LCD3:
420                 return 2;
421         default:
422                 WARN_ON(1);
423                 return 0;
424         }
425 }
426
427 static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
428 {
429         int b;
430         u8 start, end;
431
432         /*
433          * We always use PRCM clock as the DISPC func clock, except on DSS3,
434          * where we don't have separate DISPC and LCD clock sources.
435          */
436         if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) &&
437                 clk_src != DSS_CLK_SRC_FCK))
438                 return;
439
440         switch (clk_src) {
441         case DSS_CLK_SRC_FCK:
442                 b = 0;
443                 break;
444         case DSS_CLK_SRC_PLL1_1:
445                 b = 1;
446                 break;
447         case DSS_CLK_SRC_PLL2_1:
448                 b = 2;
449                 break;
450         default:
451                 BUG();
452                 return;
453         }
454
455         dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
456
457         REG_FLD_MOD(DSS_CONTROL, b, start, end);        /* DISPC_CLK_SWITCH */
458
459         dss.dispc_clk_source = clk_src;
460 }
461
462 void dss_select_dsi_clk_source(int dsi_module,
463                 enum dss_clk_source clk_src)
464 {
465         int b, pos;
466
467         switch (clk_src) {
468         case DSS_CLK_SRC_FCK:
469                 b = 0;
470                 break;
471         case DSS_CLK_SRC_PLL1_2:
472                 BUG_ON(dsi_module != 0);
473                 b = 1;
474                 break;
475         case DSS_CLK_SRC_PLL2_2:
476                 BUG_ON(dsi_module != 1);
477                 b = 1;
478                 break;
479         default:
480                 BUG();
481                 return;
482         }
483
484         pos = dsi_module == 0 ? 1 : 10;
485         REG_FLD_MOD(DSS_CONTROL, b, pos, pos);  /* DSIx_CLK_SWITCH */
486
487         dss.dsi_clk_source[dsi_module] = clk_src;
488 }
489
490 static int dss_lcd_clk_mux_dra7(enum omap_channel channel,
491         enum dss_clk_source clk_src)
492 {
493         const u8 ctrl_bits[] = {
494                 [OMAP_DSS_CHANNEL_LCD] = 0,
495                 [OMAP_DSS_CHANNEL_LCD2] = 12,
496                 [OMAP_DSS_CHANNEL_LCD3] = 19,
497         };
498
499         u8 ctrl_bit = ctrl_bits[channel];
500         int r;
501
502         if (clk_src == DSS_CLK_SRC_FCK) {
503                 /* LCDx_CLK_SWITCH */
504                 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
505                 return -EINVAL;
506         }
507
508         r = dss_ctrl_pll_set_control_mux(clk_src, channel);
509         if (r)
510                 return r;
511
512         REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
513
514         return 0;
515 }
516
517 static int dss_lcd_clk_mux_omap5(enum omap_channel channel,
518         enum dss_clk_source clk_src)
519 {
520         const u8 ctrl_bits[] = {
521                 [OMAP_DSS_CHANNEL_LCD] = 0,
522                 [OMAP_DSS_CHANNEL_LCD2] = 12,
523                 [OMAP_DSS_CHANNEL_LCD3] = 19,
524         };
525         const enum dss_clk_source allowed_plls[] = {
526                 [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
527                 [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK,
528                 [OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1,
529         };
530
531         u8 ctrl_bit = ctrl_bits[channel];
532
533         if (clk_src == DSS_CLK_SRC_FCK) {
534                 /* LCDx_CLK_SWITCH */
535                 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
536                 return -EINVAL;
537         }
538
539         if (WARN_ON(allowed_plls[channel] != clk_src))
540                 return -EINVAL;
541
542         REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
543
544         return 0;
545 }
546
547 static int dss_lcd_clk_mux_omap4(enum omap_channel channel,
548         enum dss_clk_source clk_src)
549 {
550         const u8 ctrl_bits[] = {
551                 [OMAP_DSS_CHANNEL_LCD] = 0,
552                 [OMAP_DSS_CHANNEL_LCD2] = 12,
553         };
554         const enum dss_clk_source allowed_plls[] = {
555                 [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1,
556                 [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1,
557         };
558
559         u8 ctrl_bit = ctrl_bits[channel];
560
561         if (clk_src == DSS_CLK_SRC_FCK) {
562                 /* LCDx_CLK_SWITCH */
563                 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit);
564                 return 0;
565         }
566
567         if (WARN_ON(allowed_plls[channel] != clk_src))
568                 return -EINVAL;
569
570         REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit);
571
572         return 0;
573 }
574
575 void dss_select_lcd_clk_source(enum omap_channel channel,
576                 enum dss_clk_source clk_src)
577 {
578         int idx = dss_get_channel_index(channel);
579         int r;
580
581         if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
582                 dss_select_dispc_clk_source(clk_src);
583                 dss.lcd_clk_source[idx] = clk_src;
584                 return;
585         }
586
587         r = dss.feat->select_lcd_source(channel, clk_src);
588         if (r)
589                 return;
590
591         dss.lcd_clk_source[idx] = clk_src;
592 }
593
594 enum dss_clk_source dss_get_dispc_clk_source(void)
595 {
596         return dss.dispc_clk_source;
597 }
598
599 enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
600 {
601         return dss.dsi_clk_source[dsi_module];
602 }
603
604 enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
605 {
606         if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
607                 int idx = dss_get_channel_index(channel);
608                 return dss.lcd_clk_source[idx];
609         } else {
610                 /* LCD_CLK source is the same as DISPC_FCLK source for
611                  * OMAP2 and OMAP3 */
612                 return dss.dispc_clk_source;
613         }
614 }
615
616 bool dss_div_calc(unsigned long pck, unsigned long fck_min,
617                 dss_div_calc_func func, void *data)
618 {
619         int fckd, fckd_start, fckd_stop;
620         unsigned long fck;
621         unsigned long fck_hw_max;
622         unsigned long fckd_hw_max;
623         unsigned long prate;
624         unsigned m;
625
626         fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
627
628         if (dss.parent_clk == NULL) {
629                 unsigned pckd;
630
631                 pckd = fck_hw_max / pck;
632
633                 fck = pck * pckd;
634
635                 fck = clk_round_rate(dss.dss_clk, fck);
636
637                 return func(fck, data);
638         }
639
640         fckd_hw_max = dss.feat->fck_div_max;
641
642         m = dss.feat->dss_fck_multiplier;
643         prate = clk_get_rate(dss.parent_clk);
644
645         fck_min = fck_min ? fck_min : 1;
646
647         fckd_start = min(prate * m / fck_min, fckd_hw_max);
648         fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
649
650         for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
651                 fck = DIV_ROUND_UP(prate, fckd) * m;
652
653                 if (func(fck, data))
654                         return true;
655         }
656
657         return false;
658 }
659
660 int dss_set_fck_rate(unsigned long rate)
661 {
662         int r;
663
664         DSSDBG("set fck to %lu\n", rate);
665
666         r = clk_set_rate(dss.dss_clk, rate);
667         if (r)
668                 return r;
669
670         dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
671
672         WARN_ONCE(dss.dss_clk_rate != rate,
673                         "clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
674                         rate);
675
676         return 0;
677 }
678
679 unsigned long dss_get_dispc_clk_rate(void)
680 {
681         return dss.dss_clk_rate;
682 }
683
684 static int dss_setup_default_clock(void)
685 {
686         unsigned long max_dss_fck, prate;
687         unsigned long fck;
688         unsigned fck_div;
689         int r;
690
691         max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
692
693         if (dss.parent_clk == NULL) {
694                 fck = clk_round_rate(dss.dss_clk, max_dss_fck);
695         } else {
696                 prate = clk_get_rate(dss.parent_clk);
697
698                 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
699                                 max_dss_fck);
700                 fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
701         }
702
703         r = dss_set_fck_rate(fck);
704         if (r)
705                 return r;
706
707         return 0;
708 }
709
710 void dss_set_venc_output(enum omap_dss_venc_type type)
711 {
712         int l = 0;
713
714         if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
715                 l = 0;
716         else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
717                 l = 1;
718         else
719                 BUG();
720
721         /* venc out selection. 0 = comp, 1 = svideo */
722         REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
723 }
724
725 void dss_set_dac_pwrdn_bgz(bool enable)
726 {
727         REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
728 }
729
730 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
731 {
732         enum omap_display_type dp;
733         dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
734
735         /* Complain about invalid selections */
736         WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
737         WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
738
739         /* Select only if we have options */
740         if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
741                 REG_FLD_MOD(DSS_CONTROL, src, 15, 15);  /* VENC_HDMI_SWITCH */
742 }
743
744 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
745 {
746         enum omap_display_type displays;
747
748         displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
749         if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
750                 return DSS_VENC_TV_CLK;
751
752         if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
753                 return DSS_HDMI_M_PCLK;
754
755         return REG_GET(DSS_CONTROL, 15, 15);
756 }
757
758 static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
759 {
760         if (channel != OMAP_DSS_CHANNEL_LCD)
761                 return -EINVAL;
762
763         return 0;
764 }
765
766 static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
767 {
768         int val;
769
770         switch (channel) {
771         case OMAP_DSS_CHANNEL_LCD2:
772                 val = 0;
773                 break;
774         case OMAP_DSS_CHANNEL_DIGIT:
775                 val = 1;
776                 break;
777         default:
778                 return -EINVAL;
779         }
780
781         REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
782
783         return 0;
784 }
785
786 static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
787 {
788         int val;
789
790         switch (channel) {
791         case OMAP_DSS_CHANNEL_LCD:
792                 val = 1;
793                 break;
794         case OMAP_DSS_CHANNEL_LCD2:
795                 val = 2;
796                 break;
797         case OMAP_DSS_CHANNEL_LCD3:
798                 val = 3;
799                 break;
800         case OMAP_DSS_CHANNEL_DIGIT:
801                 val = 0;
802                 break;
803         default:
804                 return -EINVAL;
805         }
806
807         REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
808
809         return 0;
810 }
811
812 static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
813 {
814         switch (port) {
815         case 0:
816                 return dss_dpi_select_source_omap5(port, channel);
817         case 1:
818                 if (channel != OMAP_DSS_CHANNEL_LCD2)
819                         return -EINVAL;
820                 break;
821         case 2:
822                 if (channel != OMAP_DSS_CHANNEL_LCD3)
823                         return -EINVAL;
824                 break;
825         default:
826                 return -EINVAL;
827         }
828
829         return 0;
830 }
831
832 int dss_dpi_select_source(int port, enum omap_channel channel)
833 {
834         return dss.feat->dpi_select_source(port, channel);
835 }
836
837 static int dss_get_clocks(void)
838 {
839         struct clk *clk;
840
841         clk = devm_clk_get(&dss.pdev->dev, "fck");
842         if (IS_ERR(clk)) {
843                 DSSERR("can't get clock fck\n");
844                 return PTR_ERR(clk);
845         }
846
847         dss.dss_clk = clk;
848
849         if (dss.feat->parent_clk_name) {
850                 clk = clk_get(NULL, dss.feat->parent_clk_name);
851                 if (IS_ERR(clk)) {
852                         DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
853                         return PTR_ERR(clk);
854                 }
855         } else {
856                 clk = NULL;
857         }
858
859         dss.parent_clk = clk;
860
861         return 0;
862 }
863
864 static void dss_put_clocks(void)
865 {
866         if (dss.parent_clk)
867                 clk_put(dss.parent_clk);
868 }
869
870 int dss_runtime_get(void)
871 {
872         int r;
873
874         DSSDBG("dss_runtime_get\n");
875
876         r = pm_runtime_get_sync(&dss.pdev->dev);
877         WARN_ON(r < 0);
878         return r < 0 ? r : 0;
879 }
880
881 void dss_runtime_put(void)
882 {
883         int r;
884
885         DSSDBG("dss_runtime_put\n");
886
887         r = pm_runtime_put_sync(&dss.pdev->dev);
888         WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
889 }
890
891 /* DEBUGFS */
892 #if defined(CONFIG_OMAP2_DSS_DEBUGFS)
893 void dss_debug_dump_clocks(struct seq_file *s)
894 {
895         dss_dump_clocks(s);
896         dispc_dump_clocks(s);
897 #ifdef CONFIG_OMAP2_DSS_DSI
898         dsi_dump_clocks(s);
899 #endif
900 }
901 #endif
902
903
904 static const enum omap_display_type omap2plus_ports[] = {
905         OMAP_DISPLAY_TYPE_DPI,
906 };
907
908 static const enum omap_display_type omap34xx_ports[] = {
909         OMAP_DISPLAY_TYPE_DPI,
910         OMAP_DISPLAY_TYPE_SDI,
911 };
912
913 static const enum omap_display_type dra7xx_ports[] = {
914         OMAP_DISPLAY_TYPE_DPI,
915         OMAP_DISPLAY_TYPE_DPI,
916         OMAP_DISPLAY_TYPE_DPI,
917 };
918
919 static const struct dss_features omap24xx_dss_feats = {
920         /*
921          * fck div max is really 16, but the divider range has gaps. The range
922          * from 1 to 6 has no gaps, so let's use that as a max.
923          */
924         .fck_div_max            =       6,
925         .dss_fck_multiplier     =       2,
926         .parent_clk_name        =       "core_ck",
927         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
928         .ports                  =       omap2plus_ports,
929         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
930 };
931
932 static const struct dss_features omap34xx_dss_feats = {
933         .fck_div_max            =       16,
934         .dss_fck_multiplier     =       2,
935         .parent_clk_name        =       "dpll4_ck",
936         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
937         .ports                  =       omap34xx_ports,
938         .num_ports              =       ARRAY_SIZE(omap34xx_ports),
939 };
940
941 static const struct dss_features omap3630_dss_feats = {
942         .fck_div_max            =       32,
943         .dss_fck_multiplier     =       1,
944         .parent_clk_name        =       "dpll4_ck",
945         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
946         .ports                  =       omap2plus_ports,
947         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
948 };
949
950 static const struct dss_features omap44xx_dss_feats = {
951         .fck_div_max            =       32,
952         .dss_fck_multiplier     =       1,
953         .parent_clk_name        =       "dpll_per_x2_ck",
954         .dpi_select_source      =       &dss_dpi_select_source_omap4,
955         .ports                  =       omap2plus_ports,
956         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
957         .select_lcd_source      =       &dss_lcd_clk_mux_omap4,
958 };
959
960 static const struct dss_features omap54xx_dss_feats = {
961         .fck_div_max            =       64,
962         .dss_fck_multiplier     =       1,
963         .parent_clk_name        =       "dpll_per_x2_ck",
964         .dpi_select_source      =       &dss_dpi_select_source_omap5,
965         .ports                  =       omap2plus_ports,
966         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
967         .select_lcd_source      =       &dss_lcd_clk_mux_omap5,
968 };
969
970 static const struct dss_features am43xx_dss_feats = {
971         .fck_div_max            =       0,
972         .dss_fck_multiplier     =       0,
973         .parent_clk_name        =       NULL,
974         .dpi_select_source      =       &dss_dpi_select_source_omap2_omap3,
975         .ports                  =       omap2plus_ports,
976         .num_ports              =       ARRAY_SIZE(omap2plus_ports),
977 };
978
979 static const struct dss_features dra7xx_dss_feats = {
980         .fck_div_max            =       64,
981         .dss_fck_multiplier     =       1,
982         .parent_clk_name        =       "dpll_per_x2_ck",
983         .dpi_select_source      =       &dss_dpi_select_source_dra7xx,
984         .ports                  =       dra7xx_ports,
985         .num_ports              =       ARRAY_SIZE(dra7xx_ports),
986         .select_lcd_source      =       &dss_lcd_clk_mux_dra7,
987 };
988
989 static int dss_init_features(struct platform_device *pdev)
990 {
991         const struct dss_features *src;
992         struct dss_features *dst;
993
994         dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
995         if (!dst) {
996                 dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
997                 return -ENOMEM;
998         }
999
1000         switch (omapdss_get_version()) {
1001         case OMAPDSS_VER_OMAP24xx:
1002                 src = &omap24xx_dss_feats;
1003                 break;
1004
1005         case OMAPDSS_VER_OMAP34xx_ES1:
1006         case OMAPDSS_VER_OMAP34xx_ES3:
1007         case OMAPDSS_VER_AM35xx:
1008                 src = &omap34xx_dss_feats;
1009                 break;
1010
1011         case OMAPDSS_VER_OMAP3630:
1012                 src = &omap3630_dss_feats;
1013                 break;
1014
1015         case OMAPDSS_VER_OMAP4430_ES1:
1016         case OMAPDSS_VER_OMAP4430_ES2:
1017         case OMAPDSS_VER_OMAP4:
1018                 src = &omap44xx_dss_feats;
1019                 break;
1020
1021         case OMAPDSS_VER_OMAP5:
1022                 src = &omap54xx_dss_feats;
1023                 break;
1024
1025         case OMAPDSS_VER_AM43xx:
1026                 src = &am43xx_dss_feats;
1027                 break;
1028
1029         case OMAPDSS_VER_DRA7xx:
1030                 src = &dra7xx_dss_feats;
1031                 break;
1032
1033         default:
1034                 return -ENODEV;
1035         }
1036
1037         memcpy(dst, src, sizeof(*dst));
1038         dss.feat = dst;
1039
1040         return 0;
1041 }
1042
1043 static int dss_init_ports(struct platform_device *pdev)
1044 {
1045         struct device_node *parent = pdev->dev.of_node;
1046         struct device_node *port;
1047         int r;
1048
1049         if (parent == NULL)
1050                 return 0;
1051
1052         port = omapdss_of_get_next_port(parent, NULL);
1053         if (!port)
1054                 return 0;
1055
1056         if (dss.feat->num_ports == 0)
1057                 return 0;
1058
1059         do {
1060                 enum omap_display_type port_type;
1061                 u32 reg;
1062
1063                 r = of_property_read_u32(port, "reg", &reg);
1064                 if (r)
1065                         reg = 0;
1066
1067                 if (reg >= dss.feat->num_ports)
1068                         continue;
1069
1070                 port_type = dss.feat->ports[reg];
1071
1072                 switch (port_type) {
1073                 case OMAP_DISPLAY_TYPE_DPI:
1074                         dpi_init_port(pdev, port);
1075                         break;
1076                 case OMAP_DISPLAY_TYPE_SDI:
1077                         sdi_init_port(pdev, port);
1078                         break;
1079                 default:
1080                         break;
1081                 }
1082         } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
1083
1084         return 0;
1085 }
1086
1087 static void dss_uninit_ports(struct platform_device *pdev)
1088 {
1089         struct device_node *parent = pdev->dev.of_node;
1090         struct device_node *port;
1091
1092         if (parent == NULL)
1093                 return;
1094
1095         port = omapdss_of_get_next_port(parent, NULL);
1096         if (!port)
1097                 return;
1098
1099         if (dss.feat->num_ports == 0)
1100                 return;
1101
1102         do {
1103                 enum omap_display_type port_type;
1104                 u32 reg;
1105                 int r;
1106
1107                 r = of_property_read_u32(port, "reg", &reg);
1108                 if (r)
1109                         reg = 0;
1110
1111                 if (reg >= dss.feat->num_ports)
1112                         continue;
1113
1114                 port_type = dss.feat->ports[reg];
1115
1116                 switch (port_type) {
1117                 case OMAP_DISPLAY_TYPE_DPI:
1118                         dpi_uninit_port(port);
1119                         break;
1120                 case OMAP_DISPLAY_TYPE_SDI:
1121                         sdi_uninit_port(port);
1122                         break;
1123                 default:
1124                         break;
1125                 }
1126         } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
1127 }
1128
1129 static int dss_video_pll_probe(struct platform_device *pdev)
1130 {
1131         struct device_node *np = pdev->dev.of_node;
1132         struct regulator *pll_regulator;
1133         int r;
1134
1135         if (!np)
1136                 return 0;
1137
1138         if (of_property_read_bool(np, "syscon-pll-ctrl")) {
1139                 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1140                         "syscon-pll-ctrl");
1141                 if (IS_ERR(dss.syscon_pll_ctrl)) {
1142                         dev_err(&pdev->dev,
1143                                 "failed to get syscon-pll-ctrl regmap\n");
1144                         return PTR_ERR(dss.syscon_pll_ctrl);
1145                 }
1146
1147                 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1148                                 &dss.syscon_pll_ctrl_offset)) {
1149                         dev_err(&pdev->dev,
1150                                 "failed to get syscon-pll-ctrl offset\n");
1151                         return -EINVAL;
1152                 }
1153         }
1154
1155         pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1156         if (IS_ERR(pll_regulator)) {
1157                 r = PTR_ERR(pll_regulator);
1158
1159                 switch (r) {
1160                 case -ENOENT:
1161                         pll_regulator = NULL;
1162                         break;
1163
1164                 case -EPROBE_DEFER:
1165                         return -EPROBE_DEFER;
1166
1167                 default:
1168                         DSSERR("can't get DPLL VDDA regulator\n");
1169                         return r;
1170                 }
1171         }
1172
1173         if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1174                 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1175                 if (IS_ERR(dss.video1_pll))
1176                         return PTR_ERR(dss.video1_pll);
1177         }
1178
1179         if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1180                 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1181                 if (IS_ERR(dss.video2_pll)) {
1182                         dss_video_pll_uninit(dss.video1_pll);
1183                         return PTR_ERR(dss.video2_pll);
1184                 }
1185         }
1186
1187         return 0;
1188 }
1189
1190 /* DSS HW IP initialisation */
1191 static int dss_bind(struct device *dev)
1192 {
1193         struct platform_device *pdev = to_platform_device(dev);
1194         struct resource *dss_mem;
1195         u32 rev;
1196         int r;
1197
1198         dss.pdev = pdev;
1199
1200         r = dss_init_features(dss.pdev);
1201         if (r)
1202                 return r;
1203
1204         dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
1205         if (!dss_mem) {
1206                 DSSERR("can't get IORESOURCE_MEM DSS\n");
1207                 return -EINVAL;
1208         }
1209
1210         dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
1211                                 resource_size(dss_mem));
1212         if (!dss.base) {
1213                 DSSERR("can't ioremap DSS\n");
1214                 return -ENOMEM;
1215         }
1216
1217         r = dss_get_clocks();
1218         if (r)
1219                 return r;
1220
1221         r = dss_setup_default_clock();
1222         if (r)
1223                 goto err_setup_clocks;
1224
1225         r = dss_video_pll_probe(pdev);
1226         if (r)
1227                 goto err_pll_init;
1228
1229         r = dss_init_ports(pdev);
1230         if (r)
1231                 goto err_init_ports;
1232
1233         pm_runtime_enable(&pdev->dev);
1234
1235         r = dss_runtime_get();
1236         if (r)
1237                 goto err_runtime_get;
1238
1239         dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
1240
1241         /* Select DPLL */
1242         REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
1243
1244         dss_select_dispc_clk_source(DSS_CLK_SRC_FCK);
1245
1246 #ifdef CONFIG_OMAP2_DSS_VENC
1247         REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);      /* venc dac demen */
1248         REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);      /* venc clock 4x enable */
1249         REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);      /* venc clock mode = normal */
1250 #endif
1251         dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK;
1252         dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK;
1253         dss.dispc_clk_source = DSS_CLK_SRC_FCK;
1254         dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK;
1255         dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK;
1256
1257         rev = dss_read_reg(DSS_REVISION);
1258         printk(KERN_INFO "OMAP DSS rev %d.%d\n",
1259                         FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1260
1261         dss_runtime_put();
1262
1263         r = component_bind_all(&pdev->dev, NULL);
1264         if (r)
1265                 goto err_component;
1266
1267         dss_debugfs_create_file("dss", dss_dump_regs);
1268
1269         pm_set_vt_switch(0);
1270
1271         dss_initialized = true;
1272
1273         return 0;
1274
1275 err_component:
1276 err_runtime_get:
1277         pm_runtime_disable(&pdev->dev);
1278         dss_uninit_ports(pdev);
1279 err_init_ports:
1280         if (dss.video1_pll)
1281                 dss_video_pll_uninit(dss.video1_pll);
1282
1283         if (dss.video2_pll)
1284                 dss_video_pll_uninit(dss.video2_pll);
1285 err_pll_init:
1286 err_setup_clocks:
1287         dss_put_clocks();
1288         return r;
1289 }
1290
1291 static void dss_unbind(struct device *dev)
1292 {
1293         struct platform_device *pdev = to_platform_device(dev);
1294
1295         dss_initialized = false;
1296
1297         component_unbind_all(&pdev->dev, NULL);
1298
1299         if (dss.video1_pll)
1300                 dss_video_pll_uninit(dss.video1_pll);
1301
1302         if (dss.video2_pll)
1303                 dss_video_pll_uninit(dss.video2_pll);
1304
1305         dss_uninit_ports(pdev);
1306
1307         pm_runtime_disable(&pdev->dev);
1308
1309         dss_put_clocks();
1310 }
1311
1312 static const struct component_master_ops dss_component_ops = {
1313         .bind = dss_bind,
1314         .unbind = dss_unbind,
1315 };
1316
1317 static int dss_component_compare(struct device *dev, void *data)
1318 {
1319         struct device *child = data;
1320         return dev == child;
1321 }
1322
1323 static int dss_add_child_component(struct device *dev, void *data)
1324 {
1325         struct component_match **match = data;
1326
1327         /*
1328          * HACK
1329          * We don't have a working driver for rfbi, so skip it here always.
1330          * Otherwise dss will never get probed successfully, as it will wait
1331          * for rfbi to get probed.
1332          */
1333         if (strstr(dev_name(dev), "rfbi"))
1334                 return 0;
1335
1336         component_match_add(dev->parent, match, dss_component_compare, dev);
1337
1338         return 0;
1339 }
1340
1341 static int dss_probe(struct platform_device *pdev)
1342 {
1343         struct component_match *match = NULL;
1344         int r;
1345
1346         /* add all the child devices as components */
1347         device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1348
1349         r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1350         if (r)
1351                 return r;
1352
1353         return 0;
1354 }
1355
1356 static int dss_remove(struct platform_device *pdev)
1357 {
1358         component_master_del(&pdev->dev, &dss_component_ops);
1359         return 0;
1360 }
1361
1362 static int dss_runtime_suspend(struct device *dev)
1363 {
1364         dss_save_context();
1365         dss_set_min_bus_tput(dev, 0);
1366
1367         pinctrl_pm_select_sleep_state(dev);
1368
1369         return 0;
1370 }
1371
1372 static int dss_runtime_resume(struct device *dev)
1373 {
1374         int r;
1375
1376         pinctrl_pm_select_default_state(dev);
1377
1378         /*
1379          * Set an arbitrarily high tput request to ensure OPP100.
1380          * What we should really do is to make a request to stay in OPP100,
1381          * without any tput requirements, but that is not currently possible
1382          * via the PM layer.
1383          */
1384
1385         r = dss_set_min_bus_tput(dev, 1000000000);
1386         if (r)
1387                 return r;
1388
1389         dss_restore_context();
1390         return 0;
1391 }
1392
1393 static const struct dev_pm_ops dss_pm_ops = {
1394         .runtime_suspend = dss_runtime_suspend,
1395         .runtime_resume = dss_runtime_resume,
1396 };
1397
1398 static const struct of_device_id dss_of_match[] = {
1399         { .compatible = "ti,omap2-dss", },
1400         { .compatible = "ti,omap3-dss", },
1401         { .compatible = "ti,omap4-dss", },
1402         { .compatible = "ti,omap5-dss", },
1403         { .compatible = "ti,dra7-dss", },
1404         {},
1405 };
1406
1407 MODULE_DEVICE_TABLE(of, dss_of_match);
1408
1409 static struct platform_driver omap_dsshw_driver = {
1410         .probe          = dss_probe,
1411         .remove         = dss_remove,
1412         .driver         = {
1413                 .name   = "omapdss_dss",
1414                 .pm     = &dss_pm_ops,
1415                 .of_match_table = dss_of_match,
1416                 .suppress_bind_attrs = true,
1417         },
1418 };
1419
1420 int __init dss_init_platform_driver(void)
1421 {
1422         return platform_driver_register(&omap_dsshw_driver);
1423 }
1424
1425 void dss_uninit_platform_driver(void)
1426 {
1427         platform_driver_unregister(&omap_dsshw_driver);
1428 }
This page took 0.116667 seconds and 4 git commands to generate.