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/omapdss.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 enum omap_channel channel = out->dispc_channel; 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, channel, 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(channel, 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 enum omap_channel channel = out->dispc_channel; 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(channel, &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 enum omap_channel channel = out->dispc_channel; 389 int r; 390 391 mutex_lock(&dpi->lock); 392 393 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) { 394 DSSERR("no VDSS_DSI regulator\n"); 395 r = -ENODEV; 396 goto err_no_reg; 397 } 398 399 if (!out->dispc_channel_connected) { 400 DSSERR("failed to enable display: no output/manager\n"); 401 r = -ENODEV; 402 goto err_no_out_mgr; 403 } 404 405 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { 406 r = regulator_enable(dpi->vdds_dsi_reg); 407 if (r) 408 goto err_reg_enable; 409 } 410 411 r = dispc_runtime_get(); 412 if (r) 413 goto err_get_dispc; 414 415 r = dss_dpi_select_source(out->port_num, channel); 416 if (r) 417 goto err_src_sel; 418 419 if (dpi->pll) { 420 r = dss_pll_enable(dpi->pll); 421 if (r) 422 goto err_dsi_pll_init; 423 } 424 425 r = dpi_set_mode(dpi); 426 if (r) 427 goto err_set_mode; 428 429 dpi_config_lcd_manager(dpi); 430 431 mdelay(2); 432 433 r = dss_mgr_enable(channel); 434 if (r) 435 goto err_mgr_enable; 436 437 mutex_unlock(&dpi->lock); 438 439 return 0; 440 441 err_mgr_enable: 442 err_set_mode: 443 if (dpi->pll) 444 dss_pll_disable(dpi->pll); 445 err_dsi_pll_init: 446 err_src_sel: 447 dispc_runtime_put(); 448 err_get_dispc: 449 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 450 regulator_disable(dpi->vdds_dsi_reg); 451 err_reg_enable: 452 err_no_out_mgr: 453 err_no_reg: 454 mutex_unlock(&dpi->lock); 455 return r; 456 } 457 458 static void dpi_display_disable(struct omap_dss_device *dssdev) 459 { 460 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 461 enum omap_channel channel = dpi->output.dispc_channel; 462 463 mutex_lock(&dpi->lock); 464 465 dss_mgr_disable(channel); 466 467 if (dpi->pll) { 468 dss_select_lcd_clk_source(channel, OMAP_DSS_CLK_SRC_FCK); 469 dss_pll_disable(dpi->pll); 470 } 471 472 dispc_runtime_put(); 473 474 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 475 regulator_disable(dpi->vdds_dsi_reg); 476 477 mutex_unlock(&dpi->lock); 478 } 479 480 static void dpi_set_timings(struct omap_dss_device *dssdev, 481 struct omap_video_timings *timings) 482 { 483 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 484 485 DSSDBG("dpi_set_timings\n"); 486 487 mutex_lock(&dpi->lock); 488 489 dpi->timings = *timings; 490 491 mutex_unlock(&dpi->lock); 492 } 493 494 static void dpi_get_timings(struct omap_dss_device *dssdev, 495 struct omap_video_timings *timings) 496 { 497 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 498 499 mutex_lock(&dpi->lock); 500 501 *timings = dpi->timings; 502 503 mutex_unlock(&dpi->lock); 504 } 505 506 static int dpi_check_timings(struct omap_dss_device *dssdev, 507 struct omap_video_timings *timings) 508 { 509 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 510 enum omap_channel channel = dpi->output.dispc_channel; 511 int lck_div, pck_div; 512 unsigned long fck; 513 unsigned long pck; 514 struct dpi_clk_calc_ctx ctx; 515 bool ok; 516 517 if (timings->x_res % 8 != 0) 518 return -EINVAL; 519 520 if (!dispc_mgr_timings_ok(channel, timings)) 521 return -EINVAL; 522 523 if (timings->pixelclock == 0) 524 return -EINVAL; 525 526 if (dpi->pll) { 527 ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx); 528 if (!ok) 529 return -EINVAL; 530 531 fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC]; 532 } else { 533 ok = dpi_dss_clk_calc(timings->pixelclock, &ctx); 534 if (!ok) 535 return -EINVAL; 536 537 fck = ctx.fck; 538 } 539 540 lck_div = ctx.dispc_cinfo.lck_div; 541 pck_div = ctx.dispc_cinfo.pck_div; 542 543 pck = fck / lck_div / pck_div; 544 545 timings->pixelclock = pck; 546 547 return 0; 548 } 549 550 static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) 551 { 552 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 553 554 mutex_lock(&dpi->lock); 555 556 dpi->data_lines = data_lines; 557 558 mutex_unlock(&dpi->lock); 559 } 560 561 static int dpi_verify_dsi_pll(struct dss_pll *pll) 562 { 563 int r; 564 565 /* do initial setup with the PLL to see if it is operational */ 566 567 r = dss_pll_enable(pll); 568 if (r) 569 return r; 570 571 dss_pll_disable(pll); 572 573 return 0; 574 } 575 576 static int dpi_init_regulator(struct dpi_data *dpi) 577 { 578 struct regulator *vdds_dsi; 579 580 if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 581 return 0; 582 583 if (dpi->vdds_dsi_reg) 584 return 0; 585 586 vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi"); 587 if (IS_ERR(vdds_dsi)) { 588 if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) 589 DSSERR("can't get VDDS_DSI regulator\n"); 590 return PTR_ERR(vdds_dsi); 591 } 592 593 dpi->vdds_dsi_reg = vdds_dsi; 594 595 return 0; 596 } 597 598 static void dpi_init_pll(struct dpi_data *dpi) 599 { 600 struct dss_pll *pll; 601 602 if (dpi->pll) 603 return; 604 605 pll = dpi_get_pll(dpi->output.dispc_channel); 606 if (!pll) 607 return; 608 609 /* On DRA7 we need to set a mux to use the PLL */ 610 if (omapdss_get_version() == OMAPDSS_VER_DRA7xx) 611 dss_ctrl_pll_set_control_mux(pll->id, dpi->output.dispc_channel); 612 613 if (dpi_verify_dsi_pll(pll)) { 614 DSSWARN("DSI PLL not operational\n"); 615 return; 616 } 617 618 dpi->pll = pll; 619 } 620 621 /* 622 * Return a hardcoded channel for the DPI output. This should work for 623 * current use cases, but this can be later expanded to either resolve 624 * the channel in some more dynamic manner, or get the channel as a user 625 * parameter. 626 */ 627 static enum omap_channel dpi_get_channel(int port_num) 628 { 629 switch (omapdss_get_version()) { 630 case OMAPDSS_VER_OMAP24xx: 631 case OMAPDSS_VER_OMAP34xx_ES1: 632 case OMAPDSS_VER_OMAP34xx_ES3: 633 case OMAPDSS_VER_OMAP3630: 634 case OMAPDSS_VER_AM35xx: 635 case OMAPDSS_VER_AM43xx: 636 return OMAP_DSS_CHANNEL_LCD; 637 638 case OMAPDSS_VER_DRA7xx: 639 switch (port_num) { 640 case 2: 641 return OMAP_DSS_CHANNEL_LCD3; 642 case 1: 643 return OMAP_DSS_CHANNEL_LCD2; 644 case 0: 645 default: 646 return OMAP_DSS_CHANNEL_LCD; 647 } 648 649 case OMAPDSS_VER_OMAP4430_ES1: 650 case OMAPDSS_VER_OMAP4430_ES2: 651 case OMAPDSS_VER_OMAP4: 652 return OMAP_DSS_CHANNEL_LCD2; 653 654 case OMAPDSS_VER_OMAP5: 655 return OMAP_DSS_CHANNEL_LCD3; 656 657 default: 658 DSSWARN("unsupported DSS version\n"); 659 return OMAP_DSS_CHANNEL_LCD; 660 } 661 } 662 663 static int dpi_connect(struct omap_dss_device *dssdev, 664 struct omap_dss_device *dst) 665 { 666 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 667 enum omap_channel channel = dpi->output.dispc_channel; 668 int r; 669 670 r = dpi_init_regulator(dpi); 671 if (r) 672 return r; 673 674 dpi_init_pll(dpi); 675 676 r = dss_mgr_connect(channel, 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(channel, 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 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); 695 enum omap_channel channel = dpi->output.dispc_channel; 696 697 WARN_ON(dst != dssdev->dst); 698 699 if (dst != dssdev->dst) 700 return; 701 702 omapdss_output_unset_device(dssdev); 703 704 dss_mgr_disconnect(channel, dssdev); 705 } 706 707 static const struct omapdss_dpi_ops dpi_ops = { 708 .connect = dpi_connect, 709 .disconnect = dpi_disconnect, 710 711 .enable = dpi_display_enable, 712 .disable = dpi_display_disable, 713 714 .check_timings = dpi_check_timings, 715 .set_timings = dpi_set_timings, 716 .get_timings = dpi_get_timings, 717 718 .set_data_lines = dpi_set_data_lines, 719 }; 720 721 static void dpi_init_output(struct platform_device *pdev) 722 { 723 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); 724 struct omap_dss_device *out = &dpi->output; 725 726 out->dev = &pdev->dev; 727 out->id = OMAP_DSS_OUTPUT_DPI; 728 out->output_type = OMAP_DISPLAY_TYPE_DPI; 729 out->name = "dpi.0"; 730 out->dispc_channel = dpi_get_channel(0); 731 out->ops.dpi = &dpi_ops; 732 out->owner = THIS_MODULE; 733 734 omapdss_register_output(out); 735 } 736 737 static void dpi_uninit_output(struct platform_device *pdev) 738 { 739 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); 740 struct omap_dss_device *out = &dpi->output; 741 742 omapdss_unregister_output(out); 743 } 744 745 static void dpi_init_output_port(struct platform_device *pdev, 746 struct device_node *port) 747 { 748 struct dpi_data *dpi = port->data; 749 struct omap_dss_device *out = &dpi->output; 750 int r; 751 u32 port_num; 752 753 r = of_property_read_u32(port, "reg", &port_num); 754 if (r) 755 port_num = 0; 756 757 switch (port_num) { 758 case 2: 759 out->name = "dpi.2"; 760 break; 761 case 1: 762 out->name = "dpi.1"; 763 break; 764 case 0: 765 default: 766 out->name = "dpi.0"; 767 break; 768 } 769 770 out->dev = &pdev->dev; 771 out->id = OMAP_DSS_OUTPUT_DPI; 772 out->output_type = OMAP_DISPLAY_TYPE_DPI; 773 out->dispc_channel = dpi_get_channel(port_num); 774 out->port_num = port_num; 775 out->ops.dpi = &dpi_ops; 776 out->owner = THIS_MODULE; 777 778 omapdss_register_output(out); 779 } 780 781 static void dpi_uninit_output_port(struct device_node *port) 782 { 783 struct dpi_data *dpi = port->data; 784 struct omap_dss_device *out = &dpi->output; 785 786 omapdss_unregister_output(out); 787 } 788 789 static int dpi_bind(struct device *dev, struct device *master, void *data) 790 { 791 struct platform_device *pdev = to_platform_device(dev); 792 struct dpi_data *dpi; 793 794 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); 795 if (!dpi) 796 return -ENOMEM; 797 798 dpi->pdev = pdev; 799 800 dev_set_drvdata(&pdev->dev, dpi); 801 802 mutex_init(&dpi->lock); 803 804 dpi_init_output(pdev); 805 806 return 0; 807 } 808 809 static void dpi_unbind(struct device *dev, struct device *master, void *data) 810 { 811 struct platform_device *pdev = to_platform_device(dev); 812 813 dpi_uninit_output(pdev); 814 } 815 816 static const struct component_ops dpi_component_ops = { 817 .bind = dpi_bind, 818 .unbind = dpi_unbind, 819 }; 820 821 static int dpi_probe(struct platform_device *pdev) 822 { 823 return component_add(&pdev->dev, &dpi_component_ops); 824 } 825 826 static int dpi_remove(struct platform_device *pdev) 827 { 828 component_del(&pdev->dev, &dpi_component_ops); 829 return 0; 830 } 831 832 static struct platform_driver omap_dpi_driver = { 833 .probe = dpi_probe, 834 .remove = dpi_remove, 835 .driver = { 836 .name = "omapdss_dpi", 837 .suppress_bind_attrs = true, 838 }, 839 }; 840 841 int __init dpi_init_platform_driver(void) 842 { 843 return platform_driver_register(&omap_dpi_driver); 844 } 845 846 void dpi_uninit_platform_driver(void) 847 { 848 platform_driver_unregister(&omap_dpi_driver); 849 } 850 851 int dpi_init_port(struct platform_device *pdev, struct device_node *port) 852 { 853 struct dpi_data *dpi; 854 struct device_node *ep; 855 u32 datalines; 856 int r; 857 858 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); 859 if (!dpi) 860 return -ENOMEM; 861 862 ep = omapdss_of_get_next_endpoint(port, NULL); 863 if (!ep) 864 return 0; 865 866 r = of_property_read_u32(ep, "data-lines", &datalines); 867 if (r) { 868 DSSERR("failed to parse datalines\n"); 869 goto err_datalines; 870 } 871 872 dpi->data_lines = datalines; 873 874 of_node_put(ep); 875 876 dpi->pdev = pdev; 877 port->data = dpi; 878 879 mutex_init(&dpi->lock); 880 881 dpi_init_output_port(pdev, port); 882 883 dpi->port_initialized = true; 884 885 return 0; 886 887 err_datalines: 888 of_node_put(ep); 889 890 return r; 891 } 892 893 void dpi_uninit_port(struct device_node *port) 894 { 895 struct dpi_data *dpi = port->data; 896 897 if (!dpi->port_initialized) 898 return; 899 900 dpi_uninit_output_port(port); 901 } 902