1 /* 2 * Copyright (C) 2011 Texas Instruments 3 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #define DSS_SUBSYS_NAME "APPLY" 19 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/slab.h> 23 #include <linux/spinlock.h> 24 #include <linux/jiffies.h> 25 26 #include <video/omapfb_dss.h> 27 28 #include "dss.h" 29 #include "dss_features.h" 30 #include "dispc-compat.h" 31 32 /* 33 * We have 4 levels of cache for the dispc settings. First two are in SW and 34 * the latter two in HW. 35 * 36 * set_info() 37 * v 38 * +--------------------+ 39 * | user_info | 40 * +--------------------+ 41 * v 42 * apply() 43 * v 44 * +--------------------+ 45 * | info | 46 * +--------------------+ 47 * v 48 * write_regs() 49 * v 50 * +--------------------+ 51 * | shadow registers | 52 * +--------------------+ 53 * v 54 * VFP or lcd/digit_enable 55 * v 56 * +--------------------+ 57 * | registers | 58 * +--------------------+ 59 */ 60 61 struct ovl_priv_data { 62 63 bool user_info_dirty; 64 struct omap_overlay_info user_info; 65 66 bool info_dirty; 67 struct omap_overlay_info info; 68 69 bool shadow_info_dirty; 70 71 bool extra_info_dirty; 72 bool shadow_extra_info_dirty; 73 74 bool enabled; 75 u32 fifo_low, fifo_high; 76 77 /* 78 * True if overlay is to be enabled. Used to check and calculate configs 79 * for the overlay before it is enabled in the HW. 80 */ 81 bool enabling; 82 }; 83 84 struct mgr_priv_data { 85 86 bool user_info_dirty; 87 struct omap_overlay_manager_info user_info; 88 89 bool info_dirty; 90 struct omap_overlay_manager_info info; 91 92 bool shadow_info_dirty; 93 94 /* If true, GO bit is up and shadow registers cannot be written. 95 * Never true for manual update displays */ 96 bool busy; 97 98 /* If true, dispc output is enabled */ 99 bool updating; 100 101 /* If true, a display is enabled using this manager */ 102 bool enabled; 103 104 bool extra_info_dirty; 105 bool shadow_extra_info_dirty; 106 107 struct omap_video_timings timings; 108 struct dss_lcd_mgr_config lcd_config; 109 110 void (*framedone_handler)(void *); 111 void *framedone_handler_data; 112 }; 113 114 static struct { 115 struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; 116 struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; 117 118 bool irq_enabled; 119 } dss_data; 120 121 /* protects dss_data */ 122 static spinlock_t data_lock; 123 /* lock for blocking functions */ 124 static DEFINE_MUTEX(apply_lock); 125 static DECLARE_COMPLETION(extra_updated_completion); 126 127 static void dss_register_vsync_isr(void); 128 129 static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl) 130 { 131 return &dss_data.ovl_priv_data_array[ovl->id]; 132 } 133 134 static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) 135 { 136 return &dss_data.mgr_priv_data_array[mgr->id]; 137 } 138 139 static void apply_init_priv(void) 140 { 141 const int num_ovls = dss_feat_get_num_ovls(); 142 struct mgr_priv_data *mp; 143 int i; 144 145 spin_lock_init(&data_lock); 146 147 for (i = 0; i < num_ovls; ++i) { 148 struct ovl_priv_data *op; 149 150 op = &dss_data.ovl_priv_data_array[i]; 151 152 op->info.color_mode = OMAP_DSS_COLOR_RGB16; 153 op->info.rotation_type = OMAP_DSS_ROT_DMA; 154 155 op->info.global_alpha = 255; 156 157 switch (i) { 158 case 0: 159 op->info.zorder = 0; 160 break; 161 case 1: 162 op->info.zorder = 163 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0; 164 break; 165 case 2: 166 op->info.zorder = 167 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0; 168 break; 169 case 3: 170 op->info.zorder = 171 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0; 172 break; 173 } 174 175 op->user_info = op->info; 176 } 177 178 /* 179 * Initialize some of the lcd_config fields for TV manager, this lets 180 * us prevent checking if the manager is LCD or TV at some places 181 */ 182 mp = &dss_data.mgr_priv_data_array[OMAP_DSS_CHANNEL_DIGIT]; 183 184 mp->lcd_config.video_port_width = 24; 185 mp->lcd_config.clock_info.lck_div = 1; 186 mp->lcd_config.clock_info.pck_div = 1; 187 } 188 189 /* 190 * A LCD manager's stallmode decides whether it is in manual or auto update. TV 191 * manager is always auto update, stallmode field for TV manager is false by 192 * default 193 */ 194 static bool ovl_manual_update(struct omap_overlay *ovl) 195 { 196 struct mgr_priv_data *mp = get_mgr_priv(ovl->manager); 197 198 return mp->lcd_config.stallmode; 199 } 200 201 static bool mgr_manual_update(struct omap_overlay_manager *mgr) 202 { 203 struct mgr_priv_data *mp = get_mgr_priv(mgr); 204 205 return mp->lcd_config.stallmode; 206 } 207 208 static int dss_check_settings_low(struct omap_overlay_manager *mgr, 209 bool applying) 210 { 211 struct omap_overlay_info *oi; 212 struct omap_overlay_manager_info *mi; 213 struct omap_overlay *ovl; 214 struct omap_overlay_info *ois[MAX_DSS_OVERLAYS]; 215 struct ovl_priv_data *op; 216 struct mgr_priv_data *mp; 217 218 mp = get_mgr_priv(mgr); 219 220 if (!mp->enabled) 221 return 0; 222 223 if (applying && mp->user_info_dirty) 224 mi = &mp->user_info; 225 else 226 mi = &mp->info; 227 228 /* collect the infos to be tested into the array */ 229 list_for_each_entry(ovl, &mgr->overlays, list) { 230 op = get_ovl_priv(ovl); 231 232 if (!op->enabled && !op->enabling) 233 oi = NULL; 234 else if (applying && op->user_info_dirty) 235 oi = &op->user_info; 236 else 237 oi = &op->info; 238 239 ois[ovl->id] = oi; 240 } 241 242 return dss_mgr_check(mgr, mi, &mp->timings, &mp->lcd_config, ois); 243 } 244 245 /* 246 * check manager and overlay settings using overlay_info from data->info 247 */ 248 static int dss_check_settings(struct omap_overlay_manager *mgr) 249 { 250 return dss_check_settings_low(mgr, false); 251 } 252 253 /* 254 * check manager and overlay settings using overlay_info from ovl->info if 255 * dirty and from data->info otherwise 256 */ 257 static int dss_check_settings_apply(struct omap_overlay_manager *mgr) 258 { 259 return dss_check_settings_low(mgr, true); 260 } 261 262 static bool need_isr(void) 263 { 264 const int num_mgrs = dss_feat_get_num_mgrs(); 265 int i; 266 267 for (i = 0; i < num_mgrs; ++i) { 268 struct omap_overlay_manager *mgr; 269 struct mgr_priv_data *mp; 270 struct omap_overlay *ovl; 271 272 mgr = omap_dss_get_overlay_manager(i); 273 mp = get_mgr_priv(mgr); 274 275 if (!mp->enabled) 276 continue; 277 278 if (mgr_manual_update(mgr)) { 279 /* to catch FRAMEDONE */ 280 if (mp->updating) 281 return true; 282 } else { 283 /* to catch GO bit going down */ 284 if (mp->busy) 285 return true; 286 287 /* to write new values to registers */ 288 if (mp->info_dirty) 289 return true; 290 291 /* to set GO bit */ 292 if (mp->shadow_info_dirty) 293 return true; 294 295 /* 296 * NOTE: we don't check extra_info flags for disabled 297 * managers, once the manager is enabled, the extra_info 298 * related manager changes will be taken in by HW. 299 */ 300 301 /* to write new values to registers */ 302 if (mp->extra_info_dirty) 303 return true; 304 305 /* to set GO bit */ 306 if (mp->shadow_extra_info_dirty) 307 return true; 308 309 list_for_each_entry(ovl, &mgr->overlays, list) { 310 struct ovl_priv_data *op; 311 312 op = get_ovl_priv(ovl); 313 314 /* 315 * NOTE: we check extra_info flags even for 316 * disabled overlays, as extra_infos need to be 317 * always written. 318 */ 319 320 /* to write new values to registers */ 321 if (op->extra_info_dirty) 322 return true; 323 324 /* to set GO bit */ 325 if (op->shadow_extra_info_dirty) 326 return true; 327 328 if (!op->enabled) 329 continue; 330 331 /* to write new values to registers */ 332 if (op->info_dirty) 333 return true; 334 335 /* to set GO bit */ 336 if (op->shadow_info_dirty) 337 return true; 338 } 339 } 340 } 341 342 return false; 343 } 344 345 static bool need_go(struct omap_overlay_manager *mgr) 346 { 347 struct omap_overlay *ovl; 348 struct mgr_priv_data *mp; 349 struct ovl_priv_data *op; 350 351 mp = get_mgr_priv(mgr); 352 353 if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty) 354 return true; 355 356 list_for_each_entry(ovl, &mgr->overlays, list) { 357 op = get_ovl_priv(ovl); 358 if (op->shadow_info_dirty || op->shadow_extra_info_dirty) 359 return true; 360 } 361 362 return false; 363 } 364 365 /* returns true if an extra_info field is currently being updated */ 366 static bool extra_info_update_ongoing(void) 367 { 368 const int num_mgrs = dss_feat_get_num_mgrs(); 369 int i; 370 371 for (i = 0; i < num_mgrs; ++i) { 372 struct omap_overlay_manager *mgr; 373 struct omap_overlay *ovl; 374 struct mgr_priv_data *mp; 375 376 mgr = omap_dss_get_overlay_manager(i); 377 mp = get_mgr_priv(mgr); 378 379 if (!mp->enabled) 380 continue; 381 382 if (!mp->updating) 383 continue; 384 385 if (mp->extra_info_dirty || mp->shadow_extra_info_dirty) 386 return true; 387 388 list_for_each_entry(ovl, &mgr->overlays, list) { 389 struct ovl_priv_data *op = get_ovl_priv(ovl); 390 391 if (op->extra_info_dirty || op->shadow_extra_info_dirty) 392 return true; 393 } 394 } 395 396 return false; 397 } 398 399 /* wait until no extra_info updates are pending */ 400 static void wait_pending_extra_info_updates(void) 401 { 402 bool updating; 403 unsigned long flags; 404 unsigned long t; 405 int r; 406 407 spin_lock_irqsave(&data_lock, flags); 408 409 updating = extra_info_update_ongoing(); 410 411 if (!updating) { 412 spin_unlock_irqrestore(&data_lock, flags); 413 return; 414 } 415 416 init_completion(&extra_updated_completion); 417 418 spin_unlock_irqrestore(&data_lock, flags); 419 420 t = msecs_to_jiffies(500); 421 r = wait_for_completion_timeout(&extra_updated_completion, t); 422 if (r == 0) 423 DSSWARN("timeout in wait_pending_extra_info_updates\n"); 424 } 425 426 static struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) 427 { 428 struct omap_dss_device *dssdev; 429 430 dssdev = mgr->output; 431 if (dssdev == NULL) 432 return NULL; 433 434 while (dssdev->dst) 435 dssdev = dssdev->dst; 436 437 if (dssdev->driver) 438 return dssdev; 439 else 440 return NULL; 441 } 442 443 static struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) 444 { 445 return ovl->manager ? dss_mgr_get_device(ovl->manager) : NULL; 446 } 447 448 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) 449 { 450 unsigned long timeout = msecs_to_jiffies(500); 451 u32 irq; 452 int r; 453 454 if (mgr->output == NULL) 455 return -ENODEV; 456 457 r = dispc_runtime_get(); 458 if (r) 459 return r; 460 461 switch (mgr->output->id) { 462 case OMAP_DSS_OUTPUT_VENC: 463 irq = DISPC_IRQ_EVSYNC_ODD; 464 break; 465 case OMAP_DSS_OUTPUT_HDMI: 466 irq = DISPC_IRQ_EVSYNC_EVEN; 467 break; 468 default: 469 irq = dispc_mgr_get_vsync_irq(mgr->id); 470 break; 471 } 472 473 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 474 475 dispc_runtime_put(); 476 477 return r; 478 } 479 480 static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) 481 { 482 unsigned long timeout = msecs_to_jiffies(500); 483 struct mgr_priv_data *mp = get_mgr_priv(mgr); 484 u32 irq; 485 unsigned long flags; 486 int r; 487 int i; 488 489 spin_lock_irqsave(&data_lock, flags); 490 491 if (mgr_manual_update(mgr)) { 492 spin_unlock_irqrestore(&data_lock, flags); 493 return 0; 494 } 495 496 if (!mp->enabled) { 497 spin_unlock_irqrestore(&data_lock, flags); 498 return 0; 499 } 500 501 spin_unlock_irqrestore(&data_lock, flags); 502 503 r = dispc_runtime_get(); 504 if (r) 505 return r; 506 507 irq = dispc_mgr_get_vsync_irq(mgr->id); 508 509 i = 0; 510 while (1) { 511 bool shadow_dirty, dirty; 512 513 spin_lock_irqsave(&data_lock, flags); 514 dirty = mp->info_dirty; 515 shadow_dirty = mp->shadow_info_dirty; 516 spin_unlock_irqrestore(&data_lock, flags); 517 518 if (!dirty && !shadow_dirty) { 519 r = 0; 520 break; 521 } 522 523 /* 4 iterations is the worst case: 524 * 1 - initial iteration, dirty = true (between VFP and VSYNC) 525 * 2 - first VSYNC, dirty = true 526 * 3 - dirty = false, shadow_dirty = true 527 * 4 - shadow_dirty = false */ 528 if (i++ == 3) { 529 DSSERR("mgr(%d)->wait_for_go() not finishing\n", 530 mgr->id); 531 r = 0; 532 break; 533 } 534 535 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 536 if (r == -ERESTARTSYS) 537 break; 538 539 if (r) { 540 DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id); 541 break; 542 } 543 } 544 545 dispc_runtime_put(); 546 547 return r; 548 } 549 550 static int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) 551 { 552 unsigned long timeout = msecs_to_jiffies(500); 553 struct ovl_priv_data *op; 554 struct mgr_priv_data *mp; 555 u32 irq; 556 unsigned long flags; 557 int r; 558 int i; 559 560 if (!ovl->manager) 561 return 0; 562 563 mp = get_mgr_priv(ovl->manager); 564 565 spin_lock_irqsave(&data_lock, flags); 566 567 if (ovl_manual_update(ovl)) { 568 spin_unlock_irqrestore(&data_lock, flags); 569 return 0; 570 } 571 572 if (!mp->enabled) { 573 spin_unlock_irqrestore(&data_lock, flags); 574 return 0; 575 } 576 577 spin_unlock_irqrestore(&data_lock, flags); 578 579 r = dispc_runtime_get(); 580 if (r) 581 return r; 582 583 irq = dispc_mgr_get_vsync_irq(ovl->manager->id); 584 585 op = get_ovl_priv(ovl); 586 i = 0; 587 while (1) { 588 bool shadow_dirty, dirty; 589 590 spin_lock_irqsave(&data_lock, flags); 591 dirty = op->info_dirty; 592 shadow_dirty = op->shadow_info_dirty; 593 spin_unlock_irqrestore(&data_lock, flags); 594 595 if (!dirty && !shadow_dirty) { 596 r = 0; 597 break; 598 } 599 600 /* 4 iterations is the worst case: 601 * 1 - initial iteration, dirty = true (between VFP and VSYNC) 602 * 2 - first VSYNC, dirty = true 603 * 3 - dirty = false, shadow_dirty = true 604 * 4 - shadow_dirty = false */ 605 if (i++ == 3) { 606 DSSERR("ovl(%d)->wait_for_go() not finishing\n", 607 ovl->id); 608 r = 0; 609 break; 610 } 611 612 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 613 if (r == -ERESTARTSYS) 614 break; 615 616 if (r) { 617 DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id); 618 break; 619 } 620 } 621 622 dispc_runtime_put(); 623 624 return r; 625 } 626 627 static void dss_ovl_write_regs(struct omap_overlay *ovl) 628 { 629 struct ovl_priv_data *op = get_ovl_priv(ovl); 630 struct omap_overlay_info *oi; 631 bool replication; 632 struct mgr_priv_data *mp; 633 int r; 634 635 DSSDBG("writing ovl %d regs\n", ovl->id); 636 637 if (!op->enabled || !op->info_dirty) 638 return; 639 640 oi = &op->info; 641 642 mp = get_mgr_priv(ovl->manager); 643 644 replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); 645 646 r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false); 647 if (r) { 648 /* 649 * We can't do much here, as this function can be called from 650 * vsync interrupt. 651 */ 652 DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id); 653 654 /* This will leave fifo configurations in a nonoptimal state */ 655 op->enabled = false; 656 dispc_ovl_enable(ovl->id, false); 657 return; 658 } 659 660 op->info_dirty = false; 661 if (mp->updating) 662 op->shadow_info_dirty = true; 663 } 664 665 static void dss_ovl_write_regs_extra(struct omap_overlay *ovl) 666 { 667 struct ovl_priv_data *op = get_ovl_priv(ovl); 668 struct mgr_priv_data *mp; 669 670 DSSDBG("writing ovl %d regs extra\n", ovl->id); 671 672 if (!op->extra_info_dirty) 673 return; 674 675 /* note: write also when op->enabled == false, so that the ovl gets 676 * disabled */ 677 678 dispc_ovl_enable(ovl->id, op->enabled); 679 dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high); 680 681 mp = get_mgr_priv(ovl->manager); 682 683 op->extra_info_dirty = false; 684 if (mp->updating) 685 op->shadow_extra_info_dirty = true; 686 } 687 688 static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) 689 { 690 struct mgr_priv_data *mp = get_mgr_priv(mgr); 691 struct omap_overlay *ovl; 692 693 DSSDBG("writing mgr %d regs\n", mgr->id); 694 695 if (!mp->enabled) 696 return; 697 698 WARN_ON(mp->busy); 699 700 /* Commit overlay settings */ 701 list_for_each_entry(ovl, &mgr->overlays, list) { 702 dss_ovl_write_regs(ovl); 703 dss_ovl_write_regs_extra(ovl); 704 } 705 706 if (mp->info_dirty) { 707 dispc_mgr_setup(mgr->id, &mp->info); 708 709 mp->info_dirty = false; 710 if (mp->updating) 711 mp->shadow_info_dirty = true; 712 } 713 } 714 715 static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) 716 { 717 struct mgr_priv_data *mp = get_mgr_priv(mgr); 718 719 DSSDBG("writing mgr %d regs extra\n", mgr->id); 720 721 if (!mp->extra_info_dirty) 722 return; 723 724 dispc_mgr_set_timings(mgr->id, &mp->timings); 725 726 /* lcd_config parameters */ 727 if (dss_mgr_is_lcd(mgr->id)) 728 dispc_mgr_set_lcd_config(mgr->id, &mp->lcd_config); 729 730 mp->extra_info_dirty = false; 731 if (mp->updating) 732 mp->shadow_extra_info_dirty = true; 733 } 734 735 static void dss_write_regs(void) 736 { 737 const int num_mgrs = omap_dss_get_num_overlay_managers(); 738 int i; 739 740 for (i = 0; i < num_mgrs; ++i) { 741 struct omap_overlay_manager *mgr; 742 struct mgr_priv_data *mp; 743 int r; 744 745 mgr = omap_dss_get_overlay_manager(i); 746 mp = get_mgr_priv(mgr); 747 748 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) 749 continue; 750 751 r = dss_check_settings(mgr); 752 if (r) { 753 DSSERR("cannot write registers for manager %s: " 754 "illegal configuration\n", mgr->name); 755 continue; 756 } 757 758 dss_mgr_write_regs(mgr); 759 dss_mgr_write_regs_extra(mgr); 760 } 761 } 762 763 static void dss_set_go_bits(void) 764 { 765 const int num_mgrs = omap_dss_get_num_overlay_managers(); 766 int i; 767 768 for (i = 0; i < num_mgrs; ++i) { 769 struct omap_overlay_manager *mgr; 770 struct mgr_priv_data *mp; 771 772 mgr = omap_dss_get_overlay_manager(i); 773 mp = get_mgr_priv(mgr); 774 775 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) 776 continue; 777 778 if (!need_go(mgr)) 779 continue; 780 781 mp->busy = true; 782 783 if (!dss_data.irq_enabled && need_isr()) 784 dss_register_vsync_isr(); 785 786 dispc_mgr_go(mgr->id); 787 } 788 789 } 790 791 static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr) 792 { 793 struct omap_overlay *ovl; 794 struct mgr_priv_data *mp; 795 struct ovl_priv_data *op; 796 797 mp = get_mgr_priv(mgr); 798 mp->shadow_info_dirty = false; 799 mp->shadow_extra_info_dirty = false; 800 801 list_for_each_entry(ovl, &mgr->overlays, list) { 802 op = get_ovl_priv(ovl); 803 op->shadow_info_dirty = false; 804 op->shadow_extra_info_dirty = false; 805 } 806 } 807 808 static int dss_mgr_connect_compat(struct omap_overlay_manager *mgr, 809 struct omap_dss_device *dst) 810 { 811 return mgr->set_output(mgr, dst); 812 } 813 814 static void dss_mgr_disconnect_compat(struct omap_overlay_manager *mgr, 815 struct omap_dss_device *dst) 816 { 817 mgr->unset_output(mgr); 818 } 819 820 static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr) 821 { 822 struct mgr_priv_data *mp = get_mgr_priv(mgr); 823 unsigned long flags; 824 int r; 825 826 spin_lock_irqsave(&data_lock, flags); 827 828 WARN_ON(mp->updating); 829 830 r = dss_check_settings(mgr); 831 if (r) { 832 DSSERR("cannot start manual update: illegal configuration\n"); 833 spin_unlock_irqrestore(&data_lock, flags); 834 return; 835 } 836 837 dss_mgr_write_regs(mgr); 838 dss_mgr_write_regs_extra(mgr); 839 840 mp->updating = true; 841 842 if (!dss_data.irq_enabled && need_isr()) 843 dss_register_vsync_isr(); 844 845 dispc_mgr_enable_sync(mgr->id); 846 847 spin_unlock_irqrestore(&data_lock, flags); 848 } 849 850 static void dss_apply_irq_handler(void *data, u32 mask); 851 852 static void dss_register_vsync_isr(void) 853 { 854 const int num_mgrs = dss_feat_get_num_mgrs(); 855 u32 mask; 856 int r, i; 857 858 mask = 0; 859 for (i = 0; i < num_mgrs; ++i) 860 mask |= dispc_mgr_get_vsync_irq(i); 861 862 for (i = 0; i < num_mgrs; ++i) 863 mask |= dispc_mgr_get_framedone_irq(i); 864 865 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask); 866 WARN_ON(r); 867 868 dss_data.irq_enabled = true; 869 } 870 871 static void dss_unregister_vsync_isr(void) 872 { 873 const int num_mgrs = dss_feat_get_num_mgrs(); 874 u32 mask; 875 int r, i; 876 877 mask = 0; 878 for (i = 0; i < num_mgrs; ++i) 879 mask |= dispc_mgr_get_vsync_irq(i); 880 881 for (i = 0; i < num_mgrs; ++i) 882 mask |= dispc_mgr_get_framedone_irq(i); 883 884 r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask); 885 WARN_ON(r); 886 887 dss_data.irq_enabled = false; 888 } 889 890 static void dss_apply_irq_handler(void *data, u32 mask) 891 { 892 const int num_mgrs = dss_feat_get_num_mgrs(); 893 int i; 894 bool extra_updating; 895 896 spin_lock(&data_lock); 897 898 /* clear busy, updating flags, shadow_dirty flags */ 899 for (i = 0; i < num_mgrs; i++) { 900 struct omap_overlay_manager *mgr; 901 struct mgr_priv_data *mp; 902 903 mgr = omap_dss_get_overlay_manager(i); 904 mp = get_mgr_priv(mgr); 905 906 if (!mp->enabled) 907 continue; 908 909 mp->updating = dispc_mgr_is_enabled(i); 910 911 if (!mgr_manual_update(mgr)) { 912 bool was_busy = mp->busy; 913 mp->busy = dispc_mgr_go_busy(i); 914 915 if (was_busy && !mp->busy) 916 mgr_clear_shadow_dirty(mgr); 917 } 918 } 919 920 dss_write_regs(); 921 dss_set_go_bits(); 922 923 extra_updating = extra_info_update_ongoing(); 924 if (!extra_updating) 925 complete_all(&extra_updated_completion); 926 927 /* call framedone handlers for manual update displays */ 928 for (i = 0; i < num_mgrs; i++) { 929 struct omap_overlay_manager *mgr; 930 struct mgr_priv_data *mp; 931 932 mgr = omap_dss_get_overlay_manager(i); 933 mp = get_mgr_priv(mgr); 934 935 if (!mgr_manual_update(mgr) || !mp->framedone_handler) 936 continue; 937 938 if (mask & dispc_mgr_get_framedone_irq(i)) 939 mp->framedone_handler(mp->framedone_handler_data); 940 } 941 942 if (!need_isr()) 943 dss_unregister_vsync_isr(); 944 945 spin_unlock(&data_lock); 946 } 947 948 static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) 949 { 950 struct ovl_priv_data *op; 951 952 op = get_ovl_priv(ovl); 953 954 if (!op->user_info_dirty) 955 return; 956 957 op->user_info_dirty = false; 958 op->info_dirty = true; 959 op->info = op->user_info; 960 } 961 962 static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) 963 { 964 struct mgr_priv_data *mp; 965 966 mp = get_mgr_priv(mgr); 967 968 if (!mp->user_info_dirty) 969 return; 970 971 mp->user_info_dirty = false; 972 mp->info_dirty = true; 973 mp->info = mp->user_info; 974 } 975 976 static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) 977 { 978 unsigned long flags; 979 struct omap_overlay *ovl; 980 int r; 981 982 DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); 983 984 spin_lock_irqsave(&data_lock, flags); 985 986 r = dss_check_settings_apply(mgr); 987 if (r) { 988 spin_unlock_irqrestore(&data_lock, flags); 989 DSSERR("failed to apply settings: illegal configuration.\n"); 990 return r; 991 } 992 993 /* Configure overlays */ 994 list_for_each_entry(ovl, &mgr->overlays, list) 995 omap_dss_mgr_apply_ovl(ovl); 996 997 /* Configure manager */ 998 omap_dss_mgr_apply_mgr(mgr); 999 1000 dss_write_regs(); 1001 dss_set_go_bits(); 1002 1003 spin_unlock_irqrestore(&data_lock, flags); 1004 1005 return 0; 1006 } 1007 1008 static void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable) 1009 { 1010 struct ovl_priv_data *op; 1011 1012 op = get_ovl_priv(ovl); 1013 1014 if (op->enabled == enable) 1015 return; 1016 1017 op->enabled = enable; 1018 op->extra_info_dirty = true; 1019 } 1020 1021 static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, 1022 u32 fifo_low, u32 fifo_high) 1023 { 1024 struct ovl_priv_data *op = get_ovl_priv(ovl); 1025 1026 if (op->fifo_low == fifo_low && op->fifo_high == fifo_high) 1027 return; 1028 1029 op->fifo_low = fifo_low; 1030 op->fifo_high = fifo_high; 1031 op->extra_info_dirty = true; 1032 } 1033 1034 static void dss_ovl_setup_fifo(struct omap_overlay *ovl) 1035 { 1036 struct ovl_priv_data *op = get_ovl_priv(ovl); 1037 u32 fifo_low, fifo_high; 1038 bool use_fifo_merge = false; 1039 1040 if (!op->enabled && !op->enabling) 1041 return; 1042 1043 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, 1044 use_fifo_merge, ovl_manual_update(ovl)); 1045 1046 dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); 1047 } 1048 1049 static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) 1050 { 1051 struct omap_overlay *ovl; 1052 struct mgr_priv_data *mp; 1053 1054 mp = get_mgr_priv(mgr); 1055 1056 if (!mp->enabled) 1057 return; 1058 1059 list_for_each_entry(ovl, &mgr->overlays, list) 1060 dss_ovl_setup_fifo(ovl); 1061 } 1062 1063 static void dss_setup_fifos(void) 1064 { 1065 const int num_mgrs = omap_dss_get_num_overlay_managers(); 1066 struct omap_overlay_manager *mgr; 1067 int i; 1068 1069 for (i = 0; i < num_mgrs; ++i) { 1070 mgr = omap_dss_get_overlay_manager(i); 1071 dss_mgr_setup_fifos(mgr); 1072 } 1073 } 1074 1075 static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr) 1076 { 1077 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1078 unsigned long flags; 1079 int r; 1080 1081 mutex_lock(&apply_lock); 1082 1083 if (mp->enabled) 1084 goto out; 1085 1086 spin_lock_irqsave(&data_lock, flags); 1087 1088 mp->enabled = true; 1089 1090 r = dss_check_settings(mgr); 1091 if (r) { 1092 DSSERR("failed to enable manager %d: check_settings failed\n", 1093 mgr->id); 1094 goto err; 1095 } 1096 1097 dss_setup_fifos(); 1098 1099 dss_write_regs(); 1100 dss_set_go_bits(); 1101 1102 if (!mgr_manual_update(mgr)) 1103 mp->updating = true; 1104 1105 if (!dss_data.irq_enabled && need_isr()) 1106 dss_register_vsync_isr(); 1107 1108 spin_unlock_irqrestore(&data_lock, flags); 1109 1110 if (!mgr_manual_update(mgr)) 1111 dispc_mgr_enable_sync(mgr->id); 1112 1113 out: 1114 mutex_unlock(&apply_lock); 1115 1116 return 0; 1117 1118 err: 1119 mp->enabled = false; 1120 spin_unlock_irqrestore(&data_lock, flags); 1121 mutex_unlock(&apply_lock); 1122 return r; 1123 } 1124 1125 static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr) 1126 { 1127 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1128 unsigned long flags; 1129 1130 mutex_lock(&apply_lock); 1131 1132 if (!mp->enabled) 1133 goto out; 1134 1135 wait_pending_extra_info_updates(); 1136 1137 if (!mgr_manual_update(mgr)) 1138 dispc_mgr_disable_sync(mgr->id); 1139 1140 spin_lock_irqsave(&data_lock, flags); 1141 1142 mp->updating = false; 1143 mp->enabled = false; 1144 1145 spin_unlock_irqrestore(&data_lock, flags); 1146 1147 out: 1148 mutex_unlock(&apply_lock); 1149 } 1150 1151 static int dss_mgr_set_info(struct omap_overlay_manager *mgr, 1152 struct omap_overlay_manager_info *info) 1153 { 1154 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1155 unsigned long flags; 1156 int r; 1157 1158 r = dss_mgr_simple_check(mgr, info); 1159 if (r) 1160 return r; 1161 1162 spin_lock_irqsave(&data_lock, flags); 1163 1164 mp->user_info = *info; 1165 mp->user_info_dirty = true; 1166 1167 spin_unlock_irqrestore(&data_lock, flags); 1168 1169 return 0; 1170 } 1171 1172 static void dss_mgr_get_info(struct omap_overlay_manager *mgr, 1173 struct omap_overlay_manager_info *info) 1174 { 1175 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1176 unsigned long flags; 1177 1178 spin_lock_irqsave(&data_lock, flags); 1179 1180 *info = mp->user_info; 1181 1182 spin_unlock_irqrestore(&data_lock, flags); 1183 } 1184 1185 static int dss_mgr_set_output(struct omap_overlay_manager *mgr, 1186 struct omap_dss_device *output) 1187 { 1188 int r; 1189 1190 mutex_lock(&apply_lock); 1191 1192 if (mgr->output) { 1193 DSSERR("manager %s is already connected to an output\n", 1194 mgr->name); 1195 r = -EINVAL; 1196 goto err; 1197 } 1198 1199 if ((mgr->supported_outputs & output->id) == 0) { 1200 DSSERR("output does not support manager %s\n", 1201 mgr->name); 1202 r = -EINVAL; 1203 goto err; 1204 } 1205 1206 output->manager = mgr; 1207 mgr->output = output; 1208 1209 mutex_unlock(&apply_lock); 1210 1211 return 0; 1212 err: 1213 mutex_unlock(&apply_lock); 1214 return r; 1215 } 1216 1217 static int dss_mgr_unset_output(struct omap_overlay_manager *mgr) 1218 { 1219 int r; 1220 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1221 unsigned long flags; 1222 1223 mutex_lock(&apply_lock); 1224 1225 if (!mgr->output) { 1226 DSSERR("failed to unset output, output not set\n"); 1227 r = -EINVAL; 1228 goto err; 1229 } 1230 1231 spin_lock_irqsave(&data_lock, flags); 1232 1233 if (mp->enabled) { 1234 DSSERR("output can't be unset when manager is enabled\n"); 1235 r = -EINVAL; 1236 goto err1; 1237 } 1238 1239 spin_unlock_irqrestore(&data_lock, flags); 1240 1241 mgr->output->manager = NULL; 1242 mgr->output = NULL; 1243 1244 mutex_unlock(&apply_lock); 1245 1246 return 0; 1247 err1: 1248 spin_unlock_irqrestore(&data_lock, flags); 1249 err: 1250 mutex_unlock(&apply_lock); 1251 1252 return r; 1253 } 1254 1255 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, 1256 const struct omap_video_timings *timings) 1257 { 1258 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1259 1260 mp->timings = *timings; 1261 mp->extra_info_dirty = true; 1262 } 1263 1264 static void dss_mgr_set_timings_compat(struct omap_overlay_manager *mgr, 1265 const struct omap_video_timings *timings) 1266 { 1267 unsigned long flags; 1268 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1269 1270 spin_lock_irqsave(&data_lock, flags); 1271 1272 if (mp->updating) { 1273 DSSERR("cannot set timings for %s: manager needs to be disabled\n", 1274 mgr->name); 1275 goto out; 1276 } 1277 1278 dss_apply_mgr_timings(mgr, timings); 1279 out: 1280 spin_unlock_irqrestore(&data_lock, flags); 1281 } 1282 1283 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, 1284 const struct dss_lcd_mgr_config *config) 1285 { 1286 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1287 1288 mp->lcd_config = *config; 1289 mp->extra_info_dirty = true; 1290 } 1291 1292 static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager *mgr, 1293 const struct dss_lcd_mgr_config *config) 1294 { 1295 unsigned long flags; 1296 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1297 1298 spin_lock_irqsave(&data_lock, flags); 1299 1300 if (mp->enabled) { 1301 DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n", 1302 mgr->name); 1303 goto out; 1304 } 1305 1306 dss_apply_mgr_lcd_config(mgr, config); 1307 out: 1308 spin_unlock_irqrestore(&data_lock, flags); 1309 } 1310 1311 static int dss_ovl_set_info(struct omap_overlay *ovl, 1312 struct omap_overlay_info *info) 1313 { 1314 struct ovl_priv_data *op = get_ovl_priv(ovl); 1315 unsigned long flags; 1316 int r; 1317 1318 r = dss_ovl_simple_check(ovl, info); 1319 if (r) 1320 return r; 1321 1322 spin_lock_irqsave(&data_lock, flags); 1323 1324 op->user_info = *info; 1325 op->user_info_dirty = true; 1326 1327 spin_unlock_irqrestore(&data_lock, flags); 1328 1329 return 0; 1330 } 1331 1332 static void dss_ovl_get_info(struct omap_overlay *ovl, 1333 struct omap_overlay_info *info) 1334 { 1335 struct ovl_priv_data *op = get_ovl_priv(ovl); 1336 unsigned long flags; 1337 1338 spin_lock_irqsave(&data_lock, flags); 1339 1340 *info = op->user_info; 1341 1342 spin_unlock_irqrestore(&data_lock, flags); 1343 } 1344 1345 static int dss_ovl_set_manager(struct omap_overlay *ovl, 1346 struct omap_overlay_manager *mgr) 1347 { 1348 struct ovl_priv_data *op = get_ovl_priv(ovl); 1349 unsigned long flags; 1350 int r; 1351 1352 if (!mgr) 1353 return -EINVAL; 1354 1355 mutex_lock(&apply_lock); 1356 1357 if (ovl->manager) { 1358 DSSERR("overlay '%s' already has a manager '%s'\n", 1359 ovl->name, ovl->manager->name); 1360 r = -EINVAL; 1361 goto err; 1362 } 1363 1364 r = dispc_runtime_get(); 1365 if (r) 1366 goto err; 1367 1368 spin_lock_irqsave(&data_lock, flags); 1369 1370 if (op->enabled) { 1371 spin_unlock_irqrestore(&data_lock, flags); 1372 DSSERR("overlay has to be disabled to change the manager\n"); 1373 r = -EINVAL; 1374 goto err1; 1375 } 1376 1377 dispc_ovl_set_channel_out(ovl->id, mgr->id); 1378 1379 ovl->manager = mgr; 1380 list_add_tail(&ovl->list, &mgr->overlays); 1381 1382 spin_unlock_irqrestore(&data_lock, flags); 1383 1384 dispc_runtime_put(); 1385 1386 mutex_unlock(&apply_lock); 1387 1388 return 0; 1389 1390 err1: 1391 dispc_runtime_put(); 1392 err: 1393 mutex_unlock(&apply_lock); 1394 return r; 1395 } 1396 1397 static int dss_ovl_unset_manager(struct omap_overlay *ovl) 1398 { 1399 struct ovl_priv_data *op = get_ovl_priv(ovl); 1400 unsigned long flags; 1401 int r; 1402 1403 mutex_lock(&apply_lock); 1404 1405 if (!ovl->manager) { 1406 DSSERR("failed to detach overlay: manager not set\n"); 1407 r = -EINVAL; 1408 goto err; 1409 } 1410 1411 spin_lock_irqsave(&data_lock, flags); 1412 1413 if (op->enabled) { 1414 spin_unlock_irqrestore(&data_lock, flags); 1415 DSSERR("overlay has to be disabled to unset the manager\n"); 1416 r = -EINVAL; 1417 goto err; 1418 } 1419 1420 spin_unlock_irqrestore(&data_lock, flags); 1421 1422 /* wait for pending extra_info updates to ensure the ovl is disabled */ 1423 wait_pending_extra_info_updates(); 1424 1425 /* 1426 * For a manual update display, there is no guarantee that the overlay 1427 * is really disabled in HW, we may need an extra update from this 1428 * manager before the configurations can go in. Return an error if the 1429 * overlay needed an update from the manager. 1430 * 1431 * TODO: Instead of returning an error, try to do a dummy manager update 1432 * here to disable the overlay in hardware. Use the *GATED fields in 1433 * the DISPC_CONFIG registers to do a dummy update. 1434 */ 1435 spin_lock_irqsave(&data_lock, flags); 1436 1437 if (ovl_manual_update(ovl) && op->extra_info_dirty) { 1438 spin_unlock_irqrestore(&data_lock, flags); 1439 DSSERR("need an update to change the manager\n"); 1440 r = -EINVAL; 1441 goto err; 1442 } 1443 1444 ovl->manager = NULL; 1445 list_del(&ovl->list); 1446 1447 spin_unlock_irqrestore(&data_lock, flags); 1448 1449 mutex_unlock(&apply_lock); 1450 1451 return 0; 1452 err: 1453 mutex_unlock(&apply_lock); 1454 return r; 1455 } 1456 1457 static bool dss_ovl_is_enabled(struct omap_overlay *ovl) 1458 { 1459 struct ovl_priv_data *op = get_ovl_priv(ovl); 1460 unsigned long flags; 1461 bool e; 1462 1463 spin_lock_irqsave(&data_lock, flags); 1464 1465 e = op->enabled; 1466 1467 spin_unlock_irqrestore(&data_lock, flags); 1468 1469 return e; 1470 } 1471 1472 static int dss_ovl_enable(struct omap_overlay *ovl) 1473 { 1474 struct ovl_priv_data *op = get_ovl_priv(ovl); 1475 unsigned long flags; 1476 int r; 1477 1478 mutex_lock(&apply_lock); 1479 1480 if (op->enabled) { 1481 r = 0; 1482 goto err1; 1483 } 1484 1485 if (ovl->manager == NULL || ovl->manager->output == NULL) { 1486 r = -EINVAL; 1487 goto err1; 1488 } 1489 1490 spin_lock_irqsave(&data_lock, flags); 1491 1492 op->enabling = true; 1493 1494 r = dss_check_settings(ovl->manager); 1495 if (r) { 1496 DSSERR("failed to enable overlay %d: check_settings failed\n", 1497 ovl->id); 1498 goto err2; 1499 } 1500 1501 dss_setup_fifos(); 1502 1503 op->enabling = false; 1504 dss_apply_ovl_enable(ovl, true); 1505 1506 dss_write_regs(); 1507 dss_set_go_bits(); 1508 1509 spin_unlock_irqrestore(&data_lock, flags); 1510 1511 mutex_unlock(&apply_lock); 1512 1513 return 0; 1514 err2: 1515 op->enabling = false; 1516 spin_unlock_irqrestore(&data_lock, flags); 1517 err1: 1518 mutex_unlock(&apply_lock); 1519 return r; 1520 } 1521 1522 static int dss_ovl_disable(struct omap_overlay *ovl) 1523 { 1524 struct ovl_priv_data *op = get_ovl_priv(ovl); 1525 unsigned long flags; 1526 int r; 1527 1528 mutex_lock(&apply_lock); 1529 1530 if (!op->enabled) { 1531 r = 0; 1532 goto err; 1533 } 1534 1535 if (ovl->manager == NULL || ovl->manager->output == NULL) { 1536 r = -EINVAL; 1537 goto err; 1538 } 1539 1540 spin_lock_irqsave(&data_lock, flags); 1541 1542 dss_apply_ovl_enable(ovl, false); 1543 dss_write_regs(); 1544 dss_set_go_bits(); 1545 1546 spin_unlock_irqrestore(&data_lock, flags); 1547 1548 mutex_unlock(&apply_lock); 1549 1550 return 0; 1551 1552 err: 1553 mutex_unlock(&apply_lock); 1554 return r; 1555 } 1556 1557 static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager *mgr, 1558 void (*handler)(void *), void *data) 1559 { 1560 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1561 1562 if (mp->framedone_handler) 1563 return -EBUSY; 1564 1565 mp->framedone_handler = handler; 1566 mp->framedone_handler_data = data; 1567 1568 return 0; 1569 } 1570 1571 static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager *mgr, 1572 void (*handler)(void *), void *data) 1573 { 1574 struct mgr_priv_data *mp = get_mgr_priv(mgr); 1575 1576 WARN_ON(mp->framedone_handler != handler || 1577 mp->framedone_handler_data != data); 1578 1579 mp->framedone_handler = NULL; 1580 mp->framedone_handler_data = NULL; 1581 } 1582 1583 static const struct dss_mgr_ops apply_mgr_ops = { 1584 .connect = dss_mgr_connect_compat, 1585 .disconnect = dss_mgr_disconnect_compat, 1586 .start_update = dss_mgr_start_update_compat, 1587 .enable = dss_mgr_enable_compat, 1588 .disable = dss_mgr_disable_compat, 1589 .set_timings = dss_mgr_set_timings_compat, 1590 .set_lcd_config = dss_mgr_set_lcd_config_compat, 1591 .register_framedone_handler = dss_mgr_register_framedone_handler_compat, 1592 .unregister_framedone_handler = dss_mgr_unregister_framedone_handler_compat, 1593 }; 1594 1595 static int compat_refcnt; 1596 static DEFINE_MUTEX(compat_init_lock); 1597 1598 int omapdss_compat_init(void) 1599 { 1600 struct platform_device *pdev = dss_get_core_pdev(); 1601 int i, r; 1602 1603 mutex_lock(&compat_init_lock); 1604 1605 if (compat_refcnt++ > 0) 1606 goto out; 1607 1608 apply_init_priv(); 1609 1610 dss_init_overlay_managers_sysfs(pdev); 1611 dss_init_overlays(pdev); 1612 1613 for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { 1614 struct omap_overlay_manager *mgr; 1615 1616 mgr = omap_dss_get_overlay_manager(i); 1617 1618 mgr->set_output = &dss_mgr_set_output; 1619 mgr->unset_output = &dss_mgr_unset_output; 1620 mgr->apply = &omap_dss_mgr_apply; 1621 mgr->set_manager_info = &dss_mgr_set_info; 1622 mgr->get_manager_info = &dss_mgr_get_info; 1623 mgr->wait_for_go = &dss_mgr_wait_for_go; 1624 mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; 1625 mgr->get_device = &dss_mgr_get_device; 1626 } 1627 1628 for (i = 0; i < omap_dss_get_num_overlays(); i++) { 1629 struct omap_overlay *ovl = omap_dss_get_overlay(i); 1630 1631 ovl->is_enabled = &dss_ovl_is_enabled; 1632 ovl->enable = &dss_ovl_enable; 1633 ovl->disable = &dss_ovl_disable; 1634 ovl->set_manager = &dss_ovl_set_manager; 1635 ovl->unset_manager = &dss_ovl_unset_manager; 1636 ovl->set_overlay_info = &dss_ovl_set_info; 1637 ovl->get_overlay_info = &dss_ovl_get_info; 1638 ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; 1639 ovl->get_device = &dss_ovl_get_device; 1640 } 1641 1642 r = dss_install_mgr_ops(&apply_mgr_ops); 1643 if (r) 1644 goto err_mgr_ops; 1645 1646 r = display_init_sysfs(pdev); 1647 if (r) 1648 goto err_disp_sysfs; 1649 1650 dispc_runtime_get(); 1651 1652 r = dss_dispc_initialize_irq(); 1653 if (r) 1654 goto err_init_irq; 1655 1656 dispc_runtime_put(); 1657 1658 out: 1659 mutex_unlock(&compat_init_lock); 1660 1661 return 0; 1662 1663 err_init_irq: 1664 dispc_runtime_put(); 1665 display_uninit_sysfs(pdev); 1666 1667 err_disp_sysfs: 1668 dss_uninstall_mgr_ops(); 1669 1670 err_mgr_ops: 1671 dss_uninit_overlay_managers_sysfs(pdev); 1672 dss_uninit_overlays(pdev); 1673 1674 compat_refcnt--; 1675 1676 mutex_unlock(&compat_init_lock); 1677 1678 return r; 1679 } 1680 EXPORT_SYMBOL(omapdss_compat_init); 1681 1682 void omapdss_compat_uninit(void) 1683 { 1684 struct platform_device *pdev = dss_get_core_pdev(); 1685 1686 mutex_lock(&compat_init_lock); 1687 1688 if (--compat_refcnt > 0) 1689 goto out; 1690 1691 dss_dispc_uninitialize_irq(); 1692 1693 display_uninit_sysfs(pdev); 1694 1695 dss_uninstall_mgr_ops(); 1696 1697 dss_uninit_overlay_managers_sysfs(pdev); 1698 dss_uninit_overlays(pdev); 1699 out: 1700 mutex_unlock(&compat_init_lock); 1701 } 1702 EXPORT_SYMBOL(omapdss_compat_uninit); 1703