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