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 return 0; 308 } 309 310 static void tilcdc_irq_uninstall(struct drm_device *dev) 311 { 312 struct tilcdc_drm_private *priv = dev->dev_private; 313 314 /* disable irqs that we might have enabled: */ 315 if (priv->rev == 1) { 316 tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, 317 LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA); 318 tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_V1_END_OF_FRAME_INT_ENA); 319 } else { 320 tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, 321 LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | 322 LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_V2_END_OF_FRAME1_INT_ENA | 323 LCDC_FRAME_DONE); 324 } 325 326 } 327 328 static void enable_vblank(struct drm_device *dev, bool enable) 329 { 330 struct tilcdc_drm_private *priv = dev->dev_private; 331 u32 reg, mask; 332 333 if (priv->rev == 1) { 334 reg = LCDC_DMA_CTRL_REG; 335 mask = LCDC_V1_END_OF_FRAME_INT_ENA; 336 } else { 337 reg = LCDC_INT_ENABLE_SET_REG; 338 mask = LCDC_V2_END_OF_FRAME0_INT_ENA | 339 LCDC_V2_END_OF_FRAME1_INT_ENA | LCDC_FRAME_DONE; 340 } 341 342 if (enable) 343 tilcdc_set(dev, reg, mask); 344 else 345 tilcdc_clear(dev, reg, mask); 346 } 347 348 static int tilcdc_enable_vblank(struct drm_device *dev, int crtc) 349 { 350 enable_vblank(dev, true); 351 return 0; 352 } 353 354 static void tilcdc_disable_vblank(struct drm_device *dev, int crtc) 355 { 356 enable_vblank(dev, false); 357 } 358 359 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PM_SLEEP) 360 static const struct { 361 const char *name; 362 uint8_t rev; 363 uint8_t save; 364 uint32_t reg; 365 } registers[] = { 366 #define REG(rev, save, reg) { #reg, rev, save, reg } 367 /* exists in revision 1: */ 368 REG(1, false, LCDC_PID_REG), 369 REG(1, true, LCDC_CTRL_REG), 370 REG(1, false, LCDC_STAT_REG), 371 REG(1, true, LCDC_RASTER_CTRL_REG), 372 REG(1, true, LCDC_RASTER_TIMING_0_REG), 373 REG(1, true, LCDC_RASTER_TIMING_1_REG), 374 REG(1, true, LCDC_RASTER_TIMING_2_REG), 375 REG(1, true, LCDC_DMA_CTRL_REG), 376 REG(1, true, LCDC_DMA_FB_BASE_ADDR_0_REG), 377 REG(1, true, LCDC_DMA_FB_CEILING_ADDR_0_REG), 378 REG(1, true, LCDC_DMA_FB_BASE_ADDR_1_REG), 379 REG(1, true, LCDC_DMA_FB_CEILING_ADDR_1_REG), 380 /* new in revision 2: */ 381 REG(2, false, LCDC_RAW_STAT_REG), 382 REG(2, false, LCDC_MASKED_STAT_REG), 383 REG(2, false, LCDC_INT_ENABLE_SET_REG), 384 REG(2, false, LCDC_INT_ENABLE_CLR_REG), 385 REG(2, false, LCDC_END_OF_INT_IND_REG), 386 REG(2, true, LCDC_CLK_ENABLE_REG), 387 REG(2, true, LCDC_INT_ENABLE_SET_REG), 388 #undef REG 389 }; 390 #endif 391 392 #ifdef CONFIG_DEBUG_FS 393 static int tilcdc_regs_show(struct seq_file *m, void *arg) 394 { 395 struct drm_info_node *node = (struct drm_info_node *) m->private; 396 struct drm_device *dev = node->minor->dev; 397 struct tilcdc_drm_private *priv = dev->dev_private; 398 unsigned i; 399 400 pm_runtime_get_sync(dev->dev); 401 402 seq_printf(m, "revision: %d\n", priv->rev); 403 404 for (i = 0; i < ARRAY_SIZE(registers); i++) 405 if (priv->rev >= registers[i].rev) 406 seq_printf(m, "%s:\t %08x\n", registers[i].name, 407 tilcdc_read(dev, registers[i].reg)); 408 409 pm_runtime_put_sync(dev->dev); 410 411 return 0; 412 } 413 414 static int tilcdc_mm_show(struct seq_file *m, void *arg) 415 { 416 struct drm_info_node *node = (struct drm_info_node *) m->private; 417 struct drm_device *dev = node->minor->dev; 418 return drm_mm_dump_table(m, dev->mm_private); 419 } 420 421 static struct drm_info_list tilcdc_debugfs_list[] = { 422 { "regs", tilcdc_regs_show, 0 }, 423 { "mm", tilcdc_mm_show, 0 }, 424 { "fb", drm_fb_cma_debugfs_show, 0 }, 425 }; 426 427 static int tilcdc_debugfs_init(struct drm_minor *minor) 428 { 429 struct drm_device *dev = minor->dev; 430 struct tilcdc_module *mod; 431 int ret; 432 433 ret = drm_debugfs_create_files(tilcdc_debugfs_list, 434 ARRAY_SIZE(tilcdc_debugfs_list), 435 minor->debugfs_root, minor); 436 437 list_for_each_entry(mod, &module_list, list) 438 if (mod->funcs->debugfs_init) 439 mod->funcs->debugfs_init(mod, minor); 440 441 if (ret) { 442 dev_err(dev->dev, "could not install tilcdc_debugfs_list\n"); 443 return ret; 444 } 445 446 return ret; 447 } 448 449 static void tilcdc_debugfs_cleanup(struct drm_minor *minor) 450 { 451 struct tilcdc_module *mod; 452 drm_debugfs_remove_files(tilcdc_debugfs_list, 453 ARRAY_SIZE(tilcdc_debugfs_list), minor); 454 455 list_for_each_entry(mod, &module_list, list) 456 if (mod->funcs->debugfs_cleanup) 457 mod->funcs->debugfs_cleanup(mod, minor); 458 } 459 #endif 460 461 static const struct file_operations fops = { 462 .owner = THIS_MODULE, 463 .open = drm_open, 464 .release = drm_release, 465 .unlocked_ioctl = drm_ioctl, 466 #ifdef CONFIG_COMPAT 467 .compat_ioctl = drm_compat_ioctl, 468 #endif 469 .poll = drm_poll, 470 .read = drm_read, 471 .fasync = drm_fasync, 472 .llseek = no_llseek, 473 .mmap = drm_gem_cma_mmap, 474 }; 475 476 static struct drm_driver tilcdc_driver = { 477 .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, 478 .load = tilcdc_load, 479 .unload = tilcdc_unload, 480 .preclose = tilcdc_preclose, 481 .lastclose = tilcdc_lastclose, 482 .irq_handler = tilcdc_irq, 483 .irq_preinstall = tilcdc_irq_preinstall, 484 .irq_postinstall = tilcdc_irq_postinstall, 485 .irq_uninstall = tilcdc_irq_uninstall, 486 .get_vblank_counter = drm_vblank_count, 487 .enable_vblank = tilcdc_enable_vblank, 488 .disable_vblank = tilcdc_disable_vblank, 489 .gem_free_object = drm_gem_cma_free_object, 490 .gem_vm_ops = &drm_gem_cma_vm_ops, 491 .dumb_create = drm_gem_cma_dumb_create, 492 .dumb_map_offset = drm_gem_cma_dumb_map_offset, 493 .dumb_destroy = drm_gem_cma_dumb_destroy, 494 #ifdef CONFIG_DEBUG_FS 495 .debugfs_init = tilcdc_debugfs_init, 496 .debugfs_cleanup = tilcdc_debugfs_cleanup, 497 #endif 498 .fops = &fops, 499 .name = "tilcdc", 500 .desc = "TI LCD Controller DRM", 501 .date = "20121205", 502 .major = 1, 503 .minor = 0, 504 }; 505 506 /* 507 * Power management: 508 */ 509 510 #ifdef CONFIG_PM_SLEEP 511 static int tilcdc_pm_suspend(struct device *dev) 512 { 513 struct drm_device *ddev = dev_get_drvdata(dev); 514 struct tilcdc_drm_private *priv = ddev->dev_private; 515 unsigned i, n = 0; 516 517 drm_kms_helper_poll_disable(ddev); 518 519 /* Save register state: */ 520 for (i = 0; i < ARRAY_SIZE(registers); i++) 521 if (registers[i].save && (priv->rev >= registers[i].rev)) 522 priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); 523 524 return 0; 525 } 526 527 static int tilcdc_pm_resume(struct device *dev) 528 { 529 struct drm_device *ddev = dev_get_drvdata(dev); 530 struct tilcdc_drm_private *priv = ddev->dev_private; 531 unsigned i, n = 0; 532 533 /* Restore register state: */ 534 for (i = 0; i < ARRAY_SIZE(registers); i++) 535 if (registers[i].save && (priv->rev >= registers[i].rev)) 536 tilcdc_write(ddev, registers[i].reg, priv->saved_register[n++]); 537 538 drm_kms_helper_poll_enable(ddev); 539 540 return 0; 541 } 542 #endif 543 544 static const struct dev_pm_ops tilcdc_pm_ops = { 545 SET_SYSTEM_SLEEP_PM_OPS(tilcdc_pm_suspend, tilcdc_pm_resume) 546 }; 547 548 /* 549 * Platform driver: 550 */ 551 552 static int tilcdc_pdev_probe(struct platform_device *pdev) 553 { 554 /* bail out early if no DT data: */ 555 if (!pdev->dev.of_node) { 556 dev_err(&pdev->dev, "device-tree data is missing\n"); 557 return -ENXIO; 558 } 559 560 return drm_platform_init(&tilcdc_driver, pdev); 561 } 562 563 static int tilcdc_pdev_remove(struct platform_device *pdev) 564 { 565 drm_platform_exit(&tilcdc_driver, pdev); 566 567 return 0; 568 } 569 570 static struct of_device_id tilcdc_of_match[] = { 571 { .compatible = "ti,am33xx-tilcdc", }, 572 { }, 573 }; 574 MODULE_DEVICE_TABLE(of, tilcdc_of_match); 575 576 static struct platform_driver tilcdc_platform_driver = { 577 .probe = tilcdc_pdev_probe, 578 .remove = tilcdc_pdev_remove, 579 .driver = { 580 .owner = THIS_MODULE, 581 .name = "tilcdc", 582 .pm = &tilcdc_pm_ops, 583 .of_match_table = tilcdc_of_match, 584 }, 585 }; 586 587 static int __init tilcdc_drm_init(void) 588 { 589 DBG("init"); 590 tilcdc_tfp410_init(); 591 tilcdc_slave_init(); 592 tilcdc_panel_init(); 593 return platform_driver_register(&tilcdc_platform_driver); 594 } 595 596 static void __exit tilcdc_drm_fini(void) 597 { 598 DBG("fini"); 599 tilcdc_tfp410_fini(); 600 tilcdc_slave_fini(); 601 tilcdc_panel_fini(); 602 platform_driver_unregister(&tilcdc_platform_driver); 603 } 604 605 late_initcall(tilcdc_drm_init); 606 module_exit(tilcdc_drm_fini); 607 608 MODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 609 MODULE_DESCRIPTION("TI LCD Controller DRM Driver"); 610 MODULE_LICENSE("GPL"); 611