0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define DSS_SUBSYS_NAME "DPI"
0011
0012 #include <linux/clk.h>
0013 #include <linux/delay.h>
0014 #include <linux/err.h>
0015 #include <linux/errno.h>
0016 #include <linux/export.h>
0017 #include <linux/kernel.h>
0018 #include <linux/of.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/regulator/consumer.h>
0021 #include <linux/string.h>
0022 #include <linux/sys_soc.h>
0023
0024 #include <drm/drm_bridge.h>
0025
0026 #include "dss.h"
0027 #include "omapdss.h"
0028
0029 struct dpi_data {
0030 struct platform_device *pdev;
0031 enum dss_model dss_model;
0032 struct dss_device *dss;
0033 unsigned int id;
0034
0035 struct regulator *vdds_dsi_reg;
0036 enum dss_clk_source clk_src;
0037 struct dss_pll *pll;
0038
0039 struct dss_lcd_mgr_config mgr_config;
0040 unsigned long pixelclock;
0041 int data_lines;
0042
0043 struct omap_dss_device output;
0044 struct drm_bridge bridge;
0045 };
0046
0047 #define drm_bridge_to_dpi(bridge) container_of(bridge, struct dpi_data, bridge)
0048
0049
0050
0051
0052
0053 static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
0054 enum omap_channel channel)
0055 {
0056
0057
0058
0059
0060
0061
0062
0063 switch (channel) {
0064 case OMAP_DSS_CHANNEL_LCD:
0065 {
0066 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_1))
0067 return DSS_CLK_SRC_PLL1_1;
0068 break;
0069 }
0070 case OMAP_DSS_CHANNEL_LCD2:
0071 {
0072 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
0073 return DSS_CLK_SRC_PLL1_3;
0074 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_3))
0075 return DSS_CLK_SRC_PLL2_3;
0076 break;
0077 }
0078 case OMAP_DSS_CHANNEL_LCD3:
0079 {
0080 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_1))
0081 return DSS_CLK_SRC_PLL2_1;
0082 if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
0083 return DSS_CLK_SRC_PLL1_3;
0084 break;
0085 }
0086 default:
0087 break;
0088 }
0089
0090 return DSS_CLK_SRC_FCK;
0091 }
0092
0093 static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
0094 {
0095 enum omap_channel channel = dpi->output.dispc_channel;
0096
0097
0098
0099
0100
0101
0102 switch (dpi->dss_model) {
0103 case DSS_MODEL_OMAP2:
0104 case DSS_MODEL_OMAP3:
0105 return DSS_CLK_SRC_FCK;
0106
0107 case DSS_MODEL_OMAP4:
0108 switch (channel) {
0109 case OMAP_DSS_CHANNEL_LCD:
0110 return DSS_CLK_SRC_PLL1_1;
0111 case OMAP_DSS_CHANNEL_LCD2:
0112 return DSS_CLK_SRC_PLL2_1;
0113 default:
0114 return DSS_CLK_SRC_FCK;
0115 }
0116
0117 case DSS_MODEL_OMAP5:
0118 switch (channel) {
0119 case OMAP_DSS_CHANNEL_LCD:
0120 return DSS_CLK_SRC_PLL1_1;
0121 case OMAP_DSS_CHANNEL_LCD3:
0122 return DSS_CLK_SRC_PLL2_1;
0123 case OMAP_DSS_CHANNEL_LCD2:
0124 default:
0125 return DSS_CLK_SRC_FCK;
0126 }
0127
0128 case DSS_MODEL_DRA7:
0129 return dpi_get_clk_src_dra7xx(dpi, channel);
0130
0131 default:
0132 return DSS_CLK_SRC_FCK;
0133 }
0134 }
0135
0136 struct dpi_clk_calc_ctx {
0137 struct dpi_data *dpi;
0138 unsigned int clkout_idx;
0139
0140
0141
0142 unsigned long pck_min, pck_max;
0143
0144
0145
0146 struct dss_pll_clock_info pll_cinfo;
0147 unsigned long fck;
0148 struct dispc_clock_info dispc_cinfo;
0149 };
0150
0151 static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
0152 unsigned long pck, void *data)
0153 {
0154 struct dpi_clk_calc_ctx *ctx = data;
0155
0156
0157
0158
0159
0160
0161 if (ctx->pck_min >= 100000000) {
0162 if (lckd > 1 && lckd % 2 != 0)
0163 return false;
0164
0165 if (pckd > 1 && pckd % 2 != 0)
0166 return false;
0167 }
0168
0169 ctx->dispc_cinfo.lck_div = lckd;
0170 ctx->dispc_cinfo.pck_div = pckd;
0171 ctx->dispc_cinfo.lck = lck;
0172 ctx->dispc_cinfo.pck = pck;
0173
0174 return true;
0175 }
0176
0177
0178 static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
0179 void *data)
0180 {
0181 struct dpi_clk_calc_ctx *ctx = data;
0182
0183 ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
0184 ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
0185
0186 return dispc_div_calc(ctx->dpi->dss->dispc, dispc,
0187 ctx->pck_min, ctx->pck_max,
0188 dpi_calc_dispc_cb, ctx);
0189 }
0190
0191
0192 static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
0193 unsigned long clkdco,
0194 void *data)
0195 {
0196 struct dpi_clk_calc_ctx *ctx = data;
0197
0198 ctx->pll_cinfo.n = n;
0199 ctx->pll_cinfo.m = m;
0200 ctx->pll_cinfo.fint = fint;
0201 ctx->pll_cinfo.clkdco = clkdco;
0202
0203 return dss_pll_hsdiv_calc_a(ctx->dpi->pll, clkdco,
0204 ctx->pck_min, dss_get_max_fck_rate(ctx->dpi->dss),
0205 dpi_calc_hsdiv_cb, ctx);
0206 }
0207
0208 static bool dpi_calc_dss_cb(unsigned long fck, void *data)
0209 {
0210 struct dpi_clk_calc_ctx *ctx = data;
0211
0212 ctx->fck = fck;
0213
0214 return dispc_div_calc(ctx->dpi->dss->dispc, fck,
0215 ctx->pck_min, ctx->pck_max,
0216 dpi_calc_dispc_cb, ctx);
0217 }
0218
0219 static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
0220 struct dpi_clk_calc_ctx *ctx)
0221 {
0222 unsigned long clkin;
0223
0224 memset(ctx, 0, sizeof(*ctx));
0225 ctx->dpi = dpi;
0226 ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);
0227
0228 clkin = clk_get_rate(dpi->pll->clkin);
0229
0230 if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
0231 unsigned long pll_min, pll_max;
0232
0233 ctx->pck_min = pck - 1000;
0234 ctx->pck_max = pck + 1000;
0235
0236 pll_min = 0;
0237 pll_max = 0;
0238
0239 return dss_pll_calc_a(ctx->dpi->pll, clkin,
0240 pll_min, pll_max,
0241 dpi_calc_pll_cb, ctx);
0242 } else {
0243 dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);
0244
0245 ctx->dispc_cinfo.lck_div = 1;
0246 ctx->dispc_cinfo.pck_div = 1;
0247 ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
0248 ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;
0249
0250 return true;
0251 }
0252 }
0253
0254 static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned long pck,
0255 struct dpi_clk_calc_ctx *ctx)
0256 {
0257 int i;
0258
0259
0260
0261
0262
0263
0264
0265
0266 for (i = 0; i < 25; ++i) {
0267 bool ok;
0268
0269 memset(ctx, 0, sizeof(*ctx));
0270 ctx->dpi = dpi;
0271 if (pck > 1000 * i * i * i)
0272 ctx->pck_min = max(pck - 1000 * i * i * i, 0lu);
0273 else
0274 ctx->pck_min = 0;
0275 ctx->pck_max = pck + 1000 * i * i * i;
0276
0277 ok = dss_div_calc(dpi->dss, pck, ctx->pck_min,
0278 dpi_calc_dss_cb, ctx);
0279 if (ok)
0280 return ok;
0281 }
0282
0283 return false;
0284 }
0285
0286
0287
0288 static int dpi_set_pll_clk(struct dpi_data *dpi, unsigned long pck_req)
0289 {
0290 struct dpi_clk_calc_ctx ctx;
0291 int r;
0292 bool ok;
0293
0294 ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
0295 if (!ok)
0296 return -EINVAL;
0297
0298 r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
0299 if (r)
0300 return r;
0301
0302 dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
0303 dpi->clk_src);
0304
0305 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
0306
0307 return 0;
0308 }
0309
0310 static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req)
0311 {
0312 struct dpi_clk_calc_ctx ctx;
0313 int r;
0314 bool ok;
0315
0316 ok = dpi_dss_clk_calc(dpi, pck_req, &ctx);
0317 if (!ok)
0318 return -EINVAL;
0319
0320 r = dss_set_fck_rate(dpi->dss, ctx.fck);
0321 if (r)
0322 return r;
0323
0324 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
0325
0326 return 0;
0327 }
0328
0329 static int dpi_set_mode(struct dpi_data *dpi)
0330 {
0331 int r;
0332
0333 if (dpi->pll)
0334 r = dpi_set_pll_clk(dpi, dpi->pixelclock);
0335 else
0336 r = dpi_set_dispc_clk(dpi, dpi->pixelclock);
0337
0338 return r;
0339 }
0340
0341 static void dpi_config_lcd_manager(struct dpi_data *dpi)
0342 {
0343 dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
0344
0345 dpi->mgr_config.stallmode = false;
0346 dpi->mgr_config.fifohandcheck = false;
0347
0348 dpi->mgr_config.video_port_width = dpi->data_lines;
0349
0350 dpi->mgr_config.lcden_sig_polarity = 0;
0351
0352 dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
0353 }
0354
0355 static int dpi_clock_update(struct dpi_data *dpi, unsigned long *clock)
0356 {
0357 int lck_div, pck_div;
0358 unsigned long fck;
0359 struct dpi_clk_calc_ctx ctx;
0360
0361 if (dpi->pll) {
0362 if (!dpi_pll_clk_calc(dpi, *clock, &ctx))
0363 return -EINVAL;
0364
0365 fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
0366 } else {
0367 if (!dpi_dss_clk_calc(dpi, *clock, &ctx))
0368 return -EINVAL;
0369
0370 fck = ctx.fck;
0371 }
0372
0373 lck_div = ctx.dispc_cinfo.lck_div;
0374 pck_div = ctx.dispc_cinfo.pck_div;
0375
0376 *clock = fck / lck_div / pck_div;
0377
0378 return 0;
0379 }
0380
0381 static int dpi_verify_pll(struct dss_pll *pll)
0382 {
0383 int r;
0384
0385
0386
0387 r = dss_pll_enable(pll);
0388 if (r)
0389 return r;
0390
0391 dss_pll_disable(pll);
0392
0393 return 0;
0394 }
0395
0396 static void dpi_init_pll(struct dpi_data *dpi)
0397 {
0398 struct dss_pll *pll;
0399
0400 if (dpi->pll)
0401 return;
0402
0403 dpi->clk_src = dpi_get_clk_src(dpi);
0404
0405 pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
0406 if (!pll)
0407 return;
0408
0409 if (dpi_verify_pll(pll)) {
0410 DSSWARN("PLL not operational\n");
0411 return;
0412 }
0413
0414 dpi->pll = pll;
0415 }
0416
0417
0418
0419
0420
0421 static int dpi_bridge_attach(struct drm_bridge *bridge,
0422 enum drm_bridge_attach_flags flags)
0423 {
0424 struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
0425
0426 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
0427 return -EINVAL;
0428
0429 dpi_init_pll(dpi);
0430
0431 return drm_bridge_attach(bridge->encoder, dpi->output.next_bridge,
0432 bridge, flags);
0433 }
0434
0435 static enum drm_mode_status
0436 dpi_bridge_mode_valid(struct drm_bridge *bridge,
0437 const struct drm_display_info *info,
0438 const struct drm_display_mode *mode)
0439 {
0440 struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
0441 unsigned long clock = mode->clock * 1000;
0442 int ret;
0443
0444 if (mode->hdisplay % 8 != 0)
0445 return MODE_BAD_WIDTH;
0446
0447 if (mode->clock == 0)
0448 return MODE_NOCLOCK;
0449
0450 ret = dpi_clock_update(dpi, &clock);
0451 if (ret < 0)
0452 return MODE_CLOCK_RANGE;
0453
0454 return MODE_OK;
0455 }
0456
0457 static bool dpi_bridge_mode_fixup(struct drm_bridge *bridge,
0458 const struct drm_display_mode *mode,
0459 struct drm_display_mode *adjusted_mode)
0460 {
0461 struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
0462 unsigned long clock = mode->clock * 1000;
0463 int ret;
0464
0465 ret = dpi_clock_update(dpi, &clock);
0466 if (ret < 0)
0467 return false;
0468
0469 adjusted_mode->clock = clock / 1000;
0470
0471 return true;
0472 }
0473
0474 static void dpi_bridge_mode_set(struct drm_bridge *bridge,
0475 const struct drm_display_mode *mode,
0476 const struct drm_display_mode *adjusted_mode)
0477 {
0478 struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
0479
0480 dpi->pixelclock = adjusted_mode->clock * 1000;
0481 }
0482
0483 static void dpi_bridge_enable(struct drm_bridge *bridge)
0484 {
0485 struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
0486 int r;
0487
0488 if (dpi->vdds_dsi_reg) {
0489 r = regulator_enable(dpi->vdds_dsi_reg);
0490 if (r)
0491 return;
0492 }
0493
0494 r = dispc_runtime_get(dpi->dss->dispc);
0495 if (r)
0496 goto err_get_dispc;
0497
0498 r = dss_dpi_select_source(dpi->dss, dpi->id, dpi->output.dispc_channel);
0499 if (r)
0500 goto err_src_sel;
0501
0502 if (dpi->pll) {
0503 r = dss_pll_enable(dpi->pll);
0504 if (r)
0505 goto err_pll_init;
0506 }
0507
0508 r = dpi_set_mode(dpi);
0509 if (r)
0510 goto err_set_mode;
0511
0512 dpi_config_lcd_manager(dpi);
0513
0514 mdelay(2);
0515
0516 r = dss_mgr_enable(&dpi->output);
0517 if (r)
0518 goto err_mgr_enable;
0519
0520 return;
0521
0522 err_mgr_enable:
0523 err_set_mode:
0524 if (dpi->pll)
0525 dss_pll_disable(dpi->pll);
0526 err_pll_init:
0527 err_src_sel:
0528 dispc_runtime_put(dpi->dss->dispc);
0529 err_get_dispc:
0530 if (dpi->vdds_dsi_reg)
0531 regulator_disable(dpi->vdds_dsi_reg);
0532 }
0533
0534 static void dpi_bridge_disable(struct drm_bridge *bridge)
0535 {
0536 struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
0537
0538 dss_mgr_disable(&dpi->output);
0539
0540 if (dpi->pll) {
0541 dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
0542 DSS_CLK_SRC_FCK);
0543 dss_pll_disable(dpi->pll);
0544 }
0545
0546 dispc_runtime_put(dpi->dss->dispc);
0547
0548 if (dpi->vdds_dsi_reg)
0549 regulator_disable(dpi->vdds_dsi_reg);
0550 }
0551
0552 static const struct drm_bridge_funcs dpi_bridge_funcs = {
0553 .attach = dpi_bridge_attach,
0554 .mode_valid = dpi_bridge_mode_valid,
0555 .mode_fixup = dpi_bridge_mode_fixup,
0556 .mode_set = dpi_bridge_mode_set,
0557 .enable = dpi_bridge_enable,
0558 .disable = dpi_bridge_disable,
0559 };
0560
0561 static void dpi_bridge_init(struct dpi_data *dpi)
0562 {
0563 dpi->bridge.funcs = &dpi_bridge_funcs;
0564 dpi->bridge.of_node = dpi->pdev->dev.of_node;
0565 dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
0566
0567 drm_bridge_add(&dpi->bridge);
0568 }
0569
0570 static void dpi_bridge_cleanup(struct dpi_data *dpi)
0571 {
0572 drm_bridge_remove(&dpi->bridge);
0573 }
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585 static enum omap_channel dpi_get_channel(struct dpi_data *dpi)
0586 {
0587 switch (dpi->dss_model) {
0588 case DSS_MODEL_OMAP2:
0589 case DSS_MODEL_OMAP3:
0590 return OMAP_DSS_CHANNEL_LCD;
0591
0592 case DSS_MODEL_DRA7:
0593 switch (dpi->id) {
0594 case 2:
0595 return OMAP_DSS_CHANNEL_LCD3;
0596 case 1:
0597 return OMAP_DSS_CHANNEL_LCD2;
0598 case 0:
0599 default:
0600 return OMAP_DSS_CHANNEL_LCD;
0601 }
0602
0603 case DSS_MODEL_OMAP4:
0604 return OMAP_DSS_CHANNEL_LCD2;
0605
0606 case DSS_MODEL_OMAP5:
0607 return OMAP_DSS_CHANNEL_LCD3;
0608
0609 default:
0610 DSSWARN("unsupported DSS version\n");
0611 return OMAP_DSS_CHANNEL_LCD;
0612 }
0613 }
0614
0615 static int dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
0616 {
0617 struct omap_dss_device *out = &dpi->output;
0618 u32 port_num = 0;
0619 int r;
0620
0621 dpi_bridge_init(dpi);
0622
0623 of_property_read_u32(port, "reg", &port_num);
0624 dpi->id = port_num <= 2 ? port_num : 0;
0625
0626 switch (port_num) {
0627 case 2:
0628 out->name = "dpi.2";
0629 break;
0630 case 1:
0631 out->name = "dpi.1";
0632 break;
0633 case 0:
0634 default:
0635 out->name = "dpi.0";
0636 break;
0637 }
0638
0639 out->dev = &dpi->pdev->dev;
0640 out->id = OMAP_DSS_OUTPUT_DPI;
0641 out->type = OMAP_DISPLAY_TYPE_DPI;
0642 out->dispc_channel = dpi_get_channel(dpi);
0643 out->of_port = port_num;
0644
0645 r = omapdss_device_init_output(out, &dpi->bridge);
0646 if (r < 0) {
0647 dpi_bridge_cleanup(dpi);
0648 return r;
0649 }
0650
0651 omapdss_device_register(out);
0652
0653 return 0;
0654 }
0655
0656 static void dpi_uninit_output_port(struct device_node *port)
0657 {
0658 struct dpi_data *dpi = port->data;
0659 struct omap_dss_device *out = &dpi->output;
0660
0661 omapdss_device_unregister(out);
0662 omapdss_device_cleanup_output(out);
0663
0664 dpi_bridge_cleanup(dpi);
0665 }
0666
0667
0668
0669
0670
0671 static const struct soc_device_attribute dpi_soc_devices[] = {
0672 { .machine = "OMAP3[456]*" },
0673 { .machine = "[AD]M37*" },
0674 { }
0675 };
0676
0677 static int dpi_init_regulator(struct dpi_data *dpi)
0678 {
0679 struct regulator *vdds_dsi;
0680
0681
0682
0683
0684
0685 if (!soc_device_match(dpi_soc_devices))
0686 return 0;
0687
0688 vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
0689 if (IS_ERR(vdds_dsi)) {
0690 if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
0691 DSSERR("can't get VDDS_DSI regulator\n");
0692 return PTR_ERR(vdds_dsi);
0693 }
0694
0695 dpi->vdds_dsi_reg = vdds_dsi;
0696
0697 return 0;
0698 }
0699
0700 int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
0701 struct device_node *port, enum dss_model dss_model)
0702 {
0703 struct dpi_data *dpi;
0704 struct device_node *ep;
0705 u32 datalines;
0706 int r;
0707
0708 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
0709 if (!dpi)
0710 return -ENOMEM;
0711
0712 ep = of_get_next_child(port, NULL);
0713 if (!ep)
0714 return 0;
0715
0716 r = of_property_read_u32(ep, "data-lines", &datalines);
0717 of_node_put(ep);
0718 if (r) {
0719 DSSERR("failed to parse datalines\n");
0720 return r;
0721 }
0722
0723 dpi->data_lines = datalines;
0724
0725 dpi->pdev = pdev;
0726 dpi->dss_model = dss_model;
0727 dpi->dss = dss;
0728 port->data = dpi;
0729
0730 r = dpi_init_regulator(dpi);
0731 if (r)
0732 return r;
0733
0734 return dpi_init_output_port(dpi, port);
0735 }
0736
0737 void dpi_uninit_port(struct device_node *port)
0738 {
0739 struct dpi_data *dpi = port->data;
0740
0741 if (!dpi)
0742 return;
0743
0744 dpi_uninit_output_port(port);
0745 }