1 /* 2 * linux/drivers/video/omap2/dss/dss.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 "DSS" 24 25 #include <linux/debugfs.h> 26 #include <linux/kernel.h> 27 #include <linux/module.h> 28 #include <linux/io.h> 29 #include <linux/export.h> 30 #include <linux/err.h> 31 #include <linux/delay.h> 32 #include <linux/seq_file.h> 33 #include <linux/clk.h> 34 #include <linux/pinctrl/consumer.h> 35 #include <linux/platform_device.h> 36 #include <linux/pm_runtime.h> 37 #include <linux/gfp.h> 38 #include <linux/sizes.h> 39 #include <linux/mfd/syscon.h> 40 #include <linux/regmap.h> 41 #include <linux/of.h> 42 #include <linux/of_device.h> 43 #include <linux/of_graph.h> 44 #include <linux/regulator/consumer.h> 45 #include <linux/suspend.h> 46 #include <linux/component.h> 47 #include <linux/sys_soc.h> 48 49 #include "omapdss.h" 50 #include "dss.h" 51 52 #define DSS_SZ_REGS SZ_512 53 54 struct dss_reg { 55 u16 idx; 56 }; 57 58 #define DSS_REG(idx) ((const struct dss_reg) { idx }) 59 60 #define DSS_REVISION DSS_REG(0x0000) 61 #define DSS_SYSCONFIG DSS_REG(0x0010) 62 #define DSS_SYSSTATUS DSS_REG(0x0014) 63 #define DSS_CONTROL DSS_REG(0x0040) 64 #define DSS_SDI_CONTROL DSS_REG(0x0044) 65 #define DSS_PLL_CONTROL DSS_REG(0x0048) 66 #define DSS_SDI_STATUS DSS_REG(0x005C) 67 68 #define REG_GET(idx, start, end) \ 69 FLD_GET(dss_read_reg(idx), start, end) 70 71 #define REG_FLD_MOD(idx, val, start, end) \ 72 dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) 73 74 struct dss_ops { 75 int (*dpi_select_source)(int port, enum omap_channel channel); 76 int (*select_lcd_source)(enum omap_channel channel, 77 enum dss_clk_source clk_src); 78 }; 79 80 struct dss_features { 81 enum dss_model model; 82 u8 fck_div_max; 83 unsigned int fck_freq_max; 84 u8 dss_fck_multiplier; 85 const char *parent_clk_name; 86 const enum omap_display_type *ports; 87 int num_ports; 88 const enum omap_dss_output_id *outputs; 89 const struct dss_ops *ops; 90 struct dss_reg_field dispc_clk_switch; 91 bool has_lcd_clk_src; 92 }; 93 94 static struct { 95 struct platform_device *pdev; 96 void __iomem *base; 97 struct regmap *syscon_pll_ctrl; 98 u32 syscon_pll_ctrl_offset; 99 100 struct clk *parent_clk; 101 struct clk *dss_clk; 102 unsigned long dss_clk_rate; 103 104 unsigned long cache_req_pck; 105 unsigned long cache_prate; 106 struct dispc_clock_info cache_dispc_cinfo; 107 108 enum dss_clk_source dsi_clk_source[MAX_NUM_DSI]; 109 enum dss_clk_source dispc_clk_source; 110 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; 111 112 bool ctx_valid; 113 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 114 115 const struct dss_features *feat; 116 117 struct dss_pll *video1_pll; 118 struct dss_pll *video2_pll; 119 } dss; 120 121 static const char * const dss_generic_clk_source_names[] = { 122 [DSS_CLK_SRC_FCK] = "FCK", 123 [DSS_CLK_SRC_PLL1_1] = "PLL1:1", 124 [DSS_CLK_SRC_PLL1_2] = "PLL1:2", 125 [DSS_CLK_SRC_PLL1_3] = "PLL1:3", 126 [DSS_CLK_SRC_PLL2_1] = "PLL2:1", 127 [DSS_CLK_SRC_PLL2_2] = "PLL2:2", 128 [DSS_CLK_SRC_PLL2_3] = "PLL2:3", 129 [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL", 130 }; 131 132 static inline void dss_write_reg(const struct dss_reg idx, u32 val) 133 { 134 __raw_writel(val, dss.base + idx.idx); 135 } 136 137 static inline u32 dss_read_reg(const struct dss_reg idx) 138 { 139 return __raw_readl(dss.base + idx.idx); 140 } 141 142 #define SR(reg) \ 143 dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg) 144 #define RR(reg) \ 145 dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)]) 146 147 static void dss_save_context(void) 148 { 149 DSSDBG("dss_save_context\n"); 150 151 SR(CONTROL); 152 153 if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { 154 SR(SDI_CONTROL); 155 SR(PLL_CONTROL); 156 } 157 158 dss.ctx_valid = true; 159 160 DSSDBG("context saved\n"); 161 } 162 163 static void dss_restore_context(void) 164 { 165 DSSDBG("dss_restore_context\n"); 166 167 if (!dss.ctx_valid) 168 return; 169 170 RR(CONTROL); 171 172 if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { 173 RR(SDI_CONTROL); 174 RR(PLL_CONTROL); 175 } 176 177 DSSDBG("context restored\n"); 178 } 179 180 #undef SR 181 #undef RR 182 183 void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable) 184 { 185 unsigned shift; 186 unsigned val; 187 188 if (!dss.syscon_pll_ctrl) 189 return; 190 191 val = !enable; 192 193 switch (pll_id) { 194 case DSS_PLL_VIDEO1: 195 shift = 0; 196 break; 197 case DSS_PLL_VIDEO2: 198 shift = 1; 199 break; 200 case DSS_PLL_HDMI: 201 shift = 2; 202 break; 203 default: 204 DSSERR("illegal DSS PLL ID %d\n", pll_id); 205 return; 206 } 207 208 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, 209 1 << shift, val << shift); 210 } 211 212 static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src, 213 enum omap_channel channel) 214 { 215 unsigned shift, val; 216 217 if (!dss.syscon_pll_ctrl) 218 return -EINVAL; 219 220 switch (channel) { 221 case OMAP_DSS_CHANNEL_LCD: 222 shift = 3; 223 224 switch (clk_src) { 225 case DSS_CLK_SRC_PLL1_1: 226 val = 0; break; 227 case DSS_CLK_SRC_HDMI_PLL: 228 val = 1; break; 229 default: 230 DSSERR("error in PLL mux config for LCD\n"); 231 return -EINVAL; 232 } 233 234 break; 235 case OMAP_DSS_CHANNEL_LCD2: 236 shift = 5; 237 238 switch (clk_src) { 239 case DSS_CLK_SRC_PLL1_3: 240 val = 0; break; 241 case DSS_CLK_SRC_PLL2_3: 242 val = 1; break; 243 case DSS_CLK_SRC_HDMI_PLL: 244 val = 2; break; 245 default: 246 DSSERR("error in PLL mux config for LCD2\n"); 247 return -EINVAL; 248 } 249 250 break; 251 case OMAP_DSS_CHANNEL_LCD3: 252 shift = 7; 253 254 switch (clk_src) { 255 case DSS_CLK_SRC_PLL2_1: 256 val = 0; break; 257 case DSS_CLK_SRC_PLL1_3: 258 val = 1; break; 259 case DSS_CLK_SRC_HDMI_PLL: 260 val = 2; break; 261 default: 262 DSSERR("error in PLL mux config for LCD3\n"); 263 return -EINVAL; 264 } 265 266 break; 267 default: 268 DSSERR("error in PLL mux config\n"); 269 return -EINVAL; 270 } 271 272 regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, 273 0x3 << shift, val << shift); 274 275 return 0; 276 } 277 278 void dss_sdi_init(int datapairs) 279 { 280 u32 l; 281 282 BUG_ON(datapairs > 3 || datapairs < 1); 283 284 l = dss_read_reg(DSS_SDI_CONTROL); 285 l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */ 286 l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */ 287 l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */ 288 dss_write_reg(DSS_SDI_CONTROL, l); 289 290 l = dss_read_reg(DSS_PLL_CONTROL); 291 l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */ 292 l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */ 293 l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */ 294 dss_write_reg(DSS_PLL_CONTROL, l); 295 } 296 297 int dss_sdi_enable(void) 298 { 299 unsigned long timeout; 300 301 dispc_pck_free_enable(1); 302 303 /* Reset SDI PLL */ 304 REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */ 305 udelay(1); /* wait 2x PCLK */ 306 307 /* Lock SDI PLL */ 308 REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */ 309 310 /* Waiting for PLL lock request to complete */ 311 timeout = jiffies + msecs_to_jiffies(500); 312 while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) { 313 if (time_after_eq(jiffies, timeout)) { 314 DSSERR("PLL lock request timed out\n"); 315 goto err1; 316 } 317 } 318 319 /* Clearing PLL_GO bit */ 320 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28); 321 322 /* Waiting for PLL to lock */ 323 timeout = jiffies + msecs_to_jiffies(500); 324 while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) { 325 if (time_after_eq(jiffies, timeout)) { 326 DSSERR("PLL lock timed out\n"); 327 goto err1; 328 } 329 } 330 331 dispc_lcd_enable_signal(1); 332 333 /* Waiting for SDI reset to complete */ 334 timeout = jiffies + msecs_to_jiffies(500); 335 while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) { 336 if (time_after_eq(jiffies, timeout)) { 337 DSSERR("SDI reset timed out\n"); 338 goto err2; 339 } 340 } 341 342 return 0; 343 344 err2: 345 dispc_lcd_enable_signal(0); 346 err1: 347 /* Reset SDI PLL */ 348 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 349 350 dispc_pck_free_enable(0); 351 352 return -ETIMEDOUT; 353 } 354 355 void dss_sdi_disable(void) 356 { 357 dispc_lcd_enable_signal(0); 358 359 dispc_pck_free_enable(0); 360 361 /* Reset SDI PLL */ 362 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 363 } 364 365 const char *dss_get_clk_source_name(enum dss_clk_source clk_src) 366 { 367 return dss_generic_clk_source_names[clk_src]; 368 } 369 370 void dss_dump_clocks(struct seq_file *s) 371 { 372 const char *fclk_name; 373 unsigned long fclk_rate; 374 375 if (dss_runtime_get()) 376 return; 377 378 seq_printf(s, "- DSS -\n"); 379 380 fclk_name = dss_get_clk_source_name(DSS_CLK_SRC_FCK); 381 fclk_rate = clk_get_rate(dss.dss_clk); 382 383 seq_printf(s, "%s = %lu\n", 384 fclk_name, 385 fclk_rate); 386 387 dss_runtime_put(); 388 } 389 390 static void dss_dump_regs(struct seq_file *s) 391 { 392 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) 393 394 if (dss_runtime_get()) 395 return; 396 397 DUMPREG(DSS_REVISION); 398 DUMPREG(DSS_SYSCONFIG); 399 DUMPREG(DSS_SYSSTATUS); 400 DUMPREG(DSS_CONTROL); 401 402 if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { 403 DUMPREG(DSS_SDI_CONTROL); 404 DUMPREG(DSS_PLL_CONTROL); 405 DUMPREG(DSS_SDI_STATUS); 406 } 407 408 dss_runtime_put(); 409 #undef DUMPREG 410 } 411 412 static int dss_get_channel_index(enum omap_channel channel) 413 { 414 switch (channel) { 415 case OMAP_DSS_CHANNEL_LCD: 416 return 0; 417 case OMAP_DSS_CHANNEL_LCD2: 418 return 1; 419 case OMAP_DSS_CHANNEL_LCD3: 420 return 2; 421 default: 422 WARN_ON(1); 423 return 0; 424 } 425 } 426 427 static void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 428 { 429 int b; 430 431 /* 432 * We always use PRCM clock as the DISPC func clock, except on DSS3, 433 * where we don't have separate DISPC and LCD clock sources. 434 */ 435 if (WARN_ON(dss.feat->has_lcd_clk_src && clk_src != DSS_CLK_SRC_FCK)) 436 return; 437 438 switch (clk_src) { 439 case DSS_CLK_SRC_FCK: 440 b = 0; 441 break; 442 case DSS_CLK_SRC_PLL1_1: 443 b = 1; 444 break; 445 case DSS_CLK_SRC_PLL2_1: 446 b = 2; 447 break; 448 default: 449 BUG(); 450 return; 451 } 452 453 REG_FLD_MOD(DSS_CONTROL, b, /* DISPC_CLK_SWITCH */ 454 dss.feat->dispc_clk_switch.start, 455 dss.feat->dispc_clk_switch.end); 456 457 dss.dispc_clk_source = clk_src; 458 } 459 460 void dss_select_dsi_clk_source(int dsi_module, 461 enum dss_clk_source clk_src) 462 { 463 int b, pos; 464 465 switch (clk_src) { 466 case DSS_CLK_SRC_FCK: 467 b = 0; 468 break; 469 case DSS_CLK_SRC_PLL1_2: 470 BUG_ON(dsi_module != 0); 471 b = 1; 472 break; 473 case DSS_CLK_SRC_PLL2_2: 474 BUG_ON(dsi_module != 1); 475 b = 1; 476 break; 477 default: 478 BUG(); 479 return; 480 } 481 482 pos = dsi_module == 0 ? 1 : 10; 483 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* DSIx_CLK_SWITCH */ 484 485 dss.dsi_clk_source[dsi_module] = clk_src; 486 } 487 488 static int dss_lcd_clk_mux_dra7(enum omap_channel channel, 489 enum dss_clk_source clk_src) 490 { 491 const u8 ctrl_bits[] = { 492 [OMAP_DSS_CHANNEL_LCD] = 0, 493 [OMAP_DSS_CHANNEL_LCD2] = 12, 494 [OMAP_DSS_CHANNEL_LCD3] = 19, 495 }; 496 497 u8 ctrl_bit = ctrl_bits[channel]; 498 int r; 499 500 if (clk_src == DSS_CLK_SRC_FCK) { 501 /* LCDx_CLK_SWITCH */ 502 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit); 503 return -EINVAL; 504 } 505 506 r = dss_ctrl_pll_set_control_mux(clk_src, channel); 507 if (r) 508 return r; 509 510 REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit); 511 512 return 0; 513 } 514 515 static int dss_lcd_clk_mux_omap5(enum omap_channel channel, 516 enum dss_clk_source clk_src) 517 { 518 const u8 ctrl_bits[] = { 519 [OMAP_DSS_CHANNEL_LCD] = 0, 520 [OMAP_DSS_CHANNEL_LCD2] = 12, 521 [OMAP_DSS_CHANNEL_LCD3] = 19, 522 }; 523 const enum dss_clk_source allowed_plls[] = { 524 [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1, 525 [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_FCK, 526 [OMAP_DSS_CHANNEL_LCD3] = DSS_CLK_SRC_PLL2_1, 527 }; 528 529 u8 ctrl_bit = ctrl_bits[channel]; 530 531 if (clk_src == DSS_CLK_SRC_FCK) { 532 /* LCDx_CLK_SWITCH */ 533 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit); 534 return -EINVAL; 535 } 536 537 if (WARN_ON(allowed_plls[channel] != clk_src)) 538 return -EINVAL; 539 540 REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit); 541 542 return 0; 543 } 544 545 static int dss_lcd_clk_mux_omap4(enum omap_channel channel, 546 enum dss_clk_source clk_src) 547 { 548 const u8 ctrl_bits[] = { 549 [OMAP_DSS_CHANNEL_LCD] = 0, 550 [OMAP_DSS_CHANNEL_LCD2] = 12, 551 }; 552 const enum dss_clk_source allowed_plls[] = { 553 [OMAP_DSS_CHANNEL_LCD] = DSS_CLK_SRC_PLL1_1, 554 [OMAP_DSS_CHANNEL_LCD2] = DSS_CLK_SRC_PLL2_1, 555 }; 556 557 u8 ctrl_bit = ctrl_bits[channel]; 558 559 if (clk_src == DSS_CLK_SRC_FCK) { 560 /* LCDx_CLK_SWITCH */ 561 REG_FLD_MOD(DSS_CONTROL, 0, ctrl_bit, ctrl_bit); 562 return 0; 563 } 564 565 if (WARN_ON(allowed_plls[channel] != clk_src)) 566 return -EINVAL; 567 568 REG_FLD_MOD(DSS_CONTROL, 1, ctrl_bit, ctrl_bit); 569 570 return 0; 571 } 572 573 void dss_select_lcd_clk_source(enum omap_channel channel, 574 enum dss_clk_source clk_src) 575 { 576 int idx = dss_get_channel_index(channel); 577 int r; 578 579 if (!dss.feat->has_lcd_clk_src) { 580 dss_select_dispc_clk_source(clk_src); 581 dss.lcd_clk_source[idx] = clk_src; 582 return; 583 } 584 585 r = dss.feat->ops->select_lcd_source(channel, clk_src); 586 if (r) 587 return; 588 589 dss.lcd_clk_source[idx] = clk_src; 590 } 591 592 enum dss_clk_source dss_get_dispc_clk_source(void) 593 { 594 return dss.dispc_clk_source; 595 } 596 597 enum dss_clk_source dss_get_dsi_clk_source(int dsi_module) 598 { 599 return dss.dsi_clk_source[dsi_module]; 600 } 601 602 enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) 603 { 604 if (dss.feat->has_lcd_clk_src) { 605 int idx = dss_get_channel_index(channel); 606 return dss.lcd_clk_source[idx]; 607 } else { 608 /* LCD_CLK source is the same as DISPC_FCLK source for 609 * OMAP2 and OMAP3 */ 610 return dss.dispc_clk_source; 611 } 612 } 613 614 bool dss_div_calc(unsigned long pck, unsigned long fck_min, 615 dss_div_calc_func func, void *data) 616 { 617 int fckd, fckd_start, fckd_stop; 618 unsigned long fck; 619 unsigned long fck_hw_max; 620 unsigned long fckd_hw_max; 621 unsigned long prate; 622 unsigned m; 623 624 fck_hw_max = dss.feat->fck_freq_max; 625 626 if (dss.parent_clk == NULL) { 627 unsigned pckd; 628 629 pckd = fck_hw_max / pck; 630 631 fck = pck * pckd; 632 633 fck = clk_round_rate(dss.dss_clk, fck); 634 635 return func(fck, data); 636 } 637 638 fckd_hw_max = dss.feat->fck_div_max; 639 640 m = dss.feat->dss_fck_multiplier; 641 prate = clk_get_rate(dss.parent_clk); 642 643 fck_min = fck_min ? fck_min : 1; 644 645 fckd_start = min(prate * m / fck_min, fckd_hw_max); 646 fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul); 647 648 for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { 649 fck = DIV_ROUND_UP(prate, fckd) * m; 650 651 if (func(fck, data)) 652 return true; 653 } 654 655 return false; 656 } 657 658 int dss_set_fck_rate(unsigned long rate) 659 { 660 int r; 661 662 DSSDBG("set fck to %lu\n", rate); 663 664 r = clk_set_rate(dss.dss_clk, rate); 665 if (r) 666 return r; 667 668 dss.dss_clk_rate = clk_get_rate(dss.dss_clk); 669 670 WARN_ONCE(dss.dss_clk_rate != rate, 671 "clk rate mismatch: %lu != %lu", dss.dss_clk_rate, 672 rate); 673 674 return 0; 675 } 676 677 unsigned long dss_get_dispc_clk_rate(void) 678 { 679 return dss.dss_clk_rate; 680 } 681 682 unsigned long dss_get_max_fck_rate(void) 683 { 684 return dss.feat->fck_freq_max; 685 } 686 687 enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel) 688 { 689 return dss.feat->outputs[channel]; 690 } 691 692 static int dss_setup_default_clock(void) 693 { 694 unsigned long max_dss_fck, prate; 695 unsigned long fck; 696 unsigned fck_div; 697 int r; 698 699 max_dss_fck = dss.feat->fck_freq_max; 700 701 if (dss.parent_clk == NULL) { 702 fck = clk_round_rate(dss.dss_clk, max_dss_fck); 703 } else { 704 prate = clk_get_rate(dss.parent_clk); 705 706 fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, 707 max_dss_fck); 708 fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier; 709 } 710 711 r = dss_set_fck_rate(fck); 712 if (r) 713 return r; 714 715 return 0; 716 } 717 718 void dss_set_venc_output(enum omap_dss_venc_type type) 719 { 720 int l = 0; 721 722 if (type == OMAP_DSS_VENC_TYPE_COMPOSITE) 723 l = 0; 724 else if (type == OMAP_DSS_VENC_TYPE_SVIDEO) 725 l = 1; 726 else 727 BUG(); 728 729 /* venc out selection. 0 = comp, 1 = svideo */ 730 REG_FLD_MOD(DSS_CONTROL, l, 6, 6); 731 } 732 733 void dss_set_dac_pwrdn_bgz(bool enable) 734 { 735 REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ 736 } 737 738 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src) 739 { 740 enum omap_dss_output_id outputs; 741 742 outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT]; 743 744 /* Complain about invalid selections */ 745 WARN_ON((src == DSS_VENC_TV_CLK) && !(outputs & OMAP_DSS_OUTPUT_VENC)); 746 WARN_ON((src == DSS_HDMI_M_PCLK) && !(outputs & OMAP_DSS_OUTPUT_HDMI)); 747 748 /* Select only if we have options */ 749 if ((outputs & OMAP_DSS_OUTPUT_VENC) && 750 (outputs & OMAP_DSS_OUTPUT_HDMI)) 751 REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */ 752 } 753 754 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void) 755 { 756 enum omap_dss_output_id outputs; 757 758 outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT]; 759 if ((outputs & OMAP_DSS_OUTPUT_HDMI) == 0) 760 return DSS_VENC_TV_CLK; 761 762 if ((outputs & OMAP_DSS_OUTPUT_VENC) == 0) 763 return DSS_HDMI_M_PCLK; 764 765 return REG_GET(DSS_CONTROL, 15, 15); 766 } 767 768 static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel) 769 { 770 if (channel != OMAP_DSS_CHANNEL_LCD) 771 return -EINVAL; 772 773 return 0; 774 } 775 776 static int dss_dpi_select_source_omap4(int port, enum omap_channel channel) 777 { 778 int val; 779 780 switch (channel) { 781 case OMAP_DSS_CHANNEL_LCD2: 782 val = 0; 783 break; 784 case OMAP_DSS_CHANNEL_DIGIT: 785 val = 1; 786 break; 787 default: 788 return -EINVAL; 789 } 790 791 REG_FLD_MOD(DSS_CONTROL, val, 17, 17); 792 793 return 0; 794 } 795 796 static int dss_dpi_select_source_omap5(int port, enum omap_channel channel) 797 { 798 int val; 799 800 switch (channel) { 801 case OMAP_DSS_CHANNEL_LCD: 802 val = 1; 803 break; 804 case OMAP_DSS_CHANNEL_LCD2: 805 val = 2; 806 break; 807 case OMAP_DSS_CHANNEL_LCD3: 808 val = 3; 809 break; 810 case OMAP_DSS_CHANNEL_DIGIT: 811 val = 0; 812 break; 813 default: 814 return -EINVAL; 815 } 816 817 REG_FLD_MOD(DSS_CONTROL, val, 17, 16); 818 819 return 0; 820 } 821 822 static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel) 823 { 824 switch (port) { 825 case 0: 826 return dss_dpi_select_source_omap5(port, channel); 827 case 1: 828 if (channel != OMAP_DSS_CHANNEL_LCD2) 829 return -EINVAL; 830 break; 831 case 2: 832 if (channel != OMAP_DSS_CHANNEL_LCD3) 833 return -EINVAL; 834 break; 835 default: 836 return -EINVAL; 837 } 838 839 return 0; 840 } 841 842 int dss_dpi_select_source(int port, enum omap_channel channel) 843 { 844 return dss.feat->ops->dpi_select_source(port, channel); 845 } 846 847 static int dss_get_clocks(void) 848 { 849 struct clk *clk; 850 851 clk = devm_clk_get(&dss.pdev->dev, "fck"); 852 if (IS_ERR(clk)) { 853 DSSERR("can't get clock fck\n"); 854 return PTR_ERR(clk); 855 } 856 857 dss.dss_clk = clk; 858 859 if (dss.feat->parent_clk_name) { 860 clk = clk_get(NULL, dss.feat->parent_clk_name); 861 if (IS_ERR(clk)) { 862 DSSERR("Failed to get %s\n", dss.feat->parent_clk_name); 863 return PTR_ERR(clk); 864 } 865 } else { 866 clk = NULL; 867 } 868 869 dss.parent_clk = clk; 870 871 return 0; 872 } 873 874 static void dss_put_clocks(void) 875 { 876 if (dss.parent_clk) 877 clk_put(dss.parent_clk); 878 } 879 880 int dss_runtime_get(void) 881 { 882 int r; 883 884 DSSDBG("dss_runtime_get\n"); 885 886 r = pm_runtime_get_sync(&dss.pdev->dev); 887 WARN_ON(r < 0); 888 return r < 0 ? r : 0; 889 } 890 891 void dss_runtime_put(void) 892 { 893 int r; 894 895 DSSDBG("dss_runtime_put\n"); 896 897 r = pm_runtime_put_sync(&dss.pdev->dev); 898 WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY); 899 } 900 901 /* DEBUGFS */ 902 #if defined(CONFIG_OMAP2_DSS_DEBUGFS) 903 static void dss_debug_dump_clocks(struct seq_file *s) 904 { 905 dss_dump_clocks(s); 906 dispc_dump_clocks(s); 907 #ifdef CONFIG_OMAP2_DSS_DSI 908 dsi_dump_clocks(s); 909 #endif 910 } 911 912 static int dss_debug_show(struct seq_file *s, void *unused) 913 { 914 void (*func)(struct seq_file *) = s->private; 915 916 func(s); 917 return 0; 918 } 919 920 static int dss_debug_open(struct inode *inode, struct file *file) 921 { 922 return single_open(file, dss_debug_show, inode->i_private); 923 } 924 925 static const struct file_operations dss_debug_fops = { 926 .open = dss_debug_open, 927 .read = seq_read, 928 .llseek = seq_lseek, 929 .release = single_release, 930 }; 931 932 static struct dentry *dss_debugfs_dir; 933 934 static int dss_initialize_debugfs(void) 935 { 936 dss_debugfs_dir = debugfs_create_dir("omapdss", NULL); 937 if (IS_ERR(dss_debugfs_dir)) { 938 int err = PTR_ERR(dss_debugfs_dir); 939 940 dss_debugfs_dir = NULL; 941 return err; 942 } 943 944 debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, 945 &dss_debug_dump_clocks, &dss_debug_fops); 946 947 return 0; 948 } 949 950 static void dss_uninitialize_debugfs(void) 951 { 952 if (dss_debugfs_dir) 953 debugfs_remove_recursive(dss_debugfs_dir); 954 } 955 956 int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) 957 { 958 struct dentry *d; 959 960 d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, 961 write, &dss_debug_fops); 962 963 return PTR_ERR_OR_ZERO(d); 964 } 965 #else /* CONFIG_OMAP2_DSS_DEBUGFS */ 966 static inline int dss_initialize_debugfs(void) 967 { 968 return 0; 969 } 970 static inline void dss_uninitialize_debugfs(void) 971 { 972 } 973 #endif /* CONFIG_OMAP2_DSS_DEBUGFS */ 974 975 static const struct dss_ops dss_ops_omap2_omap3 = { 976 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 977 }; 978 979 static const struct dss_ops dss_ops_omap4 = { 980 .dpi_select_source = &dss_dpi_select_source_omap4, 981 .select_lcd_source = &dss_lcd_clk_mux_omap4, 982 }; 983 984 static const struct dss_ops dss_ops_omap5 = { 985 .dpi_select_source = &dss_dpi_select_source_omap5, 986 .select_lcd_source = &dss_lcd_clk_mux_omap5, 987 }; 988 989 static const struct dss_ops dss_ops_dra7 = { 990 .dpi_select_source = &dss_dpi_select_source_dra7xx, 991 .select_lcd_source = &dss_lcd_clk_mux_dra7, 992 }; 993 994 static const enum omap_display_type omap2plus_ports[] = { 995 OMAP_DISPLAY_TYPE_DPI, 996 }; 997 998 static const enum omap_display_type omap34xx_ports[] = { 999 OMAP_DISPLAY_TYPE_DPI, 1000 OMAP_DISPLAY_TYPE_SDI, 1001 }; 1002 1003 static const enum omap_display_type dra7xx_ports[] = { 1004 OMAP_DISPLAY_TYPE_DPI, 1005 OMAP_DISPLAY_TYPE_DPI, 1006 OMAP_DISPLAY_TYPE_DPI, 1007 }; 1008 1009 static const enum omap_dss_output_id omap2_dss_supported_outputs[] = { 1010 /* OMAP_DSS_CHANNEL_LCD */ 1011 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, 1012 1013 /* OMAP_DSS_CHANNEL_DIGIT */ 1014 OMAP_DSS_OUTPUT_VENC, 1015 }; 1016 1017 static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = { 1018 /* OMAP_DSS_CHANNEL_LCD */ 1019 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 1020 OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1, 1021 1022 /* OMAP_DSS_CHANNEL_DIGIT */ 1023 OMAP_DSS_OUTPUT_VENC, 1024 }; 1025 1026 static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = { 1027 /* OMAP_DSS_CHANNEL_LCD */ 1028 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 1029 OMAP_DSS_OUTPUT_DSI1, 1030 1031 /* OMAP_DSS_CHANNEL_DIGIT */ 1032 OMAP_DSS_OUTPUT_VENC, 1033 }; 1034 1035 static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = { 1036 /* OMAP_DSS_CHANNEL_LCD */ 1037 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, 1038 }; 1039 1040 static const enum omap_dss_output_id omap4_dss_supported_outputs[] = { 1041 /* OMAP_DSS_CHANNEL_LCD */ 1042 OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1, 1043 1044 /* OMAP_DSS_CHANNEL_DIGIT */ 1045 OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI, 1046 1047 /* OMAP_DSS_CHANNEL_LCD2 */ 1048 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 1049 OMAP_DSS_OUTPUT_DSI2, 1050 }; 1051 1052 static const enum omap_dss_output_id omap5_dss_supported_outputs[] = { 1053 /* OMAP_DSS_CHANNEL_LCD */ 1054 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 1055 OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2, 1056 1057 /* OMAP_DSS_CHANNEL_DIGIT */ 1058 OMAP_DSS_OUTPUT_HDMI, 1059 1060 /* OMAP_DSS_CHANNEL_LCD2 */ 1061 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 1062 OMAP_DSS_OUTPUT_DSI1, 1063 1064 /* OMAP_DSS_CHANNEL_LCD3 */ 1065 OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI | 1066 OMAP_DSS_OUTPUT_DSI2, 1067 }; 1068 1069 static const struct dss_features omap24xx_dss_feats = { 1070 .model = DSS_MODEL_OMAP2, 1071 /* 1072 * fck div max is really 16, but the divider range has gaps. The range 1073 * from 1 to 6 has no gaps, so let's use that as a max. 1074 */ 1075 .fck_div_max = 6, 1076 .fck_freq_max = 133000000, 1077 .dss_fck_multiplier = 2, 1078 .parent_clk_name = "core_ck", 1079 .ports = omap2plus_ports, 1080 .num_ports = ARRAY_SIZE(omap2plus_ports), 1081 .outputs = omap2_dss_supported_outputs, 1082 .ops = &dss_ops_omap2_omap3, 1083 .dispc_clk_switch = { 0, 0 }, 1084 .has_lcd_clk_src = false, 1085 }; 1086 1087 static const struct dss_features omap34xx_dss_feats = { 1088 .model = DSS_MODEL_OMAP3, 1089 .fck_div_max = 16, 1090 .fck_freq_max = 173000000, 1091 .dss_fck_multiplier = 2, 1092 .parent_clk_name = "dpll4_ck", 1093 .ports = omap34xx_ports, 1094 .outputs = omap3430_dss_supported_outputs, 1095 .num_ports = ARRAY_SIZE(omap34xx_ports), 1096 .ops = &dss_ops_omap2_omap3, 1097 .dispc_clk_switch = { 0, 0 }, 1098 .has_lcd_clk_src = false, 1099 }; 1100 1101 static const struct dss_features omap3630_dss_feats = { 1102 .model = DSS_MODEL_OMAP3, 1103 .fck_div_max = 32, 1104 .fck_freq_max = 173000000, 1105 .dss_fck_multiplier = 1, 1106 .parent_clk_name = "dpll4_ck", 1107 .ports = omap2plus_ports, 1108 .num_ports = ARRAY_SIZE(omap2plus_ports), 1109 .outputs = omap3630_dss_supported_outputs, 1110 .ops = &dss_ops_omap2_omap3, 1111 .dispc_clk_switch = { 0, 0 }, 1112 .has_lcd_clk_src = false, 1113 }; 1114 1115 static const struct dss_features omap44xx_dss_feats = { 1116 .model = DSS_MODEL_OMAP4, 1117 .fck_div_max = 32, 1118 .fck_freq_max = 186000000, 1119 .dss_fck_multiplier = 1, 1120 .parent_clk_name = "dpll_per_x2_ck", 1121 .ports = omap2plus_ports, 1122 .num_ports = ARRAY_SIZE(omap2plus_ports), 1123 .outputs = omap4_dss_supported_outputs, 1124 .ops = &dss_ops_omap4, 1125 .dispc_clk_switch = { 9, 8 }, 1126 .has_lcd_clk_src = true, 1127 }; 1128 1129 static const struct dss_features omap54xx_dss_feats = { 1130 .model = DSS_MODEL_OMAP5, 1131 .fck_div_max = 64, 1132 .fck_freq_max = 209250000, 1133 .dss_fck_multiplier = 1, 1134 .parent_clk_name = "dpll_per_x2_ck", 1135 .ports = omap2plus_ports, 1136 .num_ports = ARRAY_SIZE(omap2plus_ports), 1137 .outputs = omap5_dss_supported_outputs, 1138 .ops = &dss_ops_omap5, 1139 .dispc_clk_switch = { 9, 7 }, 1140 .has_lcd_clk_src = true, 1141 }; 1142 1143 static const struct dss_features am43xx_dss_feats = { 1144 .model = DSS_MODEL_OMAP3, 1145 .fck_div_max = 0, 1146 .fck_freq_max = 200000000, 1147 .dss_fck_multiplier = 0, 1148 .parent_clk_name = NULL, 1149 .ports = omap2plus_ports, 1150 .num_ports = ARRAY_SIZE(omap2plus_ports), 1151 .outputs = am43xx_dss_supported_outputs, 1152 .ops = &dss_ops_omap2_omap3, 1153 .dispc_clk_switch = { 0, 0 }, 1154 .has_lcd_clk_src = true, 1155 }; 1156 1157 static const struct dss_features dra7xx_dss_feats = { 1158 .model = DSS_MODEL_DRA7, 1159 .fck_div_max = 64, 1160 .fck_freq_max = 209250000, 1161 .dss_fck_multiplier = 1, 1162 .parent_clk_name = "dpll_per_x2_ck", 1163 .ports = dra7xx_ports, 1164 .num_ports = ARRAY_SIZE(dra7xx_ports), 1165 .outputs = omap5_dss_supported_outputs, 1166 .ops = &dss_ops_dra7, 1167 .dispc_clk_switch = { 9, 7 }, 1168 .has_lcd_clk_src = true, 1169 }; 1170 1171 static int dss_init_ports(struct platform_device *pdev) 1172 { 1173 struct device_node *parent = pdev->dev.of_node; 1174 struct device_node *port; 1175 int i; 1176 1177 for (i = 0; i < dss.feat->num_ports; i++) { 1178 port = of_graph_get_port_by_id(parent, i); 1179 if (!port) 1180 continue; 1181 1182 switch (dss.feat->ports[i]) { 1183 case OMAP_DISPLAY_TYPE_DPI: 1184 dpi_init_port(pdev, port, dss.feat->model); 1185 break; 1186 case OMAP_DISPLAY_TYPE_SDI: 1187 sdi_init_port(pdev, port); 1188 break; 1189 default: 1190 break; 1191 } 1192 } 1193 1194 return 0; 1195 } 1196 1197 static void dss_uninit_ports(struct platform_device *pdev) 1198 { 1199 struct device_node *parent = pdev->dev.of_node; 1200 struct device_node *port; 1201 int i; 1202 1203 for (i = 0; i < dss.feat->num_ports; i++) { 1204 port = of_graph_get_port_by_id(parent, i); 1205 if (!port) 1206 continue; 1207 1208 switch (dss.feat->ports[i]) { 1209 case OMAP_DISPLAY_TYPE_DPI: 1210 dpi_uninit_port(port); 1211 break; 1212 case OMAP_DISPLAY_TYPE_SDI: 1213 sdi_uninit_port(port); 1214 break; 1215 default: 1216 break; 1217 } 1218 } 1219 } 1220 1221 static int dss_video_pll_probe(struct platform_device *pdev) 1222 { 1223 struct device_node *np = pdev->dev.of_node; 1224 struct regulator *pll_regulator; 1225 int r; 1226 1227 if (!np) 1228 return 0; 1229 1230 if (of_property_read_bool(np, "syscon-pll-ctrl")) { 1231 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np, 1232 "syscon-pll-ctrl"); 1233 if (IS_ERR(dss.syscon_pll_ctrl)) { 1234 dev_err(&pdev->dev, 1235 "failed to get syscon-pll-ctrl regmap\n"); 1236 return PTR_ERR(dss.syscon_pll_ctrl); 1237 } 1238 1239 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1, 1240 &dss.syscon_pll_ctrl_offset)) { 1241 dev_err(&pdev->dev, 1242 "failed to get syscon-pll-ctrl offset\n"); 1243 return -EINVAL; 1244 } 1245 } 1246 1247 pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video"); 1248 if (IS_ERR(pll_regulator)) { 1249 r = PTR_ERR(pll_regulator); 1250 1251 switch (r) { 1252 case -ENOENT: 1253 pll_regulator = NULL; 1254 break; 1255 1256 case -EPROBE_DEFER: 1257 return -EPROBE_DEFER; 1258 1259 default: 1260 DSSERR("can't get DPLL VDDA regulator\n"); 1261 return r; 1262 } 1263 } 1264 1265 if (of_property_match_string(np, "reg-names", "pll1") >= 0) { 1266 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator); 1267 if (IS_ERR(dss.video1_pll)) 1268 return PTR_ERR(dss.video1_pll); 1269 } 1270 1271 if (of_property_match_string(np, "reg-names", "pll2") >= 0) { 1272 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator); 1273 if (IS_ERR(dss.video2_pll)) { 1274 dss_video_pll_uninit(dss.video1_pll); 1275 return PTR_ERR(dss.video2_pll); 1276 } 1277 } 1278 1279 return 0; 1280 } 1281 1282 /* DSS HW IP initialisation */ 1283 static const struct of_device_id dss_of_match[] = { 1284 { .compatible = "ti,omap2-dss", .data = &omap24xx_dss_feats }, 1285 { .compatible = "ti,omap3-dss", .data = &omap3630_dss_feats }, 1286 { .compatible = "ti,omap4-dss", .data = &omap44xx_dss_feats }, 1287 { .compatible = "ti,omap5-dss", .data = &omap54xx_dss_feats }, 1288 { .compatible = "ti,dra7-dss", .data = &dra7xx_dss_feats }, 1289 {}, 1290 }; 1291 MODULE_DEVICE_TABLE(of, dss_of_match); 1292 1293 static const struct soc_device_attribute dss_soc_devices[] = { 1294 { .machine = "OMAP3430/3530", .data = &omap34xx_dss_feats }, 1295 { .machine = "AM35??", .data = &omap34xx_dss_feats }, 1296 { .family = "AM43xx", .data = &am43xx_dss_feats }, 1297 { /* sentinel */ } 1298 }; 1299 1300 static int dss_bind(struct device *dev) 1301 { 1302 struct platform_device *pdev = to_platform_device(dev); 1303 struct resource *dss_mem; 1304 u32 rev; 1305 int r; 1306 1307 dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); 1308 dss.base = devm_ioremap_resource(&pdev->dev, dss_mem); 1309 if (IS_ERR(dss.base)) 1310 return PTR_ERR(dss.base); 1311 1312 r = dss_get_clocks(); 1313 if (r) 1314 return r; 1315 1316 r = dss_setup_default_clock(); 1317 if (r) 1318 goto err_setup_clocks; 1319 1320 r = dss_video_pll_probe(pdev); 1321 if (r) 1322 goto err_pll_init; 1323 1324 r = dss_init_ports(pdev); 1325 if (r) 1326 goto err_init_ports; 1327 1328 pm_runtime_enable(&pdev->dev); 1329 1330 r = dss_runtime_get(); 1331 if (r) 1332 goto err_runtime_get; 1333 1334 dss.dss_clk_rate = clk_get_rate(dss.dss_clk); 1335 1336 /* Select DPLL */ 1337 REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); 1338 1339 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); 1340 1341 #ifdef CONFIG_OMAP2_DSS_VENC 1342 REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ 1343 REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ 1344 REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ 1345 #endif 1346 dss.dsi_clk_source[0] = DSS_CLK_SRC_FCK; 1347 dss.dsi_clk_source[1] = DSS_CLK_SRC_FCK; 1348 dss.dispc_clk_source = DSS_CLK_SRC_FCK; 1349 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK; 1350 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; 1351 1352 rev = dss_read_reg(DSS_REVISION); 1353 pr_info("OMAP DSS rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 1354 1355 dss_runtime_put(); 1356 1357 r = component_bind_all(&pdev->dev, NULL); 1358 if (r) 1359 goto err_component; 1360 1361 dss_debugfs_create_file("dss", dss_dump_regs); 1362 1363 pm_set_vt_switch(0); 1364 1365 omapdss_gather_components(dev); 1366 omapdss_set_is_initialized(true); 1367 1368 return 0; 1369 1370 err_component: 1371 err_runtime_get: 1372 pm_runtime_disable(&pdev->dev); 1373 dss_uninit_ports(pdev); 1374 err_init_ports: 1375 if (dss.video1_pll) 1376 dss_video_pll_uninit(dss.video1_pll); 1377 1378 if (dss.video2_pll) 1379 dss_video_pll_uninit(dss.video2_pll); 1380 err_pll_init: 1381 err_setup_clocks: 1382 dss_put_clocks(); 1383 return r; 1384 } 1385 1386 static void dss_unbind(struct device *dev) 1387 { 1388 struct platform_device *pdev = to_platform_device(dev); 1389 1390 omapdss_set_is_initialized(false); 1391 1392 component_unbind_all(&pdev->dev, NULL); 1393 1394 if (dss.video1_pll) 1395 dss_video_pll_uninit(dss.video1_pll); 1396 1397 if (dss.video2_pll) 1398 dss_video_pll_uninit(dss.video2_pll); 1399 1400 dss_uninit_ports(pdev); 1401 1402 pm_runtime_disable(&pdev->dev); 1403 1404 dss_put_clocks(); 1405 } 1406 1407 static const struct component_master_ops dss_component_ops = { 1408 .bind = dss_bind, 1409 .unbind = dss_unbind, 1410 }; 1411 1412 static int dss_component_compare(struct device *dev, void *data) 1413 { 1414 struct device *child = data; 1415 return dev == child; 1416 } 1417 1418 static int dss_add_child_component(struct device *dev, void *data) 1419 { 1420 struct component_match **match = data; 1421 1422 /* 1423 * HACK 1424 * We don't have a working driver for rfbi, so skip it here always. 1425 * Otherwise dss will never get probed successfully, as it will wait 1426 * for rfbi to get probed. 1427 */ 1428 if (strstr(dev_name(dev), "rfbi")) 1429 return 0; 1430 1431 component_match_add(dev->parent, match, dss_component_compare, dev); 1432 1433 return 0; 1434 } 1435 1436 static int dss_probe(struct platform_device *pdev) 1437 { 1438 const struct soc_device_attribute *soc; 1439 struct component_match *match = NULL; 1440 int r; 1441 1442 dss.pdev = pdev; 1443 1444 /* 1445 * The various OMAP3-based SoCs can't be told apart using the compatible 1446 * string, use SoC device matching. 1447 */ 1448 soc = soc_device_match(dss_soc_devices); 1449 if (soc) 1450 dss.feat = soc->data; 1451 else 1452 dss.feat = of_match_device(dss_of_match, &pdev->dev)->data; 1453 1454 r = dss_initialize_debugfs(); 1455 if (r) 1456 return r; 1457 1458 /* add all the child devices as components */ 1459 device_for_each_child(&pdev->dev, &match, dss_add_child_component); 1460 1461 r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match); 1462 if (r) { 1463 dss_uninitialize_debugfs(); 1464 return r; 1465 } 1466 1467 return 0; 1468 } 1469 1470 static int dss_remove(struct platform_device *pdev) 1471 { 1472 component_master_del(&pdev->dev, &dss_component_ops); 1473 1474 dss_uninitialize_debugfs(); 1475 1476 return 0; 1477 } 1478 1479 static void dss_shutdown(struct platform_device *pdev) 1480 { 1481 struct omap_dss_device *dssdev = NULL; 1482 1483 DSSDBG("shutdown\n"); 1484 1485 for_each_dss_dev(dssdev) { 1486 if (!dssdev->driver) 1487 continue; 1488 1489 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 1490 dssdev->driver->disable(dssdev); 1491 } 1492 } 1493 1494 static int dss_runtime_suspend(struct device *dev) 1495 { 1496 dss_save_context(); 1497 dss_set_min_bus_tput(dev, 0); 1498 1499 pinctrl_pm_select_sleep_state(dev); 1500 1501 return 0; 1502 } 1503 1504 static int dss_runtime_resume(struct device *dev) 1505 { 1506 int r; 1507 1508 pinctrl_pm_select_default_state(dev); 1509 1510 /* 1511 * Set an arbitrarily high tput request to ensure OPP100. 1512 * What we should really do is to make a request to stay in OPP100, 1513 * without any tput requirements, but that is not currently possible 1514 * via the PM layer. 1515 */ 1516 1517 r = dss_set_min_bus_tput(dev, 1000000000); 1518 if (r) 1519 return r; 1520 1521 dss_restore_context(); 1522 return 0; 1523 } 1524 1525 static const struct dev_pm_ops dss_pm_ops = { 1526 .runtime_suspend = dss_runtime_suspend, 1527 .runtime_resume = dss_runtime_resume, 1528 }; 1529 1530 static struct platform_driver omap_dsshw_driver = { 1531 .probe = dss_probe, 1532 .remove = dss_remove, 1533 .shutdown = dss_shutdown, 1534 .driver = { 1535 .name = "omapdss_dss", 1536 .pm = &dss_pm_ops, 1537 .of_match_table = dss_of_match, 1538 .suppress_bind_attrs = true, 1539 }, 1540 }; 1541 1542 int __init dss_init_platform_driver(void) 1543 { 1544 return platform_driver_register(&omap_dsshw_driver); 1545 } 1546 1547 void dss_uninit_platform_driver(void) 1548 { 1549 platform_driver_unregister(&omap_dsshw_driver); 1550 } 1551