1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2018 Linus Walleij <linus.walleij@linaro.org> 4 * Parts of this file were based on the MCDE driver by Marcus Lorentzon 5 * (C) ST-Ericsson SA 2013 6 */ 7 8 /** 9 * DOC: ST-Ericsson MCDE Driver 10 * 11 * The MCDE (short for multi-channel display engine) is a graphics 12 * controller found in the Ux500 chipsets, such as NovaThor U8500. 13 * It was initially conceptualized by ST Microelectronics for the 14 * successor of the Nomadik line, STn8500 but productified in the 15 * ST-Ericsson U8500 where is was used for mass-market deployments 16 * in Android phones from Samsung and Sony Ericsson. 17 * 18 * It can do 1080p30 on SDTV CCIR656, DPI-2, DBI-2 or DSI for 19 * panels with or without frame buffering and can convert most 20 * input formats including most variants of RGB and YUV. 21 * 22 * The hardware has four display pipes, and the layout is a little 23 * bit like this: 24 * 25 * Memory -> Overlay -> Channel -> FIFO -> 5 formatters -> DSI/DPI 26 * External 0..5 0..3 A,B, 3 x DSI bridge 27 * source 0..9 C0,C1 2 x DPI 28 * 29 * FIFOs A and B are for LCD and HDMI while FIFO CO/C1 are for 30 * panels with embedded buffer. 31 * 3 of the formatters are for DSI. 32 * 2 of the formatters are for DPI. 33 * 34 * Behind the formatters are the DSI or DPI ports that route to 35 * the external pins of the chip. As there are 3 DSI ports and one 36 * DPI port, it is possible to configure up to 4 display pipelines 37 * (effectively using channels 0..3) for concurrent use. 38 * 39 * In the current DRM/KMS setup, we use one external source, one overlay, 40 * one FIFO and one formatter which we connect to the simple CMA framebuffer 41 * helpers. We then provide a bridge to the DSI port, and on the DSI port 42 * bridge we connect hang a panel bridge or other bridge. This may be subject 43 * to change as we exploit more of the hardware capabilities. 44 * 45 * TODO: 46 * - Enabled damaged rectangles using drm_plane_enable_fb_damage_clips() 47 * so we can selectively just transmit the damaged area to a 48 * command-only display. 49 * - Enable mixing of more planes, possibly at the cost of moving away 50 * from using the simple framebuffer pipeline. 51 * - Enable output to bridges such as the AV8100 HDMI encoder from 52 * the DSI bridge. 53 */ 54 55 #include <linux/clk.h> 56 #include <linux/component.h> 57 #include <linux/dma-buf.h> 58 #include <linux/irq.h> 59 #include <linux/io.h> 60 #include <linux/module.h> 61 #include <linux/of_platform.h> 62 #include <linux/platform_device.h> 63 #include <linux/regulator/consumer.h> 64 #include <linux/slab.h> 65 66 #include <drm/drm_atomic_helper.h> 67 #include <drm/drm_bridge.h> 68 #include <drm/drm_drv.h> 69 #include <drm/drm_fb_cma_helper.h> 70 #include <drm/drm_fb_helper.h> 71 #include <drm/drm_gem.h> 72 #include <drm/drm_gem_cma_helper.h> 73 #include <drm/drm_gem_framebuffer_helper.h> 74 #include <drm/drm_of.h> 75 #include <drm/drm_probe_helper.h> 76 #include <drm/drm_panel.h> 77 #include <drm/drm_vblank.h> 78 79 #include "mcde_drm.h" 80 81 #define DRIVER_DESC "DRM module for MCDE" 82 83 #define MCDE_CR 0x00000000 84 #define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_SHIFT 0 85 #define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_MASK 0x0000003F 86 #define MCDE_CR_IFIFOCTRLEN BIT(15) 87 #define MCDE_CR_UFRECOVERY_MODE_V422 BIT(16) 88 #define MCDE_CR_WRAP_MODE_V422_SHIFT BIT(17) 89 #define MCDE_CR_AUTOCLKG_EN BIT(30) 90 #define MCDE_CR_MCDEEN BIT(31) 91 92 #define MCDE_CONF0 0x00000004 93 #define MCDE_CONF0_SYNCMUX0 BIT(0) 94 #define MCDE_CONF0_SYNCMUX1 BIT(1) 95 #define MCDE_CONF0_SYNCMUX2 BIT(2) 96 #define MCDE_CONF0_SYNCMUX3 BIT(3) 97 #define MCDE_CONF0_SYNCMUX4 BIT(4) 98 #define MCDE_CONF0_SYNCMUX5 BIT(5) 99 #define MCDE_CONF0_SYNCMUX6 BIT(6) 100 #define MCDE_CONF0_SYNCMUX7 BIT(7) 101 #define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT 12 102 #define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_MASK 0x00007000 103 #define MCDE_CONF0_OUTMUX0_SHIFT 16 104 #define MCDE_CONF0_OUTMUX0_MASK 0x00070000 105 #define MCDE_CONF0_OUTMUX1_SHIFT 19 106 #define MCDE_CONF0_OUTMUX1_MASK 0x00380000 107 #define MCDE_CONF0_OUTMUX2_SHIFT 22 108 #define MCDE_CONF0_OUTMUX2_MASK 0x01C00000 109 #define MCDE_CONF0_OUTMUX3_SHIFT 25 110 #define MCDE_CONF0_OUTMUX3_MASK 0x0E000000 111 #define MCDE_CONF0_OUTMUX4_SHIFT 28 112 #define MCDE_CONF0_OUTMUX4_MASK 0x70000000 113 114 #define MCDE_SSP 0x00000008 115 #define MCDE_AIS 0x00000100 116 #define MCDE_IMSCERR 0x00000110 117 #define MCDE_RISERR 0x00000120 118 #define MCDE_MISERR 0x00000130 119 #define MCDE_SISERR 0x00000140 120 121 #define MCDE_PID 0x000001FC 122 #define MCDE_PID_METALFIX_VERSION_SHIFT 0 123 #define MCDE_PID_METALFIX_VERSION_MASK 0x000000FF 124 #define MCDE_PID_DEVELOPMENT_VERSION_SHIFT 8 125 #define MCDE_PID_DEVELOPMENT_VERSION_MASK 0x0000FF00 126 #define MCDE_PID_MINOR_VERSION_SHIFT 16 127 #define MCDE_PID_MINOR_VERSION_MASK 0x00FF0000 128 #define MCDE_PID_MAJOR_VERSION_SHIFT 24 129 #define MCDE_PID_MAJOR_VERSION_MASK 0xFF000000 130 131 static const struct drm_mode_config_funcs mcde_mode_config_funcs = { 132 .fb_create = drm_gem_fb_create_with_dirty, 133 .atomic_check = drm_atomic_helper_check, 134 .atomic_commit = drm_atomic_helper_commit, 135 }; 136 137 static const struct drm_mode_config_helper_funcs mcde_mode_config_helpers = { 138 /* 139 * Using this function is necessary to commit atomic updates 140 * that need the CRTC to be enabled before a commit, as is 141 * the case with e.g. DSI displays. 142 */ 143 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, 144 }; 145 146 static irqreturn_t mcde_irq(int irq, void *data) 147 { 148 struct mcde *mcde = data; 149 u32 val; 150 151 val = readl(mcde->regs + MCDE_MISERR); 152 153 mcde_display_irq(mcde); 154 155 if (val) 156 dev_info(mcde->dev, "some error IRQ\n"); 157 writel(val, mcde->regs + MCDE_RISERR); 158 159 return IRQ_HANDLED; 160 } 161 162 static int mcde_modeset_init(struct drm_device *drm) 163 { 164 struct drm_mode_config *mode_config; 165 struct mcde *mcde = drm->dev_private; 166 int ret; 167 168 if (!mcde->bridge) { 169 dev_err(drm->dev, "no display output bridge yet\n"); 170 return -EPROBE_DEFER; 171 } 172 173 mode_config = &drm->mode_config; 174 mode_config->funcs = &mcde_mode_config_funcs; 175 mode_config->helper_private = &mcde_mode_config_helpers; 176 /* This hardware can do 1080p */ 177 mode_config->min_width = 1; 178 mode_config->max_width = 1920; 179 mode_config->min_height = 1; 180 mode_config->max_height = 1080; 181 182 /* 183 * Currently we only support vblank handling on the DSI bridge, using 184 * TE synchronization. If TE sync is not set up, it is still possible 185 * to push out a single update on demand, but this is hard for DRM to 186 * exploit. 187 */ 188 if (mcde->te_sync) { 189 ret = drm_vblank_init(drm, 1); 190 if (ret) { 191 dev_err(drm->dev, "failed to init vblank\n"); 192 goto out_config; 193 } 194 } 195 196 ret = mcde_display_init(drm); 197 if (ret) { 198 dev_err(drm->dev, "failed to init display\n"); 199 goto out_config; 200 } 201 202 /* 203 * Attach the DSI bridge 204 * 205 * TODO: when adding support for the DPI bridge or several DSI bridges, 206 * we selectively connect the bridge(s) here instead of this simple 207 * attachment. 208 */ 209 ret = drm_simple_display_pipe_attach_bridge(&mcde->pipe, 210 mcde->bridge); 211 if (ret) { 212 dev_err(drm->dev, "failed to attach display output bridge\n"); 213 goto out_config; 214 } 215 216 drm_mode_config_reset(drm); 217 drm_kms_helper_poll_init(drm); 218 drm_fbdev_generic_setup(drm, 32); 219 220 return 0; 221 222 out_config: 223 drm_mode_config_cleanup(drm); 224 return ret; 225 } 226 227 static void mcde_release(struct drm_device *drm) 228 { 229 struct mcde *mcde = drm->dev_private; 230 231 drm_mode_config_cleanup(drm); 232 drm_dev_fini(drm); 233 kfree(mcde); 234 } 235 236 DEFINE_DRM_GEM_CMA_FOPS(drm_fops); 237 238 static struct drm_driver mcde_drm_driver = { 239 .driver_features = 240 DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, 241 .release = mcde_release, 242 .lastclose = drm_fb_helper_lastclose, 243 .ioctls = NULL, 244 .fops = &drm_fops, 245 .name = "mcde", 246 .desc = DRIVER_DESC, 247 .date = "20180529", 248 .major = 1, 249 .minor = 0, 250 .patchlevel = 0, 251 .dumb_create = drm_gem_cma_dumb_create, 252 .gem_free_object_unlocked = drm_gem_cma_free_object, 253 .gem_vm_ops = &drm_gem_cma_vm_ops, 254 255 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 256 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 257 .gem_prime_import = drm_gem_prime_import, 258 .gem_prime_export = drm_gem_prime_export, 259 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 260 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 261 .gem_prime_vmap = drm_gem_cma_prime_vmap, 262 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 263 .gem_prime_mmap = drm_gem_cma_prime_mmap, 264 }; 265 266 static int mcde_drm_bind(struct device *dev) 267 { 268 struct drm_device *drm = dev_get_drvdata(dev); 269 int ret; 270 271 drm_mode_config_init(drm); 272 273 ret = component_bind_all(drm->dev, drm); 274 if (ret) { 275 dev_err(dev, "can't bind component devices\n"); 276 return ret; 277 } 278 279 ret = mcde_modeset_init(drm); 280 if (ret) 281 goto unbind; 282 283 ret = drm_dev_register(drm, 0); 284 if (ret < 0) 285 goto unbind; 286 287 return 0; 288 289 unbind: 290 component_unbind_all(drm->dev, drm); 291 return ret; 292 } 293 294 static void mcde_drm_unbind(struct device *dev) 295 { 296 struct drm_device *drm = dev_get_drvdata(dev); 297 298 drm_dev_unregister(drm); 299 drm_atomic_helper_shutdown(drm); 300 component_unbind_all(drm->dev, drm); 301 } 302 303 static const struct component_master_ops mcde_drm_comp_ops = { 304 .bind = mcde_drm_bind, 305 .unbind = mcde_drm_unbind, 306 }; 307 308 static struct platform_driver *const mcde_component_drivers[] = { 309 &mcde_dsi_driver, 310 }; 311 312 static int mcde_compare_dev(struct device *dev, void *data) 313 { 314 return dev == data; 315 } 316 317 static int mcde_probe(struct platform_device *pdev) 318 { 319 struct device *dev = &pdev->dev; 320 struct drm_device *drm; 321 struct mcde *mcde; 322 struct component_match *match; 323 struct resource *res; 324 u32 pid; 325 u32 val; 326 int irq; 327 int ret; 328 int i; 329 330 mcde = kzalloc(sizeof(*mcde), GFP_KERNEL); 331 if (!mcde) 332 return -ENOMEM; 333 mcde->dev = dev; 334 335 ret = drm_dev_init(&mcde->drm, &mcde_drm_driver, dev); 336 if (ret) { 337 kfree(mcde); 338 return ret; 339 } 340 drm = &mcde->drm; 341 drm->dev_private = mcde; 342 platform_set_drvdata(pdev, drm); 343 344 /* Enable use of the TE signal and interrupt */ 345 mcde->te_sync = true; 346 /* Enable continuous updates: this is what Linux' framebuffer expects */ 347 mcde->oneshot_mode = false; 348 drm->dev_private = mcde; 349 350 /* First obtain and turn on the main power */ 351 mcde->epod = devm_regulator_get(dev, "epod"); 352 if (IS_ERR(mcde->epod)) { 353 ret = PTR_ERR(mcde->epod); 354 dev_err(dev, "can't get EPOD regulator\n"); 355 goto dev_unref; 356 } 357 ret = regulator_enable(mcde->epod); 358 if (ret) { 359 dev_err(dev, "can't enable EPOD regulator\n"); 360 goto dev_unref; 361 } 362 mcde->vana = devm_regulator_get(dev, "vana"); 363 if (IS_ERR(mcde->vana)) { 364 ret = PTR_ERR(mcde->vana); 365 dev_err(dev, "can't get VANA regulator\n"); 366 goto regulator_epod_off; 367 } 368 ret = regulator_enable(mcde->vana); 369 if (ret) { 370 dev_err(dev, "can't enable VANA regulator\n"); 371 goto regulator_epod_off; 372 } 373 /* 374 * The vendor code uses ESRAM (onchip RAM) and need to activate 375 * the v-esram34 regulator, but we don't use that yet 376 */ 377 378 /* Clock the silicon so we can access the registers */ 379 mcde->mcde_clk = devm_clk_get(dev, "mcde"); 380 if (IS_ERR(mcde->mcde_clk)) { 381 dev_err(dev, "unable to get MCDE main clock\n"); 382 ret = PTR_ERR(mcde->mcde_clk); 383 goto regulator_off; 384 } 385 ret = clk_prepare_enable(mcde->mcde_clk); 386 if (ret) { 387 dev_err(dev, "failed to enable MCDE main clock\n"); 388 goto regulator_off; 389 } 390 dev_info(dev, "MCDE clk rate %lu Hz\n", clk_get_rate(mcde->mcde_clk)); 391 392 mcde->lcd_clk = devm_clk_get(dev, "lcd"); 393 if (IS_ERR(mcde->lcd_clk)) { 394 dev_err(dev, "unable to get LCD clock\n"); 395 ret = PTR_ERR(mcde->lcd_clk); 396 goto clk_disable; 397 } 398 mcde->hdmi_clk = devm_clk_get(dev, "hdmi"); 399 if (IS_ERR(mcde->hdmi_clk)) { 400 dev_err(dev, "unable to get HDMI clock\n"); 401 ret = PTR_ERR(mcde->hdmi_clk); 402 goto clk_disable; 403 } 404 405 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 406 mcde->regs = devm_ioremap_resource(dev, res); 407 if (IS_ERR(mcde->regs)) { 408 dev_err(dev, "no MCDE regs\n"); 409 ret = -EINVAL; 410 goto clk_disable; 411 } 412 413 irq = platform_get_irq(pdev, 0); 414 if (!irq) { 415 ret = -EINVAL; 416 goto clk_disable; 417 } 418 419 ret = devm_request_irq(dev, irq, mcde_irq, 0, "mcde", mcde); 420 if (ret) { 421 dev_err(dev, "failed to request irq %d\n", ret); 422 goto clk_disable; 423 } 424 425 /* 426 * Check hardware revision, we only support U8500v2 version 427 * as this was the only version used for mass market deployment, 428 * but surely you can add more versions if you have them and 429 * need them. 430 */ 431 pid = readl(mcde->regs + MCDE_PID); 432 dev_info(dev, "found MCDE HW revision %d.%d (dev %d, metal fix %d)\n", 433 (pid & MCDE_PID_MAJOR_VERSION_MASK) 434 >> MCDE_PID_MAJOR_VERSION_SHIFT, 435 (pid & MCDE_PID_MINOR_VERSION_MASK) 436 >> MCDE_PID_MINOR_VERSION_SHIFT, 437 (pid & MCDE_PID_DEVELOPMENT_VERSION_MASK) 438 >> MCDE_PID_DEVELOPMENT_VERSION_SHIFT, 439 (pid & MCDE_PID_METALFIX_VERSION_MASK) 440 >> MCDE_PID_METALFIX_VERSION_SHIFT); 441 if (pid != 0x03000800) { 442 dev_err(dev, "unsupported hardware revision\n"); 443 ret = -ENODEV; 444 goto clk_disable; 445 } 446 447 /* Set up the main control, watermark level at 7 */ 448 val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT; 449 /* 24 bits DPI: connect LSB Ch B to D[0:7] */ 450 val |= 3 << MCDE_CONF0_OUTMUX0_SHIFT; 451 /* TV out: connect LSB Ch B to D[8:15] */ 452 val |= 3 << MCDE_CONF0_OUTMUX1_SHIFT; 453 /* Don't care about this muxing */ 454 val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT; 455 /* 24 bits DPI: connect MID Ch B to D[24:31] */ 456 val |= 4 << MCDE_CONF0_OUTMUX3_SHIFT; 457 /* 5: 24 bits DPI: connect MSB Ch B to D[32:39] */ 458 val |= 5 << MCDE_CONF0_OUTMUX4_SHIFT; 459 /* Syncmux bits zero: DPI channel A and B on output pins A and B resp */ 460 writel(val, mcde->regs + MCDE_CONF0); 461 462 /* Enable automatic clock gating */ 463 val = readl(mcde->regs + MCDE_CR); 464 val |= MCDE_CR_MCDEEN | MCDE_CR_AUTOCLKG_EN; 465 writel(val, mcde->regs + MCDE_CR); 466 467 /* Clear any pending interrupts */ 468 mcde_display_disable_irqs(mcde); 469 writel(0, mcde->regs + MCDE_IMSCERR); 470 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR); 471 472 /* Spawn child devices for the DSI ports */ 473 devm_of_platform_populate(dev); 474 475 /* Create something that will match the subdrivers when we bind */ 476 for (i = 0; i < ARRAY_SIZE(mcde_component_drivers); i++) { 477 struct device_driver *drv = &mcde_component_drivers[i]->driver; 478 struct device *p = NULL, *d; 479 480 while ((d = bus_find_device(&platform_bus_type, p, drv, 481 (void *)platform_bus_type.match))) { 482 put_device(p); 483 component_match_add(dev, &match, mcde_compare_dev, d); 484 p = d; 485 } 486 put_device(p); 487 } 488 if (IS_ERR(match)) { 489 dev_err(dev, "could not create component match\n"); 490 ret = PTR_ERR(match); 491 goto clk_disable; 492 } 493 ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops, 494 match); 495 if (ret) { 496 dev_err(dev, "failed to add component master\n"); 497 goto clk_disable; 498 } 499 return 0; 500 501 clk_disable: 502 clk_disable_unprepare(mcde->mcde_clk); 503 regulator_off: 504 regulator_disable(mcde->vana); 505 regulator_epod_off: 506 regulator_disable(mcde->epod); 507 dev_unref: 508 drm_dev_put(drm); 509 return ret; 510 511 } 512 513 static int mcde_remove(struct platform_device *pdev) 514 { 515 struct drm_device *drm = platform_get_drvdata(pdev); 516 struct mcde *mcde = drm->dev_private; 517 518 component_master_del(&pdev->dev, &mcde_drm_comp_ops); 519 clk_disable_unprepare(mcde->mcde_clk); 520 regulator_disable(mcde->vana); 521 regulator_disable(mcde->epod); 522 drm_dev_put(drm); 523 524 return 0; 525 } 526 527 static const struct of_device_id mcde_of_match[] = { 528 { 529 .compatible = "ste,mcde", 530 }, 531 {}, 532 }; 533 534 static struct platform_driver mcde_driver = { 535 .driver = { 536 .name = "mcde", 537 .of_match_table = of_match_ptr(mcde_of_match), 538 }, 539 .probe = mcde_probe, 540 .remove = mcde_remove, 541 }; 542 543 static struct platform_driver *const component_drivers[] = { 544 &mcde_dsi_driver, 545 }; 546 547 static int __init mcde_drm_register(void) 548 { 549 int ret; 550 551 ret = platform_register_drivers(component_drivers, 552 ARRAY_SIZE(component_drivers)); 553 if (ret) 554 return ret; 555 556 return platform_driver_register(&mcde_driver); 557 } 558 559 static void __exit mcde_drm_unregister(void) 560 { 561 platform_unregister_drivers(component_drivers, 562 ARRAY_SIZE(component_drivers)); 563 platform_driver_unregister(&mcde_driver); 564 } 565 566 module_init(mcde_drm_register); 567 module_exit(mcde_drm_unregister); 568 569 MODULE_ALIAS("platform:mcde-drm"); 570 MODULE_DESCRIPTION(DRIVER_DESC); 571 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 572 MODULE_LICENSE("GPL"); 573