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