1 /* 2 * Copyright (C) 2012 Texas Instruments 3 * Author: Rob Clark <robdclark@gmail.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 /* LCDC DRM driver, based on da8xx-fb */ 19 20 #include "tilcdc_drv.h" 21 #include "tilcdc_regs.h" 22 #include "tilcdc_tfp410.h" 23 #include "tilcdc_slave.h" 24 #include "tilcdc_panel.h" 25 26 #include "drm_fb_helper.h" 27 28 static LIST_HEAD(module_list); 29 30 void tilcdc_module_init(struct tilcdc_module *mod, const char *name, 31 const struct tilcdc_module_ops *funcs) 32 { 33 mod->name = name; 34 mod->funcs = funcs; 35 INIT_LIST_HEAD(&mod->list); 36 list_add(&mod->list, &module_list); 37 } 38 39 void tilcdc_module_cleanup(struct tilcdc_module *mod) 40 { 41 list_del(&mod->list); 42 } 43 44 static struct of_device_id tilcdc_of_match[]; 45 46 static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev, 47 struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) 48 { 49 return drm_fb_cma_create(dev, file_priv, mode_cmd); 50 } 51 52 static void tilcdc_fb_output_poll_changed(struct drm_device *dev) 53 { 54 struct tilcdc_drm_private *priv = dev->dev_private; 55 if (priv->fbdev) 56 drm_fbdev_cma_hotplug_event(priv->fbdev); 57 } 58 59 static const struct drm_mode_config_funcs mode_config_funcs = { 60 .fb_create = tilcdc_fb_create, 61 .output_poll_changed = tilcdc_fb_output_poll_changed, 62 }; 63 64 static int modeset_init(struct drm_device *dev) 65 { 66 struct tilcdc_drm_private *priv = dev->dev_private; 67 struct tilcdc_module *mod; 68 69 drm_mode_config_init(dev); 70 71 priv->crtc = tilcdc_crtc_create(dev); 72 73 list_for_each_entry(mod, &module_list, list) { 74 DBG("loading module: %s", mod->name); 75 mod->funcs->modeset_init(mod, dev); 76 } 77 78 if ((priv->num_encoders = 0) || (priv->num_connectors == 0)) { 79 /* oh nos! */ 80 dev_err(dev->dev, "no encoders/connectors found\n"); 81 return -ENXIO; 82 } 83 84 dev->mode_config.min_width = 0; 85 dev->mode_config.min_height = 0; 86 dev->mode_config.max_width = tilcdc_crtc_max_width(priv->crtc); 87 dev->mode_config.max_height = 2048; 88 dev->mode_config.funcs = &mode_config_funcs; 89 90 return 0; 91 } 92 93 #ifdef CONFIG_CPU_FREQ 94 static int cpufreq_transition(struct notifier_block *nb, 95 unsigned long val, void *data) 96 { 97 struct tilcdc_drm_private *priv = container_of(nb, 98 struct tilcdc_drm_private, freq_transition); 99 if (val == CPUFREQ_POSTCHANGE) { 100 if (priv->lcd_fck_rate != clk_get_rate(priv->clk)) { 101 priv->lcd_fck_rate = clk_get_rate(priv->clk); 102 tilcdc_crtc_update_clk(priv->crtc); 103 } 104 } 105 106 return 0; 107 } 108 #endif 109 110 /* 111 * DRM operations: 112 */ 113 114 static int tilcdc_unload(struct drm_device *dev) 115 { 116 struct tilcdc_drm_private *priv = dev->dev_private; 117 struct tilcdc_module *mod, *cur; 118 119 drm_kms_helper_poll_fini(dev); 120 drm_mode_config_cleanup(dev); 121 drm_vblank_cleanup(dev); 122 123 pm_runtime_get_sync(dev->dev); 124 drm_irq_uninstall(dev); 125 pm_runtime_put_sync(dev->dev); 126 127 #ifdef CONFIG_CPU_FREQ 128 cpufreq_unregister_notifier(&priv->freq_transition, 129 CPUFREQ_TRANSITION_NOTIFIER); 130 #endif 131 132 if (priv->clk) 133 clk_put(priv->clk); 134 135 if (priv->mmio) 136 iounmap(priv->mmio); 137 138 flush_workqueue(priv->wq); 139 destroy_workqueue(priv->wq); 140 141 dev->dev_private = NULL; 142 143 pm_runtime_disable(dev->dev); 144 145 list_for_each_entry_safe(mod, cur, &module_list, list) { 146 DBG("destroying module: %s", mod->name); 147 mod->funcs->destroy(mod); 148 } 149 150 kfree(priv); 151 152 return 0; 153 } 154 155 static int tilcdc_load(struct drm_device *dev, unsigned long flags) 156 { 157 struct platform_device *pdev = dev->platformdev; 158 struct device_node *node = pdev->dev.of_node; 159 struct tilcdc_drm_private *priv; 160 struct resource *res; 161 int ret; 162 163 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 164 if (!priv) { 165 dev_err(dev->dev, "failed to allocate private data\n"); 166 return -ENOMEM; 167 } 168 169 dev->dev_private = priv; 170 171 priv->wq = alloc_ordered_workqueue("tilcdc", 0); 172 173 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 174 if (!res) { 175 dev_err(dev->dev, "failed to get memory resource\n"); 176 ret = -EINVAL; 177 goto fail; 178 } 179 180 priv->mmio = ioremap_nocache(res->start, resource_size(res)); 181 if (!priv->mmio) { 182 dev_err(dev->dev, "failed to ioremap\n"); 183 ret = -ENOMEM; 184 goto fail; 185 } 186 187 priv->clk = clk_get(dev->dev, "fck"); 188 if (IS_ERR(priv->clk)) { 189 dev_err(dev->dev, "failed to get functional clock\n"); 190 ret = -ENODEV; 191 goto fail; 192 } 193 194 priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); 195 if (IS_ERR(priv->clk)) { 196 dev_err(dev->dev, "failed to get display clock\n"); 197 ret = -ENODEV; 198 goto fail; 199 } 200 201 #ifdef CONFIG_CPU_FREQ 202 priv->lcd_fck_rate = clk_get_rate(priv->clk); 203 priv->freq_transition.notifier_call = cpufreq_transition; 204 ret = cpufreq_register_notifier(&priv->freq_transition, 205 CPUFREQ_TRANSITION_NOTIFIER); 206 if (ret) { 207 dev_err(dev->dev, "failed to register cpufreq notifier\n"); 208 goto fail; 209 } 210 #endif 211 212 if (of_property_read_u32(node, "max-bandwidth", &priv->max_bandwidth)) 213 priv->max_bandwidth = 1280 * 1024 * 60; 214 215 pm_runtime_enable(dev->dev); 216 217 /* Determine LCD IP Version */ 218 pm_runtime_get_sync(dev->dev); 219 switch (tilcdc_read(dev, LCDC_PID_REG)) { 220 case 0x4c100102: 221 priv->rev = 1; 222 break; 223 case 0x4f200800: 224 case 0x4f201000: 225 priv->rev = 2; 226 break; 227 default: 228 dev_warn(dev->dev, "Unknown PID Reg value 0x%08x, " 229 "defaulting to LCD revision 1\n", 230 tilcdc_read(dev, LCDC_PID_REG)); 231 priv->rev = 1; 232 break; 233 } 234 235 pm_runtime_put_sync(dev->dev); 236 237 ret = modeset_init(dev); 238 if (ret < 0) { 239 dev_err(dev->dev, "failed to initialize mode setting\n"); 240 goto fail; 241 } 242 243 ret = drm_vblank_init(dev, 1); 244 if (ret < 0) { 245 dev_err(dev->dev, "failed to initialize vblank\n"); 246 goto fail; 247 } 248 249 pm_runtime_get_sync(dev->dev); 250 ret = drm_irq_install(dev); 251 pm_runtime_put_sync(dev->dev); 252 if (ret < 0) { 253 dev_err(dev->dev, "failed to install IRQ handler\n"); 254 goto fail; 255 } 256 257 platform_set_drvdata(pdev, dev); 258 259 priv->fbdev = drm_fbdev_cma_init(dev, 16, 260 dev->mode_config.num_crtc, 261 dev->mode_config.num_connector); 262 263 drm_kms_helper_poll_init(dev); 264 265 return 0; 266 267 fail: 268 tilcdc_unload(dev); 269 return ret; 270 } 271 272 static void tilcdc_preclose(struct drm_device *dev, struct drm_file *file) 273 { 274 struct tilcdc_drm_private *priv = dev->dev_private; 275 276 tilcdc_crtc_cancel_page_flip(priv->crtc, file); 277 } 278 279 static void tilcdc_lastclose(struct drm_device *dev) 280 { 281 struct tilcdc_drm_private *priv = dev->dev_private; 282 drm_fbdev_cma_restore_mode(priv->fbdev); 283 } 284 285 static irqreturn_t tilcdc_irq(DRM_IRQ_ARGS) 286 { 287 struct drm_device *dev = arg; 288 struct tilcdc_drm_private *priv = dev->dev_private; 289 return tilcdc_crtc_irq(priv->crtc); 290 } 291 292 static void tilcdc_irq_preinstall(struct drm_device *dev) 293 { 294 tilcdc_clear_irqstatus(dev, 0xffffffff); 295 } 296 297 static int tilcdc_irq_postinstall(struct drm_device *dev) 298 { 299 struct tilcdc_drm_private *priv = dev->dev_private; 300 301 /* enable FIFO underflow irq: */ 302 if (priv->rev == 1) { 303 tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA); 304 } else { 305 tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA); 306 } 307 308 return 0; 309 } 310 311 static void tilcdc_irq_uninstall(struct drm_device *dev) 312 { 313 struct tilcdc_drm_private *priv = dev->dev_private; 314 315 /* disable irqs that we might have enabled: */ 316 if (priv->rev == 1) { 317 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, 318 LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA); 319 tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_V1_END_OF_FRAME_INT_ENA); 320 } else { 321 tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, 322 LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | 323 LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_V2_END_OF_FRAME1_INT_ENA | 324 LCDC_FRAME_DONE); 325 } 326 327 } 328 329 static void enable_vblank(struct drm_device *dev, bool enable) 330 { 331 struct tilcdc_drm_private *priv = dev->dev_private; 332 u32 reg, mask; 333 334 if (priv->rev == 1) { 335 reg = LCDC_DMA_CTRL_REG; 336 mask = LCDC_V1_END_OF_FRAME_INT_ENA; 337 } else { 338 reg = LCDC_INT_ENABLE_SET_REG; 339 mask = LCDC_V2_END_OF_FRAME0_INT_ENA | 340 LCDC_V2_END_OF_FRAME1_INT_ENA | LCDC_FRAME_DONE; 341 } 342 343 if (enable) 344 tilcdc_set(dev, reg, mask); 345 else 346 tilcdc_clear(dev, reg, mask); 347 } 348 349 static int tilcdc_enable_vblank(struct drm_device *dev, int crtc) 350 { 351 enable_vblank(dev, true); 352 return 0; 353 } 354 355 static void tilcdc_disable_vblank(struct drm_device *dev, int crtc) 356 { 357 enable_vblank(dev, false); 358 } 359 360 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PM_SLEEP) 361 static const struct { 362 const char *name; 363 uint8_t rev; 364 uint8_t save; 365 uint32_t reg; 366 } registers[] = { 367 #define REG(rev, save, reg) { #reg, rev, save, reg } 368 /* exists in revision 1: */ 369 REG(1, false, LCDC_PID_REG), 370 REG(1, true, LCDC_CTRL_REG), 371 REG(1, false, LCDC_STAT_REG), 372 REG(1, true, LCDC_RASTER_CTRL_REG), 373 REG(1, true, LCDC_RASTER_TIMING_0_REG), 374 REG(1, true, LCDC_RASTER_TIMING_1_REG), 375 REG(1, true, LCDC_RASTER_TIMING_2_REG), 376 REG(1, true, LCDC_DMA_CTRL_REG), 377 REG(1, true, LCDC_DMA_FB_BASE_ADDR_0_REG), 378 REG(1, true, LCDC_DMA_FB_CEILING_ADDR_0_REG), 379 REG(1, true, LCDC_DMA_FB_BASE_ADDR_1_REG), 380 REG(1, true, LCDC_DMA_FB_CEILING_ADDR_1_REG), 381 /* new in revision 2: */ 382 REG(2, false, LCDC_RAW_STAT_REG), 383 REG(2, false, LCDC_MASKED_STAT_REG), 384 REG(2, false, LCDC_INT_ENABLE_SET_REG), 385 REG(2, false, LCDC_INT_ENABLE_CLR_REG), 386 REG(2, false, LCDC_END_OF_INT_IND_REG), 387 REG(2, true, LCDC_CLK_ENABLE_REG), 388 REG(2, true, LCDC_INT_ENABLE_SET_REG), 389 #undef REG 390 }; 391 #endif 392 393 #ifdef CONFIG_DEBUG_FS 394 static int tilcdc_regs_show(struct seq_file *m, void *arg) 395 { 396 struct drm_info_node *node = (struct drm_info_node *) m->private; 397 struct drm_device *dev = node->minor->dev; 398 struct tilcdc_drm_private *priv = dev->dev_private; 399 unsigned i; 400 401 pm_runtime_get_sync(dev->dev); 402 403 seq_printf(m, "revision: %d\n", priv->rev); 404 405 for (i = 0; i < ARRAY_SIZE(registers); i++) 406 if (priv->rev >= registers[i].rev) 407 seq_printf(m, "%s:\t %08x\n", registers[i].name, 408 tilcdc_read(dev, registers[i].reg)); 409 410 pm_runtime_put_sync(dev->dev); 411 412 return 0; 413 } 414 415 static int tilcdc_mm_show(struct seq_file *m, void *arg) 416 { 417 struct drm_info_node *node = (struct drm_info_node *) m->private; 418 struct drm_device *dev = node->minor->dev; 419 return drm_mm_dump_table(m, dev->mm_private); 420 } 421 422 static struct drm_info_list tilcdc_debugfs_list[] = { 423 { "regs", tilcdc_regs_show, 0 }, 424 { "mm", tilcdc_mm_show, 0 }, 425 { "fb", drm_fb_cma_debugfs_show, 0 }, 426 }; 427 428 static int tilcdc_debugfs_init(struct drm_minor *minor) 429 { 430 struct drm_device *dev = minor->dev; 431 struct tilcdc_module *mod; 432 int ret; 433 434 ret = drm_debugfs_create_files(tilcdc_debugfs_list, 435 ARRAY_SIZE(tilcdc_debugfs_list), 436 minor->debugfs_root, minor); 437 438 list_for_each_entry(mod, &module_list, list) 439 if (mod->funcs->debugfs_init) 440 mod->funcs->debugfs_init(mod, minor); 441 442 if (ret) { 443 dev_err(dev->dev, "could not install tilcdc_debugfs_list\n"); 444 return ret; 445 } 446 447 return ret; 448 } 449 450 static void tilcdc_debugfs_cleanup(struct drm_minor *minor) 451 { 452 struct tilcdc_module *mod; 453 drm_debugfs_remove_files(tilcdc_debugfs_list, 454 ARRAY_SIZE(tilcdc_debugfs_list), minor); 455 456 list_for_each_entry(mod, &module_list, list) 457 if (mod->funcs->debugfs_cleanup) 458 mod->funcs->debugfs_cleanup(mod, minor); 459 } 460 #endif 461 462 static const struct file_operations fops = { 463 .owner = THIS_MODULE, 464 .open = drm_open, 465 .release = drm_release, 466 .unlocked_ioctl = drm_ioctl, 467 #ifdef CONFIG_COMPAT 468 .compat_ioctl = drm_compat_ioctl, 469 #endif 470 .poll = drm_poll, 471 .read = drm_read, 472 .fasync = drm_fasync, 473 .llseek = no_llseek, 474 .mmap = drm_gem_cma_mmap, 475 }; 476 477 static struct drm_driver tilcdc_driver = { 478 .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, 479 .load = tilcdc_load, 480 .unload = tilcdc_unload, 481 .preclose = tilcdc_preclose, 482 .lastclose = tilcdc_lastclose, 483 .irq_handler = tilcdc_irq, 484 .irq_preinstall = tilcdc_irq_preinstall, 485 .irq_postinstall = tilcdc_irq_postinstall, 486 .irq_uninstall = tilcdc_irq_uninstall, 487 .get_vblank_counter = drm_vblank_count, 488 .enable_vblank = tilcdc_enable_vblank, 489 .disable_vblank = tilcdc_disable_vblank, 490 .gem_free_object = drm_gem_cma_free_object, 491 .gem_vm_ops = &drm_gem_cma_vm_ops, 492 .dumb_create = drm_gem_cma_dumb_create, 493 .dumb_map_offset = drm_gem_cma_dumb_map_offset, 494 .dumb_destroy = drm_gem_cma_dumb_destroy, 495 #ifdef CONFIG_DEBUG_FS 496 .debugfs_init = tilcdc_debugfs_init, 497 .debugfs_cleanup = tilcdc_debugfs_cleanup, 498 #endif 499 .fops = &fops, 500 .name = "tilcdc", 501 .desc = "TI LCD Controller DRM", 502 .date = "20121205", 503 .major = 1, 504 .minor = 0, 505 }; 506 507 /* 508 * Power management: 509 */ 510 511 #ifdef CONFIG_PM_SLEEP 512 static int tilcdc_pm_suspend(struct device *dev) 513 { 514 struct drm_device *ddev = dev_get_drvdata(dev); 515 struct tilcdc_drm_private *priv = ddev->dev_private; 516 unsigned i, n = 0; 517 518 drm_kms_helper_poll_disable(ddev); 519 520 /* Save register state: */ 521 for (i = 0; i < ARRAY_SIZE(registers); i++) 522 if (registers[i].save && (priv->rev >= registers[i].rev)) 523 priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); 524 525 return 0; 526 } 527 528 static int tilcdc_pm_resume(struct device *dev) 529 { 530 struct drm_device *ddev = dev_get_drvdata(dev); 531 struct tilcdc_drm_private *priv = ddev->dev_private; 532 unsigned i, n = 0; 533 534 /* Restore register state: */ 535 for (i = 0; i < ARRAY_SIZE(registers); i++) 536 if (registers[i].save && (priv->rev >= registers[i].rev)) 537 tilcdc_write(ddev, registers[i].reg, priv->saved_register[n++]); 538 539 drm_kms_helper_poll_enable(ddev); 540 541 return 0; 542 } 543 #endif 544 545 static const struct dev_pm_ops tilcdc_pm_ops = { 546 SET_SYSTEM_SLEEP_PM_OPS(tilcdc_pm_suspend, tilcdc_pm_resume) 547 }; 548 549 /* 550 * Platform driver: 551 */ 552 553 static int tilcdc_pdev_probe(struct platform_device *pdev) 554 { 555 /* bail out early if no DT data: */ 556 if (!pdev->dev.of_node) { 557 dev_err(&pdev->dev, "device-tree data is missing\n"); 558 return -ENXIO; 559 } 560 561 return drm_platform_init(&tilcdc_driver, pdev); 562 } 563 564 static int tilcdc_pdev_remove(struct platform_device *pdev) 565 { 566 drm_platform_exit(&tilcdc_driver, pdev); 567 568 return 0; 569 } 570 571 static struct of_device_id tilcdc_of_match[] = { 572 { .compatible = "ti,am33xx-tilcdc", }, 573 { }, 574 }; 575 MODULE_DEVICE_TABLE(of, tilcdc_of_match); 576 577 static struct platform_driver tilcdc_platform_driver = { 578 .probe = tilcdc_pdev_probe, 579 .remove = tilcdc_pdev_remove, 580 .driver = { 581 .owner = THIS_MODULE, 582 .name = "tilcdc", 583 .pm = &tilcdc_pm_ops, 584 .of_match_table = tilcdc_of_match, 585 }, 586 }; 587 588 static int __init tilcdc_drm_init(void) 589 { 590 DBG("init"); 591 tilcdc_tfp410_init(); 592 tilcdc_slave_init(); 593 tilcdc_panel_init(); 594 return platform_driver_register(&tilcdc_platform_driver); 595 } 596 597 static void __exit tilcdc_drm_fini(void) 598 { 599 DBG("fini"); 600 tilcdc_tfp410_fini(); 601 tilcdc_slave_fini(); 602 tilcdc_panel_fini(); 603 platform_driver_unregister(&tilcdc_platform_driver); 604 } 605 606 late_initcall(tilcdc_drm_init); 607 module_exit(tilcdc_drm_fini); 608 609 MODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 610 MODULE_DESCRIPTION("TI LCD Controller DRM Driver"); 611 MODULE_LICENSE("GPL"); 612