0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define DSS_SUBSYS_NAME "DSS"
0013
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/io.h>
0017 #include <linux/export.h>
0018 #include <linux/err.h>
0019 #include <linux/delay.h>
0020 #include <linux/seq_file.h>
0021 #include <linux/clk.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/pm_runtime.h>
0024 #include <linux/gfp.h>
0025 #include <linux/sizes.h>
0026 #include <linux/mfd/syscon.h>
0027 #include <linux/regmap.h>
0028 #include <linux/of.h>
0029 #include <linux/regulator/consumer.h>
0030 #include <linux/suspend.h>
0031 #include <linux/component.h>
0032 #include <linux/pinctrl/consumer.h>
0033
0034 #include <video/omapfb_dss.h>
0035
0036 #include "dss.h"
0037 #include "dss_features.h"
0038
0039 #define DSS_SZ_REGS SZ_512
0040
0041 struct dss_reg {
0042 u16 idx;
0043 };
0044
0045 #define DSS_REG(idx) ((const struct dss_reg) { idx })
0046
0047 #define DSS_REVISION DSS_REG(0x0000)
0048 #define DSS_SYSCONFIG DSS_REG(0x0010)
0049 #define DSS_SYSSTATUS DSS_REG(0x0014)
0050 #define DSS_CONTROL DSS_REG(0x0040)
0051 #define DSS_SDI_CONTROL DSS_REG(0x0044)
0052 #define DSS_PLL_CONTROL DSS_REG(0x0048)
0053 #define DSS_SDI_STATUS DSS_REG(0x005C)
0054
0055 #define REG_GET(idx, start, end) \
0056 FLD_GET(dss_read_reg(idx), start, end)
0057
0058 #define REG_FLD_MOD(idx, val, start, end) \
0059 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
0060
0061 struct dss_features {
0062 u8 fck_div_max;
0063 u8 dss_fck_multiplier;
0064 const char *parent_clk_name;
0065 const enum omap_display_type *ports;
0066 int num_ports;
0067 int (*dpi_select_source)(int port, enum omap_channel channel);
0068 };
0069
0070 static struct {
0071 struct platform_device *pdev;
0072 void __iomem *base;
0073 struct regmap *syscon_pll_ctrl;
0074 u32 syscon_pll_ctrl_offset;
0075
0076 struct clk *parent_clk;
0077 struct clk *dss_clk;
0078 unsigned long dss_clk_rate;
0079
0080 unsigned long cache_req_pck;
0081 unsigned long cache_prate;
0082 struct dispc_clock_info cache_dispc_cinfo;
0083
0084 enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
0085 enum omap_dss_clk_source dispc_clk_source;
0086 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
0087
0088 bool ctx_valid;
0089 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
0090
0091 const struct dss_features *feat;
0092
0093 struct dss_pll *video1_pll;
0094 struct dss_pll *video2_pll;
0095 } dss;
0096
0097 static const char * const dss_generic_clk_source_names[] = {
0098 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
0099 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
0100 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
0101 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC",
0102 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI",
0103 };
0104
0105 static bool dss_initialized;
0106
0107 bool omapdss_is_initialized(void)
0108 {
0109 return dss_initialized;
0110 }
0111 EXPORT_SYMBOL(omapdss_is_initialized);
0112
0113 static inline void dss_write_reg(const struct dss_reg idx, u32 val)
0114 {
0115 __raw_writel(val, dss.base + idx.idx);
0116 }
0117
0118 static inline u32 dss_read_reg(const struct dss_reg idx)
0119 {
0120 return __raw_readl(dss.base + idx.idx);
0121 }
0122
0123 #define SR(reg) \
0124 dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
0125 #define RR(reg) \
0126 dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
0127
0128 static void dss_save_context(void)
0129 {
0130 DSSDBG("dss_save_context\n");
0131
0132 SR(CONTROL);
0133
0134 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
0135 OMAP_DISPLAY_TYPE_SDI) {
0136 SR(SDI_CONTROL);
0137 SR(PLL_CONTROL);
0138 }
0139
0140 dss.ctx_valid = true;
0141
0142 DSSDBG("context saved\n");
0143 }
0144
0145 static void dss_restore_context(void)
0146 {
0147 DSSDBG("dss_restore_context\n");
0148
0149 if (!dss.ctx_valid)
0150 return;
0151
0152 RR(CONTROL);
0153
0154 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
0155 OMAP_DISPLAY_TYPE_SDI) {
0156 RR(SDI_CONTROL);
0157 RR(PLL_CONTROL);
0158 }
0159
0160 DSSDBG("context restored\n");
0161 }
0162
0163 #undef SR
0164 #undef RR
0165
0166 void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable)
0167 {
0168 unsigned shift;
0169 unsigned val;
0170
0171 if (!dss.syscon_pll_ctrl)
0172 return;
0173
0174 val = !enable;
0175
0176 switch (pll_id) {
0177 case DSS_PLL_VIDEO1:
0178 shift = 0;
0179 break;
0180 case DSS_PLL_VIDEO2:
0181 shift = 1;
0182 break;
0183 case DSS_PLL_HDMI:
0184 shift = 2;
0185 break;
0186 default:
0187 DSSERR("illegal DSS PLL ID %d\n", pll_id);
0188 return;
0189 }
0190
0191 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
0192 1 << shift, val << shift);
0193 }
0194
0195 void dss_ctrl_pll_set_control_mux(enum dss_pll_id pll_id,
0196 enum omap_channel channel)
0197 {
0198 unsigned shift, val;
0199
0200 if (!dss.syscon_pll_ctrl)
0201 return;
0202
0203 switch (channel) {
0204 case OMAP_DSS_CHANNEL_LCD:
0205 shift = 3;
0206
0207 switch (pll_id) {
0208 case DSS_PLL_VIDEO1:
0209 val = 0; break;
0210 case DSS_PLL_HDMI:
0211 val = 1; break;
0212 default:
0213 DSSERR("error in PLL mux config for LCD\n");
0214 return;
0215 }
0216
0217 break;
0218 case OMAP_DSS_CHANNEL_LCD2:
0219 shift = 5;
0220
0221 switch (pll_id) {
0222 case DSS_PLL_VIDEO1:
0223 val = 0; break;
0224 case DSS_PLL_VIDEO2:
0225 val = 1; break;
0226 case DSS_PLL_HDMI:
0227 val = 2; break;
0228 default:
0229 DSSERR("error in PLL mux config for LCD2\n");
0230 return;
0231 }
0232
0233 break;
0234 case OMAP_DSS_CHANNEL_LCD3:
0235 shift = 7;
0236
0237 switch (pll_id) {
0238 case DSS_PLL_VIDEO1:
0239 val = 1; break;
0240 case DSS_PLL_VIDEO2:
0241 val = 0; break;
0242 case DSS_PLL_HDMI:
0243 val = 2; break;
0244 default:
0245 DSSERR("error in PLL mux config for LCD3\n");
0246 return;
0247 }
0248
0249 break;
0250 default:
0251 DSSERR("error in PLL mux config\n");
0252 return;
0253 }
0254
0255 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset,
0256 0x3 << shift, val << shift);
0257 }
0258
0259 void dss_sdi_init(int datapairs)
0260 {
0261 u32 l;
0262
0263 BUG_ON(datapairs > 3 || datapairs < 1);
0264
0265 l = dss_read_reg(DSS_SDI_CONTROL);
0266 l = FLD_MOD(l, 0xf, 19, 15);
0267 l = FLD_MOD(l, datapairs-1, 3, 2);
0268 l = FLD_MOD(l, 2, 1, 0);
0269 dss_write_reg(DSS_SDI_CONTROL, l);
0270
0271 l = dss_read_reg(DSS_PLL_CONTROL);
0272 l = FLD_MOD(l, 0x7, 25, 22);
0273 l = FLD_MOD(l, 0xb, 16, 11);
0274 l = FLD_MOD(l, 0xb4, 10, 1);
0275 dss_write_reg(DSS_PLL_CONTROL, l);
0276 }
0277
0278 int dss_sdi_enable(void)
0279 {
0280 unsigned long timeout;
0281
0282 dispc_pck_free_enable(1);
0283
0284
0285 REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18);
0286 udelay(1);
0287
0288
0289 REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28);
0290
0291
0292 timeout = jiffies + msecs_to_jiffies(500);
0293 while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) {
0294 if (time_after_eq(jiffies, timeout)) {
0295 DSSERR("PLL lock request timed out\n");
0296 goto err1;
0297 }
0298 }
0299
0300
0301 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
0302
0303
0304 timeout = jiffies + msecs_to_jiffies(500);
0305 while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) {
0306 if (time_after_eq(jiffies, timeout)) {
0307 DSSERR("PLL lock timed out\n");
0308 goto err1;
0309 }
0310 }
0311
0312 dispc_lcd_enable_signal(1);
0313
0314
0315 timeout = jiffies + msecs_to_jiffies(500);
0316 while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) {
0317 if (time_after_eq(jiffies, timeout)) {
0318 DSSERR("SDI reset timed out\n");
0319 goto err2;
0320 }
0321 }
0322
0323 return 0;
0324
0325 err2:
0326 dispc_lcd_enable_signal(0);
0327 err1:
0328
0329 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18);
0330
0331 dispc_pck_free_enable(0);
0332
0333 return -ETIMEDOUT;
0334 }
0335
0336 void dss_sdi_disable(void)
0337 {
0338 dispc_lcd_enable_signal(0);
0339
0340 dispc_pck_free_enable(0);
0341
0342
0343 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18);
0344 }
0345
0346 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
0347 {
0348 return dss_generic_clk_source_names[clk_src];
0349 }
0350
0351 void dss_dump_clocks(struct seq_file *s)
0352 {
0353 const char *fclk_name, *fclk_real_name;
0354 unsigned long fclk_rate;
0355
0356 if (dss_runtime_get())
0357 return;
0358
0359 seq_printf(s, "- DSS -\n");
0360
0361 fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
0362 fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
0363 fclk_rate = clk_get_rate(dss.dss_clk);
0364
0365 seq_printf(s, "%s (%s) = %lu\n",
0366 fclk_name, fclk_real_name,
0367 fclk_rate);
0368
0369 dss_runtime_put();
0370 }
0371
0372 static void dss_dump_regs(struct seq_file *s)
0373 {
0374 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
0375
0376 if (dss_runtime_get())
0377 return;
0378
0379 DUMPREG(DSS_REVISION);
0380 DUMPREG(DSS_SYSCONFIG);
0381 DUMPREG(DSS_SYSSTATUS);
0382 DUMPREG(DSS_CONTROL);
0383
0384 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
0385 OMAP_DISPLAY_TYPE_SDI) {
0386 DUMPREG(DSS_SDI_CONTROL);
0387 DUMPREG(DSS_PLL_CONTROL);
0388 DUMPREG(DSS_SDI_STATUS);
0389 }
0390
0391 dss_runtime_put();
0392 #undef DUMPREG
0393 }
0394
0395 static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
0396 {
0397 int b;
0398 u8 start, end;
0399
0400 switch (clk_src) {
0401 case OMAP_DSS_CLK_SRC_FCK:
0402 b = 0;
0403 break;
0404 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
0405 b = 1;
0406 break;
0407 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
0408 b = 2;
0409 break;
0410 default:
0411 BUG();
0412 return;
0413 }
0414
0415 dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
0416
0417 REG_FLD_MOD(DSS_CONTROL, b, start, end);
0418
0419 dss.dispc_clk_source = clk_src;
0420 }
0421
0422 void dss_select_dsi_clk_source(int dsi_module,
0423 enum omap_dss_clk_source clk_src)
0424 {
0425 int b, pos;
0426
0427 switch (clk_src) {
0428 case OMAP_DSS_CLK_SRC_FCK:
0429 b = 0;
0430 break;
0431 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
0432 BUG_ON(dsi_module != 0);
0433 b = 1;
0434 break;
0435 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
0436 BUG_ON(dsi_module != 1);
0437 b = 1;
0438 break;
0439 default:
0440 BUG();
0441 return;
0442 }
0443
0444 pos = dsi_module == 0 ? 1 : 10;
0445 REG_FLD_MOD(DSS_CONTROL, b, pos, pos);
0446
0447 dss.dsi_clk_source[dsi_module] = clk_src;
0448 }
0449
0450 void dss_select_lcd_clk_source(enum omap_channel channel,
0451 enum omap_dss_clk_source clk_src)
0452 {
0453 int b, ix, pos;
0454
0455 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
0456 dss_select_dispc_clk_source(clk_src);
0457 return;
0458 }
0459
0460 switch (clk_src) {
0461 case OMAP_DSS_CLK_SRC_FCK:
0462 b = 0;
0463 break;
0464 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
0465 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
0466 b = 1;
0467 break;
0468 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
0469 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
0470 channel != OMAP_DSS_CHANNEL_LCD3);
0471 b = 1;
0472 break;
0473 default:
0474 BUG();
0475 return;
0476 }
0477
0478 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
0479 (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
0480 REG_FLD_MOD(DSS_CONTROL, b, pos, pos);
0481
0482 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
0483 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
0484 dss.lcd_clk_source[ix] = clk_src;
0485 }
0486
0487 enum omap_dss_clk_source dss_get_dispc_clk_source(void)
0488 {
0489 return dss.dispc_clk_source;
0490 }
0491
0492 enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
0493 {
0494 return dss.dsi_clk_source[dsi_module];
0495 }
0496
0497 enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
0498 {
0499 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
0500 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
0501 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
0502 return dss.lcd_clk_source[ix];
0503 } else {
0504
0505
0506 return dss.dispc_clk_source;
0507 }
0508 }
0509
0510 bool dss_div_calc(unsigned long pck, unsigned long fck_min,
0511 dss_div_calc_func func, void *data)
0512 {
0513 int fckd, fckd_start, fckd_stop;
0514 unsigned long fck;
0515 unsigned long fck_hw_max;
0516 unsigned long fckd_hw_max;
0517 unsigned long prate;
0518 unsigned m;
0519
0520 fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
0521
0522 if (dss.parent_clk == NULL) {
0523 unsigned pckd;
0524
0525 pckd = fck_hw_max / pck;
0526
0527 fck = pck * pckd;
0528
0529 fck = clk_round_rate(dss.dss_clk, fck);
0530
0531 return func(fck, data);
0532 }
0533
0534 fckd_hw_max = dss.feat->fck_div_max;
0535
0536 m = dss.feat->dss_fck_multiplier;
0537 prate = clk_get_rate(dss.parent_clk);
0538
0539 fck_min = fck_min ? fck_min : 1;
0540
0541 fckd_start = min(prate * m / fck_min, fckd_hw_max);
0542 fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
0543
0544 for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
0545 fck = DIV_ROUND_UP(prate, fckd) * m;
0546
0547 if (func(fck, data))
0548 return true;
0549 }
0550
0551 return false;
0552 }
0553
0554 int dss_set_fck_rate(unsigned long rate)
0555 {
0556 int r;
0557
0558 DSSDBG("set fck to %lu\n", rate);
0559
0560 r = clk_set_rate(dss.dss_clk, rate);
0561 if (r)
0562 return r;
0563
0564 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
0565
0566 WARN_ONCE(dss.dss_clk_rate != rate,
0567 "clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
0568 rate);
0569
0570 return 0;
0571 }
0572
0573 unsigned long dss_get_dispc_clk_rate(void)
0574 {
0575 return dss.dss_clk_rate;
0576 }
0577
0578 static int dss_setup_default_clock(void)
0579 {
0580 unsigned long max_dss_fck, prate;
0581 unsigned long fck;
0582 unsigned fck_div;
0583 int r;
0584
0585 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
0586
0587 if (dss.parent_clk == NULL) {
0588 fck = clk_round_rate(dss.dss_clk, max_dss_fck);
0589 } else {
0590 prate = clk_get_rate(dss.parent_clk);
0591
0592 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
0593 max_dss_fck);
0594 fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
0595 }
0596
0597 r = dss_set_fck_rate(fck);
0598 if (r)
0599 return r;
0600
0601 return 0;
0602 }
0603
0604 void dss_set_venc_output(enum omap_dss_venc_type type)
0605 {
0606 int l = 0;
0607
0608 if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
0609 l = 0;
0610 else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
0611 l = 1;
0612 else
0613 BUG();
0614
0615
0616 REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
0617 }
0618
0619 void dss_set_dac_pwrdn_bgz(bool enable)
0620 {
0621 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);
0622 }
0623
0624 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
0625 {
0626 enum omap_display_type dp;
0627 dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
0628
0629
0630 WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
0631 WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
0632
0633
0634 if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
0635 REG_FLD_MOD(DSS_CONTROL, src, 15, 15);
0636 }
0637
0638 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
0639 {
0640 enum omap_display_type displays;
0641
0642 displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
0643 if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
0644 return DSS_VENC_TV_CLK;
0645
0646 if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
0647 return DSS_HDMI_M_PCLK;
0648
0649 return REG_GET(DSS_CONTROL, 15, 15);
0650 }
0651
0652 static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
0653 {
0654 if (channel != OMAP_DSS_CHANNEL_LCD)
0655 return -EINVAL;
0656
0657 return 0;
0658 }
0659
0660 static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
0661 {
0662 int val;
0663
0664 switch (channel) {
0665 case OMAP_DSS_CHANNEL_LCD2:
0666 val = 0;
0667 break;
0668 case OMAP_DSS_CHANNEL_DIGIT:
0669 val = 1;
0670 break;
0671 default:
0672 return -EINVAL;
0673 }
0674
0675 REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
0676
0677 return 0;
0678 }
0679
0680 static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
0681 {
0682 int val;
0683
0684 switch (channel) {
0685 case OMAP_DSS_CHANNEL_LCD:
0686 val = 1;
0687 break;
0688 case OMAP_DSS_CHANNEL_LCD2:
0689 val = 2;
0690 break;
0691 case OMAP_DSS_CHANNEL_LCD3:
0692 val = 3;
0693 break;
0694 case OMAP_DSS_CHANNEL_DIGIT:
0695 val = 0;
0696 break;
0697 default:
0698 return -EINVAL;
0699 }
0700
0701 REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
0702
0703 return 0;
0704 }
0705
0706 static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
0707 {
0708 switch (port) {
0709 case 0:
0710 return dss_dpi_select_source_omap5(port, channel);
0711 case 1:
0712 if (channel != OMAP_DSS_CHANNEL_LCD2)
0713 return -EINVAL;
0714 break;
0715 case 2:
0716 if (channel != OMAP_DSS_CHANNEL_LCD3)
0717 return -EINVAL;
0718 break;
0719 default:
0720 return -EINVAL;
0721 }
0722
0723 return 0;
0724 }
0725
0726 int dss_dpi_select_source(int port, enum omap_channel channel)
0727 {
0728 return dss.feat->dpi_select_source(port, channel);
0729 }
0730
0731 static int dss_get_clocks(void)
0732 {
0733 struct clk *clk;
0734
0735 clk = devm_clk_get(&dss.pdev->dev, "fck");
0736 if (IS_ERR(clk)) {
0737 DSSERR("can't get clock fck\n");
0738 return PTR_ERR(clk);
0739 }
0740
0741 dss.dss_clk = clk;
0742
0743 if (dss.feat->parent_clk_name) {
0744 clk = clk_get(NULL, dss.feat->parent_clk_name);
0745 if (IS_ERR(clk)) {
0746 DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
0747 return PTR_ERR(clk);
0748 }
0749 } else {
0750 clk = NULL;
0751 }
0752
0753 dss.parent_clk = clk;
0754
0755 return 0;
0756 }
0757
0758 static void dss_put_clocks(void)
0759 {
0760 if (dss.parent_clk)
0761 clk_put(dss.parent_clk);
0762 }
0763
0764 int dss_runtime_get(void)
0765 {
0766 int r;
0767
0768 DSSDBG("dss_runtime_get\n");
0769
0770 r = pm_runtime_get_sync(&dss.pdev->dev);
0771 if (WARN_ON(r < 0)) {
0772 pm_runtime_put_sync(&dss.pdev->dev);
0773 return r;
0774 }
0775 return 0;
0776 }
0777
0778 void dss_runtime_put(void)
0779 {
0780 int r;
0781
0782 DSSDBG("dss_runtime_put\n");
0783
0784 r = pm_runtime_put_sync(&dss.pdev->dev);
0785 WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY);
0786 }
0787
0788
0789 #if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS)
0790 void dss_debug_dump_clocks(struct seq_file *s)
0791 {
0792 dss_dump_clocks(s);
0793 dispc_dump_clocks(s);
0794 #ifdef CONFIG_FB_OMAP2_DSS_DSI
0795 dsi_dump_clocks(s);
0796 #endif
0797 }
0798 #endif
0799
0800
0801 static const enum omap_display_type omap2plus_ports[] = {
0802 OMAP_DISPLAY_TYPE_DPI,
0803 };
0804
0805 static const enum omap_display_type omap34xx_ports[] = {
0806 OMAP_DISPLAY_TYPE_DPI,
0807 OMAP_DISPLAY_TYPE_SDI,
0808 };
0809
0810 static const enum omap_display_type dra7xx_ports[] = {
0811 OMAP_DISPLAY_TYPE_DPI,
0812 OMAP_DISPLAY_TYPE_DPI,
0813 OMAP_DISPLAY_TYPE_DPI,
0814 };
0815
0816 static const struct dss_features omap24xx_dss_feats = {
0817
0818
0819
0820
0821 .fck_div_max = 6,
0822 .dss_fck_multiplier = 2,
0823 .parent_clk_name = "core_ck",
0824 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
0825 .ports = omap2plus_ports,
0826 .num_ports = ARRAY_SIZE(omap2plus_ports),
0827 };
0828
0829 static const struct dss_features omap34xx_dss_feats = {
0830 .fck_div_max = 16,
0831 .dss_fck_multiplier = 2,
0832 .parent_clk_name = "dpll4_ck",
0833 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
0834 .ports = omap34xx_ports,
0835 .num_ports = ARRAY_SIZE(omap34xx_ports),
0836 };
0837
0838 static const struct dss_features omap3630_dss_feats = {
0839 .fck_div_max = 31,
0840 .dss_fck_multiplier = 1,
0841 .parent_clk_name = "dpll4_ck",
0842 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
0843 .ports = omap2plus_ports,
0844 .num_ports = ARRAY_SIZE(omap2plus_ports),
0845 };
0846
0847 static const struct dss_features omap44xx_dss_feats = {
0848 .fck_div_max = 32,
0849 .dss_fck_multiplier = 1,
0850 .parent_clk_name = "dpll_per_x2_ck",
0851 .dpi_select_source = &dss_dpi_select_source_omap4,
0852 .ports = omap2plus_ports,
0853 .num_ports = ARRAY_SIZE(omap2plus_ports),
0854 };
0855
0856 static const struct dss_features omap54xx_dss_feats = {
0857 .fck_div_max = 64,
0858 .dss_fck_multiplier = 1,
0859 .parent_clk_name = "dpll_per_x2_ck",
0860 .dpi_select_source = &dss_dpi_select_source_omap5,
0861 .ports = omap2plus_ports,
0862 .num_ports = ARRAY_SIZE(omap2plus_ports),
0863 };
0864
0865 static const struct dss_features am43xx_dss_feats = {
0866 .fck_div_max = 0,
0867 .dss_fck_multiplier = 0,
0868 .parent_clk_name = NULL,
0869 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
0870 .ports = omap2plus_ports,
0871 .num_ports = ARRAY_SIZE(omap2plus_ports),
0872 };
0873
0874 static const struct dss_features dra7xx_dss_feats = {
0875 .fck_div_max = 64,
0876 .dss_fck_multiplier = 1,
0877 .parent_clk_name = "dpll_per_x2_ck",
0878 .dpi_select_source = &dss_dpi_select_source_dra7xx,
0879 .ports = dra7xx_ports,
0880 .num_ports = ARRAY_SIZE(dra7xx_ports),
0881 };
0882
0883 static const struct dss_features *dss_get_features(void)
0884 {
0885 switch (omapdss_get_version()) {
0886 case OMAPDSS_VER_OMAP24xx:
0887 return &omap24xx_dss_feats;
0888
0889 case OMAPDSS_VER_OMAP34xx_ES1:
0890 case OMAPDSS_VER_OMAP34xx_ES3:
0891 case OMAPDSS_VER_AM35xx:
0892 return &omap34xx_dss_feats;
0893
0894 case OMAPDSS_VER_OMAP3630:
0895 return &omap3630_dss_feats;
0896
0897 case OMAPDSS_VER_OMAP4430_ES1:
0898 case OMAPDSS_VER_OMAP4430_ES2:
0899 case OMAPDSS_VER_OMAP4:
0900 return &omap44xx_dss_feats;
0901
0902 case OMAPDSS_VER_OMAP5:
0903 return &omap54xx_dss_feats;
0904
0905 case OMAPDSS_VER_AM43xx:
0906 return &am43xx_dss_feats;
0907
0908 case OMAPDSS_VER_DRA7xx:
0909 return &dra7xx_dss_feats;
0910
0911 default:
0912 return NULL;
0913 }
0914 }
0915
0916 static void dss_uninit_ports(struct platform_device *pdev);
0917
0918 static int dss_init_ports(struct platform_device *pdev)
0919 {
0920 struct device_node *parent = pdev->dev.of_node;
0921 struct device_node *port;
0922 int r, ret = 0;
0923
0924 if (parent == NULL)
0925 return 0;
0926
0927 port = omapdss_of_get_next_port(parent, NULL);
0928 if (!port)
0929 return 0;
0930
0931 if (dss.feat->num_ports == 0)
0932 return 0;
0933
0934 do {
0935 enum omap_display_type port_type;
0936 u32 reg;
0937
0938 r = of_property_read_u32(port, "reg", ®);
0939 if (r)
0940 reg = 0;
0941
0942 if (reg >= dss.feat->num_ports)
0943 continue;
0944
0945 port_type = dss.feat->ports[reg];
0946
0947 switch (port_type) {
0948 case OMAP_DISPLAY_TYPE_DPI:
0949 ret = dpi_init_port(pdev, port);
0950 break;
0951 case OMAP_DISPLAY_TYPE_SDI:
0952 ret = sdi_init_port(pdev, port);
0953 break;
0954 default:
0955 break;
0956 }
0957 } while (!ret &&
0958 (port = omapdss_of_get_next_port(parent, port)) != NULL);
0959
0960 if (ret)
0961 dss_uninit_ports(pdev);
0962
0963 return ret;
0964 }
0965
0966 static void dss_uninit_ports(struct platform_device *pdev)
0967 {
0968 struct device_node *parent = pdev->dev.of_node;
0969 struct device_node *port;
0970
0971 if (parent == NULL)
0972 return;
0973
0974 port = omapdss_of_get_next_port(parent, NULL);
0975 if (!port)
0976 return;
0977
0978 if (dss.feat->num_ports == 0)
0979 return;
0980
0981 do {
0982 enum omap_display_type port_type;
0983 u32 reg;
0984 int r;
0985
0986 r = of_property_read_u32(port, "reg", ®);
0987 if (r)
0988 reg = 0;
0989
0990 if (reg >= dss.feat->num_ports)
0991 continue;
0992
0993 port_type = dss.feat->ports[reg];
0994
0995 switch (port_type) {
0996 case OMAP_DISPLAY_TYPE_DPI:
0997 dpi_uninit_port(port);
0998 break;
0999 case OMAP_DISPLAY_TYPE_SDI:
1000 sdi_uninit_port(port);
1001 break;
1002 default:
1003 break;
1004 }
1005 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
1006 }
1007
1008 static int dss_video_pll_probe(struct platform_device *pdev)
1009 {
1010 struct device_node *np = pdev->dev.of_node;
1011 struct regulator *pll_regulator;
1012 int r;
1013
1014 if (!np)
1015 return 0;
1016
1017 if (of_property_read_bool(np, "syscon-pll-ctrl")) {
1018 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1019 "syscon-pll-ctrl");
1020 if (IS_ERR(dss.syscon_pll_ctrl)) {
1021 dev_err(&pdev->dev,
1022 "failed to get syscon-pll-ctrl regmap\n");
1023 return PTR_ERR(dss.syscon_pll_ctrl);
1024 }
1025
1026 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1027 &dss.syscon_pll_ctrl_offset)) {
1028 dev_err(&pdev->dev,
1029 "failed to get syscon-pll-ctrl offset\n");
1030 return -EINVAL;
1031 }
1032 }
1033
1034 pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1035 if (IS_ERR(pll_regulator)) {
1036 r = PTR_ERR(pll_regulator);
1037
1038 switch (r) {
1039 case -ENOENT:
1040 pll_regulator = NULL;
1041 break;
1042
1043 case -EPROBE_DEFER:
1044 return -EPROBE_DEFER;
1045
1046 default:
1047 DSSERR("can't get DPLL VDDA regulator\n");
1048 return r;
1049 }
1050 }
1051
1052 if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1053 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1054 if (IS_ERR(dss.video1_pll))
1055 return PTR_ERR(dss.video1_pll);
1056 }
1057
1058 if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1059 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1060 if (IS_ERR(dss.video2_pll)) {
1061 dss_video_pll_uninit(dss.video1_pll);
1062 return PTR_ERR(dss.video2_pll);
1063 }
1064 }
1065
1066 return 0;
1067 }
1068
1069
1070 static int dss_bind(struct device *dev)
1071 {
1072 struct platform_device *pdev = to_platform_device(dev);
1073 struct resource *dss_mem;
1074 u32 rev;
1075 int r;
1076
1077 dss.pdev = pdev;
1078
1079 dss.feat = dss_get_features();
1080 if (!dss.feat)
1081 return -ENODEV;
1082
1083 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
1084 if (!dss_mem) {
1085 DSSERR("can't get IORESOURCE_MEM DSS\n");
1086 return -EINVAL;
1087 }
1088
1089 dss.base = devm_ioremap(&pdev->dev, dss_mem->start,
1090 resource_size(dss_mem));
1091 if (!dss.base) {
1092 DSSERR("can't ioremap DSS\n");
1093 return -ENOMEM;
1094 }
1095
1096 r = dss_get_clocks();
1097 if (r)
1098 return r;
1099
1100 r = dss_setup_default_clock();
1101 if (r)
1102 goto err_setup_clocks;
1103
1104 r = dss_video_pll_probe(pdev);
1105 if (r)
1106 goto err_pll_init;
1107
1108 r = dss_init_ports(pdev);
1109 if (r)
1110 goto err_init_ports;
1111
1112 pm_runtime_enable(&pdev->dev);
1113
1114 r = dss_runtime_get();
1115 if (r)
1116 goto err_runtime_get;
1117
1118 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
1119
1120
1121 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
1122
1123 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
1124
1125 #ifdef CONFIG_FB_OMAP2_DSS_VENC
1126 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4);
1127 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3);
1128 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2);
1129 #endif
1130 dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1131 dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1132 dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
1133 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1134 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1135
1136 rev = dss_read_reg(DSS_REVISION);
1137 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
1138 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1139
1140 dss_runtime_put();
1141
1142 r = component_bind_all(&pdev->dev, NULL);
1143 if (r)
1144 goto err_component;
1145
1146 dss_debugfs_create_file("dss", dss_dump_regs);
1147
1148 pm_set_vt_switch(0);
1149
1150 dss_initialized = true;
1151
1152 return 0;
1153
1154 err_component:
1155 err_runtime_get:
1156 pm_runtime_disable(&pdev->dev);
1157 dss_uninit_ports(pdev);
1158 err_init_ports:
1159 if (dss.video1_pll)
1160 dss_video_pll_uninit(dss.video1_pll);
1161
1162 if (dss.video2_pll)
1163 dss_video_pll_uninit(dss.video2_pll);
1164 err_pll_init:
1165 err_setup_clocks:
1166 dss_put_clocks();
1167 return r;
1168 }
1169
1170 static void dss_unbind(struct device *dev)
1171 {
1172 struct platform_device *pdev = to_platform_device(dev);
1173
1174 dss_initialized = false;
1175
1176 component_unbind_all(&pdev->dev, NULL);
1177
1178 if (dss.video1_pll)
1179 dss_video_pll_uninit(dss.video1_pll);
1180
1181 if (dss.video2_pll)
1182 dss_video_pll_uninit(dss.video2_pll);
1183
1184 dss_uninit_ports(pdev);
1185
1186 pm_runtime_disable(&pdev->dev);
1187
1188 dss_put_clocks();
1189 }
1190
1191 static const struct component_master_ops dss_component_ops = {
1192 .bind = dss_bind,
1193 .unbind = dss_unbind,
1194 };
1195
1196 static int dss_add_child_component(struct device *dev, void *data)
1197 {
1198 struct component_match **match = data;
1199
1200
1201
1202
1203
1204
1205
1206 if (strstr(dev_name(dev), "rfbi"))
1207 return 0;
1208
1209 component_match_add(dev->parent, match, component_compare_dev, dev);
1210
1211 return 0;
1212 }
1213
1214 static int dss_probe(struct platform_device *pdev)
1215 {
1216 struct component_match *match = NULL;
1217 int r;
1218
1219
1220 device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1221
1222 r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1223 if (r)
1224 return r;
1225
1226 return 0;
1227 }
1228
1229 static int dss_remove(struct platform_device *pdev)
1230 {
1231 component_master_del(&pdev->dev, &dss_component_ops);
1232 return 0;
1233 }
1234
1235 static int dss_runtime_suspend(struct device *dev)
1236 {
1237 dss_save_context();
1238 dss_set_min_bus_tput(dev, 0);
1239
1240 pinctrl_pm_select_sleep_state(dev);
1241
1242 return 0;
1243 }
1244
1245 static int dss_runtime_resume(struct device *dev)
1246 {
1247 int r;
1248
1249 pinctrl_pm_select_default_state(dev);
1250
1251
1252
1253
1254
1255
1256
1257
1258 r = dss_set_min_bus_tput(dev, 1000000000);
1259 if (r)
1260 return r;
1261
1262 dss_restore_context();
1263 return 0;
1264 }
1265
1266 static const struct dev_pm_ops dss_pm_ops = {
1267 .runtime_suspend = dss_runtime_suspend,
1268 .runtime_resume = dss_runtime_resume,
1269 };
1270
1271 static const struct of_device_id dss_of_match[] = {
1272 { .compatible = "ti,omap2-dss", },
1273 { .compatible = "ti,omap3-dss", },
1274 { .compatible = "ti,omap4-dss", },
1275 { .compatible = "ti,omap5-dss", },
1276 { .compatible = "ti,dra7-dss", },
1277 {},
1278 };
1279
1280 MODULE_DEVICE_TABLE(of, dss_of_match);
1281
1282 static struct platform_driver omap_dsshw_driver = {
1283 .probe = dss_probe,
1284 .remove = dss_remove,
1285 .driver = {
1286 .name = "omapdss_dss",
1287 .pm = &dss_pm_ops,
1288 .of_match_table = dss_of_match,
1289 .suppress_bind_attrs = true,
1290 },
1291 };
1292
1293 int __init dss_init_platform_driver(void)
1294 {
1295 return platform_driver_register(&omap_dsshw_driver);
1296 }
1297
1298 void dss_uninit_platform_driver(void)
1299 {
1300 platform_driver_unregister(&omap_dsshw_driver);
1301 }