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