1 /* 2 * linux/drivers/video/omap2/dss/dpi.c 3 * 4 * Copyright (C) 2009 Nokia Corporation 5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 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 "DPI" 24 25 #include <linux/kernel.h> 26 #include <linux/delay.h> 27 #include <linux/export.h> 28 #include <linux/err.h> 29 #include <linux/errno.h> 30 #include <linux/platform_device.h> 31 #include <linux/regulator/consumer.h> 32 #include <linux/string.h> 33 #include <linux/of.h> 34 #include <linux/clk.h> 35 #include <linux/component.h> 36 37 #include "omapdss.h" 38 #include "dss.h" 39 #include "dss_features.h" 40 41 struct dpi_data { 42 struct platform_device *pdev; 43 44 struct regulator *vdds_dsi_reg; 45 enum dss_clk_source clk_src; 46 struct dss_pll *pll; 47 48 struct mutex lock; 49 50 struct videomode vm; 51 struct dss_lcd_mgr_config mgr_config; 52 int data_lines; 53 54 struct omap_dss_device output; 55 56 bool port_initialized; 57 }; 58 59 static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev) 60 { 61 return container_of(dssdev, struct dpi_data, output); 62 } 63 64 /* only used in non-DT mode */ 65 static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev) 66 { 67 return dev_get_drvdata(&pdev->dev); 68 } 69 70 static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel) 71 { 72 /* 73 * Possible clock sources: 74 * LCD1: FCK/PLL1_1/HDMI_PLL 75 * LCD2: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_3) 76 * LCD3: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_1) 77 */ 78 79 switch (channel) { 80 case OMAP_DSS_CHANNEL_LCD: 81 { 82 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1)) 83 return DSS_CLK_SRC_PLL1_1; 84 break; 85 } 86 case OMAP_DSS_CHANNEL_LCD2: 87 { 88 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3)) 89 return DSS_CLK_SRC_PLL1_3; 90 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3)) 91 return DSS_CLK_SRC_PLL2_3; 92 break; 93 } 94 case OMAP_DSS_CHANNEL_LCD3: 95 { 96 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1)) 97 return DSS_CLK_SRC_PLL2_1; 98 if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3)) 99 return DSS_CLK_SRC_PLL1_3; 100 break; 101 } 102 default: 103 break; 104 } 105 106 return DSS_CLK_SRC_FCK; 107 } 108 109 static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel) 110 { 111 /* 112 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL 113 * would also be used for DISPC fclk. Meaning, when the DPI output is 114 * disabled, DISPC clock will be disabled, and TV out will stop. 115 */ 116 switch (omapdss_get_version()) { 117 case OMAPDSS_VER_OMAP24xx: 118 case OMAPDSS_VER_OMAP34xx_ES1: 119 case OMAPDSS_VER_OMAP34xx_ES3: 120 case OMAPDSS_VER_OMAP3630: 121 case OMAPDSS_VER_AM35xx: 122 case OMAPDSS_VER_AM43xx: 123 return DSS_CLK_SRC_FCK; 124 125 case OMAPDSS_VER_OMAP4430_ES1: 126 case OMAPDSS_VER_OMAP4430_ES2: 127 case OMAPDSS_VER_OMAP4: 128 switch (channel) { 129 case OMAP_DSS_CHANNEL_LCD: 130 return DSS_CLK_SRC_PLL1_1; 131 case OMAP_DSS_CHANNEL_LCD2: 132 return DSS_CLK_SRC_PLL2_1; 133 default: 134 return DSS_CLK_SRC_FCK; 135 } 136 137 case OMAPDSS_VER_OMAP5: 138 switch (channel) { 139 case OMAP_DSS_CHANNEL_LCD: 140 return DSS_CLK_SRC_PLL1_1; 141 case OMAP_DSS_CHANNEL_LCD3: 142 return DSS_CLK_SRC_PLL2_1; 143 case OMAP_DSS_CHANNEL_LCD2: 144 default: 145 return DSS_CLK_SRC_FCK; 146 } 147 148 case OMAPDSS_VER_DRA7xx: 149 return dpi_get_clk_src_dra7xx(channel); 150 151 default: 152 return DSS_CLK_SRC_FCK; 153 } 154 } 155 156 struct dpi_clk_calc_ctx { 157 struct dss_pll *pll; 158 unsigned clkout_idx; 159 160 /* inputs */ 161 162 unsigned long pck_min, pck_max; 163 164 /* outputs */ 165 166 struct dss_pll_clock_info pll_cinfo; 167 unsigned long fck; 168 struct dispc_clock_info dispc_cinfo; 169 }; 170 171 static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck, 172 unsigned long pck, void *data) 173 { 174 struct dpi_clk_calc_ctx *ctx = data; 175 176 /* 177 * Odd dividers give us uneven duty cycle, causing problem when level 178 * shifted. So skip all odd dividers when the pixel clock is on the 179 * higher side. 180 */ 181 if (ctx->pck_min >= 100000000) { 182 if (lckd > 1 && lckd % 2 != 0) 183 return false; 184 185 if (pckd > 1 && pckd % 2 != 0) 186 return false; 187 } 188 189 ctx->dispc_cinfo.lck_div = lckd; 190 ctx->dispc_cinfo.pck_div = pckd; 191 ctx->dispc_cinfo.lck = lck; 192 ctx->dispc_cinfo.pck = pck; 193 194 return true; 195 } 196 197 198 static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc, 199 void *data) 200 { 201 struct dpi_clk_calc_ctx *ctx = data; 202 203 ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc; 204 ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc; 205 206 return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, 207 dpi_calc_dispc_cb, ctx); 208 } 209 210 211 static bool dpi_calc_pll_cb(int n, int m, unsigned long fint, 212 unsigned long clkdco, 213 void *data) 214 { 215 struct dpi_clk_calc_ctx *ctx = data; 216 217 ctx->pll_cinfo.n = n; 218 ctx->pll_cinfo.m = m; 219 ctx->pll_cinfo.fint = fint; 220 ctx->pll_cinfo.clkdco = clkdco; 221 222 return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, 223 ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK), 224 dpi_calc_hsdiv_cb, ctx); 225 } 226 227 static bool dpi_calc_dss_cb(unsigned long fck, void *data) 228 { 229 struct dpi_clk_calc_ctx *ctx = data; 230 231 ctx->fck = fck; 232 233 return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max, 234 dpi_calc_dispc_cb, ctx); 235 } 236 237 static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck, 238 struct dpi_clk_calc_ctx *ctx) 239 { 240 unsigned long clkin; 241 242 memset(ctx, 0, sizeof(*ctx)); 243 ctx->pll = dpi->pll; 244 ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src); 245 246 clkin = clk_get_rate(dpi->pll->clkin); 247 248 if (dpi->pll->hw->type == DSS_PLL_TYPE_A) { 249 unsigned long pll_min, pll_max; 250 251 ctx->pck_min = pck - 1000; 252 ctx->pck_max = pck + 1000; 253 254 pll_min = 0; 255 pll_max = 0; 256 257 return dss_pll_calc_a(ctx->pll, clkin, 258 pll_min, pll_max, 259 dpi_calc_pll_cb, ctx); 260 } else { /* DSS_PLL_TYPE_B */ 261 dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo); 262 263 ctx->dispc_cinfo.lck_div = 1; 264 ctx->dispc_cinfo.pck_div = 1; 265 ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0]; 266 ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck; 267 268 return true; 269 } 270 } 271 272 static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) 273 { 274 int i; 275 276 /* 277 * DSS fck gives us very few possibilities, so finding a good pixel 278 * clock may not be possible. We try multiple times to find the clock, 279 * each time widening the pixel clock range we look for, up to 280 * +/- ~15MHz. 281 */ 282 283 for (i = 0; i < 25; ++i) { 284 bool ok; 285 286 memset(ctx, 0, sizeof(*ctx)); 287 if (pck > 1000 * i * i * i) 288 ctx->pck_min = max(pck - 1000 * i * i * i, 0lu); 289 else 290 ctx->pck_min = 0; 291 ctx->pck_max = pck + 1000 * i * i * i; 292 293 ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx); 294 if (ok) 295 return ok; 296 } 297 298 return false; 299 } 300 301 302 303 static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel, 304 unsigned long pck_req, unsigned long *fck, int *lck_div, 305 int *pck_div) 306 { 307 struct dpi_clk_calc_ctx ctx; 308 int r; 309 bool ok; 310 311 ok = dpi_pll_clk_calc(dpi, pck_req, &ctx); 312 if (!ok) 313 return -EINVAL; 314 315 r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo); 316 if (r) 317 return r; 318 319 dss_select_lcd_clk_source(channel, dpi->clk_src); 320 321 dpi->mgr_config.clock_info = ctx.dispc_cinfo; 322 323 *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx]; 324 *lck_div = ctx.dispc_cinfo.lck_div; 325 *pck_div = ctx.dispc_cinfo.pck_div; 326 327 return 0; 328 } 329 330 static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req, 331 unsigned long *fck, int *lck_div, int *pck_div) 332 { 333 struct dpi_clk_calc_ctx ctx; 334 int r; 335 bool ok; 336 337 ok = dpi_dss_clk_calc(pck_req, &ctx); 338 if (!ok) 339 return -EINVAL; 340 341 r = dss_set_fck_rate(ctx.fck); 342 if (r) 343 return r; 344 345 dpi->mgr_config.clock_info = ctx.dispc_cinfo; 346 347 *fck = ctx.fck; 348 *lck_div = ctx.dispc_cinfo.lck_div; 349 *pck_div = ctx.dispc_cinfo.pck_div; 350 351 return 0; 352 } 353 354 static int dpi_set_mode(struct dpi_data *dpi) 355 { 356 struct omap_dss_device *out = &dpi->output; 357 enum omap_channel channel = out->dispc_channel; 358 struct videomode *vm = &dpi->vm; 359 int lck_div = 0, pck_div = 0; 360 unsigned long fck = 0; 361 unsigned long pck; 362 int r = 0; 363 364 if (dpi->pll) 365 r = dpi_set_pll_clk(dpi, channel, vm->pixelclock, &fck, 366 &lck_div, &pck_div); 367 else 368 r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck, 369 &lck_div, &pck_div); 370 if (r) 371 return r; 372 373 pck = fck / lck_div / pck_div; 374 375 if (pck != vm->pixelclock) { 376 DSSWARN("Could not find exact pixel clock. Requested %lu Hz, got %lu Hz\n", 377 vm->pixelclock, pck); 378 379 vm->pixelclock = pck; 380 } 381 382 dss_mgr_set_timings(channel, vm); 383 384 return 0; 385 } 386 387 static void dpi_config_lcd_manager(struct dpi_data *dpi) 388 { 389 struct omap_dss_device *out = &dpi->output; 390 enum omap_channel channel = out->dispc_channel; 391 392 dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 393 394 dpi->mgr_config.stallmode = false; 395 dpi->mgr_config.fifohandcheck = false; 396 397 dpi->mgr_config.video_port_width = dpi->data_lines; 398 399 dpi->mgr_config.lcden_sig_polarity = 0; 400 401 dss_mgr_set_lcd_config(channel, &dpi->mgr_config); 402 } 403 404 static int dpi_display_enable(struct omap_dss_device *dssdev) 405 { 406 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 407 struct omap_dss_device *out = &dpi->output; 408 enum omap_channel channel = out->dispc_channel; 409 int r; 410 411 mutex_lock(&dpi->lock); 412 413 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) { 414 DSSERR("no VDSS_DSI regulator\n"); 415 r = -ENODEV; 416 goto err_no_reg; 417 } 418 419 if (!out->dispc_channel_connected) { 420 DSSERR("failed to enable display: no output/manager\n"); 421 r = -ENODEV; 422 goto err_no_out_mgr; 423 } 424 425 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { 426 r = regulator_enable(dpi->vdds_dsi_reg); 427 if (r) 428 goto err_reg_enable; 429 } 430 431 r = dispc_runtime_get(); 432 if (r) 433 goto err_get_dispc; 434 435 r = dss_dpi_select_source(out->port_num, channel); 436 if (r) 437 goto err_src_sel; 438 439 if (dpi->pll) { 440 r = dss_pll_enable(dpi->pll); 441 if (r) 442 goto err_pll_init; 443 } 444 445 r = dpi_set_mode(dpi); 446 if (r) 447 goto err_set_mode; 448 449 dpi_config_lcd_manager(dpi); 450 451 mdelay(2); 452 453 r = dss_mgr_enable(channel); 454 if (r) 455 goto err_mgr_enable; 456 457 mutex_unlock(&dpi->lock); 458 459 return 0; 460 461 err_mgr_enable: 462 err_set_mode: 463 if (dpi->pll) 464 dss_pll_disable(dpi->pll); 465 err_pll_init: 466 err_src_sel: 467 dispc_runtime_put(); 468 err_get_dispc: 469 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 470 regulator_disable(dpi->vdds_dsi_reg); 471 err_reg_enable: 472 err_no_out_mgr: 473 err_no_reg: 474 mutex_unlock(&dpi->lock); 475 return r; 476 } 477 478 static void dpi_display_disable(struct omap_dss_device *dssdev) 479 { 480 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 481 enum omap_channel channel = dpi->output.dispc_channel; 482 483 mutex_lock(&dpi->lock); 484 485 dss_mgr_disable(channel); 486 487 if (dpi->pll) { 488 dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); 489 dss_pll_disable(dpi->pll); 490 } 491 492 dispc_runtime_put(); 493 494 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 495 regulator_disable(dpi->vdds_dsi_reg); 496 497 mutex_unlock(&dpi->lock); 498 } 499 500 static void dpi_set_timings(struct omap_dss_device *dssdev, 501 struct videomode *vm) 502 { 503 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 504 505 DSSDBG("dpi_set_timings\n"); 506 507 mutex_lock(&dpi->lock); 508 509 dpi->vm = *vm; 510 511 mutex_unlock(&dpi->lock); 512 } 513 514 static void dpi_get_timings(struct omap_dss_device *dssdev, 515 struct videomode *vm) 516 { 517 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 518 519 mutex_lock(&dpi->lock); 520 521 *vm = dpi->vm; 522 523 mutex_unlock(&dpi->lock); 524 } 525 526 static int dpi_check_timings(struct omap_dss_device *dssdev, 527 struct videomode *vm) 528 { 529 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 530 enum omap_channel channel = dpi->output.dispc_channel; 531 int lck_div, pck_div; 532 unsigned long fck; 533 unsigned long pck; 534 struct dpi_clk_calc_ctx ctx; 535 bool ok; 536 537 if (vm->hactive % 8 != 0) 538 return -EINVAL; 539 540 if (!dispc_mgr_timings_ok(channel, vm)) 541 return -EINVAL; 542 543 if (vm->pixelclock == 0) 544 return -EINVAL; 545 546 if (dpi->pll) { 547 ok = dpi_pll_clk_calc(dpi, vm->pixelclock, &ctx); 548 if (!ok) 549 return -EINVAL; 550 551 fck = ctx.pll_cinfo.clkout[ctx.clkout_idx]; 552 } else { 553 ok = dpi_dss_clk_calc(vm->pixelclock, &ctx); 554 if (!ok) 555 return -EINVAL; 556 557 fck = ctx.fck; 558 } 559 560 lck_div = ctx.dispc_cinfo.lck_div; 561 pck_div = ctx.dispc_cinfo.pck_div; 562 563 pck = fck / lck_div / pck_div; 564 565 vm->pixelclock = pck; 566 567 return 0; 568 } 569 570 static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) 571 { 572 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 573 574 mutex_lock(&dpi->lock); 575 576 dpi->data_lines = data_lines; 577 578 mutex_unlock(&dpi->lock); 579 } 580 581 static int dpi_verify_pll(struct dss_pll *pll) 582 { 583 int r; 584 585 /* do initial setup with the PLL to see if it is operational */ 586 587 r = dss_pll_enable(pll); 588 if (r) 589 return r; 590 591 dss_pll_disable(pll); 592 593 return 0; 594 } 595 596 static int dpi_init_regulator(struct dpi_data *dpi) 597 { 598 struct regulator *vdds_dsi; 599 600 if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 601 return 0; 602 603 if (dpi->vdds_dsi_reg) 604 return 0; 605 606 vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi"); 607 if (IS_ERR(vdds_dsi)) { 608 if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) 609 DSSERR("can't get VDDS_DSI regulator\n"); 610 return PTR_ERR(vdds_dsi); 611 } 612 613 dpi->vdds_dsi_reg = vdds_dsi; 614 615 return 0; 616 } 617 618 static void dpi_init_pll(struct dpi_data *dpi) 619 { 620 struct dss_pll *pll; 621 622 if (dpi->pll) 623 return; 624 625 dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel); 626 627 pll = dss_pll_find_by_src(dpi->clk_src); 628 if (!pll) 629 return; 630 631 if (dpi_verify_pll(pll)) { 632 DSSWARN("PLL not operational\n"); 633 return; 634 } 635 636 dpi->pll = pll; 637 } 638 639 /* 640 * Return a hardcoded channel for the DPI output. This should work for 641 * current use cases, but this can be later expanded to either resolve 642 * the channel in some more dynamic manner, or get the channel as a user 643 * parameter. 644 */ 645 static enum omap_channel dpi_get_channel(int port_num) 646 { 647 switch (omapdss_get_version()) { 648 case OMAPDSS_VER_OMAP24xx: 649 case OMAPDSS_VER_OMAP34xx_ES1: 650 case OMAPDSS_VER_OMAP34xx_ES3: 651 case OMAPDSS_VER_OMAP3630: 652 case OMAPDSS_VER_AM35xx: 653 case OMAPDSS_VER_AM43xx: 654 return OMAP_DSS_CHANNEL_LCD; 655 656 case OMAPDSS_VER_DRA7xx: 657 switch (port_num) { 658 case 2: 659 return OMAP_DSS_CHANNEL_LCD3; 660 case 1: 661 return OMAP_DSS_CHANNEL_LCD2; 662 case 0: 663 default: 664 return OMAP_DSS_CHANNEL_LCD; 665 } 666 667 case OMAPDSS_VER_OMAP4430_ES1: 668 case OMAPDSS_VER_OMAP4430_ES2: 669 case OMAPDSS_VER_OMAP4: 670 return OMAP_DSS_CHANNEL_LCD2; 671 672 case OMAPDSS_VER_OMAP5: 673 return OMAP_DSS_CHANNEL_LCD3; 674 675 default: 676 DSSWARN("unsupported DSS version\n"); 677 return OMAP_DSS_CHANNEL_LCD; 678 } 679 } 680 681 static int dpi_connect(struct omap_dss_device *dssdev, 682 struct omap_dss_device *dst) 683 { 684 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 685 enum omap_channel channel = dpi->output.dispc_channel; 686 int r; 687 688 r = dpi_init_regulator(dpi); 689 if (r) 690 return r; 691 692 dpi_init_pll(dpi); 693 694 r = dss_mgr_connect(channel, dssdev); 695 if (r) 696 return r; 697 698 r = omapdss_output_set_device(dssdev, dst); 699 if (r) { 700 DSSERR("failed to connect output to new device: %s\n", 701 dst->name); 702 dss_mgr_disconnect(channel, dssdev); 703 return r; 704 } 705 706 return 0; 707 } 708 709 static void dpi_disconnect(struct omap_dss_device *dssdev, 710 struct omap_dss_device *dst) 711 { 712 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 713 enum omap_channel channel = dpi->output.dispc_channel; 714 715 WARN_ON(dst != dssdev->dst); 716 717 if (dst != dssdev->dst) 718 return; 719 720 omapdss_output_unset_device(dssdev); 721 722 dss_mgr_disconnect(channel, dssdev); 723 } 724 725 static const struct omapdss_dpi_ops dpi_ops = { 726 .connect = dpi_connect, 727 .disconnect = dpi_disconnect, 728 729 .enable = dpi_display_enable, 730 .disable = dpi_display_disable, 731 732 .check_timings = dpi_check_timings, 733 .set_timings = dpi_set_timings, 734 .get_timings = dpi_get_timings, 735 736 .set_data_lines = dpi_set_data_lines, 737 }; 738 739 static void dpi_init_output(struct platform_device *pdev) 740 { 741 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); 742 struct omap_dss_device *out = &dpi->output; 743 744 out->dev = &pdev->dev; 745 out->id = OMAP_DSS_OUTPUT_DPI; 746 out->output_type = OMAP_DISPLAY_TYPE_DPI; 747 out->name = "dpi.0"; 748 out->dispc_channel = dpi_get_channel(0); 749 out->ops.dpi = &dpi_ops; 750 out->owner = THIS_MODULE; 751 752 omapdss_register_output(out); 753 } 754 755 static void dpi_uninit_output(struct platform_device *pdev) 756 { 757 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); 758 struct omap_dss_device *out = &dpi->output; 759 760 omapdss_unregister_output(out); 761 } 762 763 static void dpi_init_output_port(struct platform_device *pdev, 764 struct device_node *port) 765 { 766 struct dpi_data *dpi = port->data; 767 struct omap_dss_device *out = &dpi->output; 768 int r; 769 u32 port_num; 770 771 r = of_property_read_u32(port, "reg", &port_num); 772 if (r) 773 port_num = 0; 774 775 switch (port_num) { 776 case 2: 777 out->name = "dpi.2"; 778 break; 779 case 1: 780 out->name = "dpi.1"; 781 break; 782 case 0: 783 default: 784 out->name = "dpi.0"; 785 break; 786 } 787 788 out->dev = &pdev->dev; 789 out->id = OMAP_DSS_OUTPUT_DPI; 790 out->output_type = OMAP_DISPLAY_TYPE_DPI; 791 out->dispc_channel = dpi_get_channel(port_num); 792 out->port_num = port_num; 793 out->ops.dpi = &dpi_ops; 794 out->owner = THIS_MODULE; 795 796 omapdss_register_output(out); 797 } 798 799 static void dpi_uninit_output_port(struct device_node *port) 800 { 801 struct dpi_data *dpi = port->data; 802 struct omap_dss_device *out = &dpi->output; 803 804 omapdss_unregister_output(out); 805 } 806 807 static int dpi_bind(struct device *dev, struct device *master, void *data) 808 { 809 struct platform_device *pdev = to_platform_device(dev); 810 struct dpi_data *dpi; 811 812 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); 813 if (!dpi) 814 return -ENOMEM; 815 816 dpi->pdev = pdev; 817 818 dev_set_drvdata(&pdev->dev, dpi); 819 820 mutex_init(&dpi->lock); 821 822 dpi_init_output(pdev); 823 824 return 0; 825 } 826 827 static void dpi_unbind(struct device *dev, struct device *master, void *data) 828 { 829 struct platform_device *pdev = to_platform_device(dev); 830 831 dpi_uninit_output(pdev); 832 } 833 834 static const struct component_ops dpi_component_ops = { 835 .bind = dpi_bind, 836 .unbind = dpi_unbind, 837 }; 838 839 static int dpi_probe(struct platform_device *pdev) 840 { 841 return component_add(&pdev->dev, &dpi_component_ops); 842 } 843 844 static int dpi_remove(struct platform_device *pdev) 845 { 846 component_del(&pdev->dev, &dpi_component_ops); 847 return 0; 848 } 849 850 static struct platform_driver omap_dpi_driver = { 851 .probe = dpi_probe, 852 .remove = dpi_remove, 853 .driver = { 854 .name = "omapdss_dpi", 855 .suppress_bind_attrs = true, 856 }, 857 }; 858 859 int __init dpi_init_platform_driver(void) 860 { 861 return platform_driver_register(&omap_dpi_driver); 862 } 863 864 void dpi_uninit_platform_driver(void) 865 { 866 platform_driver_unregister(&omap_dpi_driver); 867 } 868 869 int dpi_init_port(struct platform_device *pdev, struct device_node *port) 870 { 871 struct dpi_data *dpi; 872 struct device_node *ep; 873 u32 datalines; 874 int r; 875 876 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); 877 if (!dpi) 878 return -ENOMEM; 879 880 ep = of_get_next_child(port, NULL); 881 if (!ep) 882 return 0; 883 884 r = of_property_read_u32(ep, "data-lines", &datalines); 885 if (r) { 886 DSSERR("failed to parse datalines\n"); 887 goto err_datalines; 888 } 889 890 dpi->data_lines = datalines; 891 892 of_node_put(ep); 893 894 dpi->pdev = pdev; 895 port->data = dpi; 896 897 mutex_init(&dpi->lock); 898 899 dpi_init_output_port(pdev, port); 900 901 dpi->port_initialized = true; 902 903 return 0; 904 905 err_datalines: 906 of_node_put(ep); 907 908 return r; 909 } 910 911 void dpi_uninit_port(struct device_node *port) 912 { 913 struct dpi_data *dpi = port->data; 914 915 if (!dpi->port_initialized) 916 return; 917 918 dpi_uninit_output_port(port); 919 } 920