1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 4 * Author:Mark Yao <mark.yao@rock-chips.com> 5 * 6 * based on exynos_drm_drv.c 7 */ 8 9 #include <linux/dma-mapping.h> 10 #include <linux/platform_device.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/module.h> 13 #include <linux/of_graph.h> 14 #include <linux/of_platform.h> 15 #include <linux/component.h> 16 #include <linux/console.h> 17 #include <linux/iommu.h> 18 19 #include <drm/drm_aperture.h> 20 #include <drm/drm_client_setup.h> 21 #include <drm/drm_drv.h> 22 #include <drm/drm_fbdev_dma.h> 23 #include <drm/drm_gem_dma_helper.h> 24 #include <drm/drm_of.h> 25 #include <drm/drm_probe_helper.h> 26 #include <drm/drm_vblank.h> 27 28 #if defined(CONFIG_ARM_DMA_USE_IOMMU) 29 #include <asm/dma-iommu.h> 30 #else 31 #define arm_iommu_detach_device(...) ({ }) 32 #define arm_iommu_release_mapping(...) ({ }) 33 #define to_dma_iommu_mapping(dev) NULL 34 #endif 35 36 #include "rockchip_drm_drv.h" 37 #include "rockchip_drm_fb.h" 38 #include "rockchip_drm_gem.h" 39 40 #define DRIVER_NAME "rockchip" 41 #define DRIVER_DESC "RockChip Soc DRM" 42 #define DRIVER_DATE "20140818" 43 #define DRIVER_MAJOR 1 44 #define DRIVER_MINOR 0 45 46 static const struct drm_driver rockchip_drm_driver; 47 48 /* 49 * Attach a (component) device to the shared drm dma mapping from master drm 50 * device. This is used by the VOPs to map GEM buffers to a common DMA 51 * mapping. 52 */ 53 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, 54 struct device *dev) 55 { 56 struct rockchip_drm_private *private = drm_dev->dev_private; 57 int ret; 58 59 if (!private->domain) 60 return 0; 61 62 if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { 63 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); 64 65 if (mapping) { 66 arm_iommu_detach_device(dev); 67 arm_iommu_release_mapping(mapping); 68 } 69 } 70 71 ret = iommu_attach_device(private->domain, dev); 72 if (ret) { 73 DRM_DEV_ERROR(dev, "Failed to attach iommu device\n"); 74 return ret; 75 } 76 77 return 0; 78 } 79 80 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, 81 struct device *dev) 82 { 83 struct rockchip_drm_private *private = drm_dev->dev_private; 84 85 if (!private->domain) 86 return; 87 88 iommu_detach_device(private->domain, dev); 89 } 90 91 void rockchip_drm_dma_init_device(struct drm_device *drm_dev, 92 struct device *dev) 93 { 94 struct rockchip_drm_private *private = drm_dev->dev_private; 95 96 if (!device_iommu_mapped(dev)) 97 private->iommu_dev = ERR_PTR(-ENODEV); 98 else if (!private->iommu_dev) 99 private->iommu_dev = dev; 100 } 101 102 static int rockchip_drm_init_iommu(struct drm_device *drm_dev) 103 { 104 struct rockchip_drm_private *private = drm_dev->dev_private; 105 struct iommu_domain_geometry *geometry; 106 u64 start, end; 107 108 if (IS_ERR_OR_NULL(private->iommu_dev)) 109 return 0; 110 111 private->domain = iommu_domain_alloc(private->iommu_dev->bus); 112 if (!private->domain) 113 return -ENOMEM; 114 115 geometry = &private->domain->geometry; 116 start = geometry->aperture_start; 117 end = geometry->aperture_end; 118 119 DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n", 120 start, end); 121 drm_mm_init(&private->mm, start, end - start + 1); 122 mutex_init(&private->mm_lock); 123 124 return 0; 125 } 126 127 static void rockchip_iommu_cleanup(struct drm_device *drm_dev) 128 { 129 struct rockchip_drm_private *private = drm_dev->dev_private; 130 131 if (!private->domain) 132 return; 133 134 drm_mm_takedown(&private->mm); 135 iommu_domain_free(private->domain); 136 } 137 138 static int rockchip_drm_bind(struct device *dev) 139 { 140 struct drm_device *drm_dev; 141 struct rockchip_drm_private *private; 142 int ret; 143 144 /* Remove existing drivers that may own the framebuffer memory. */ 145 ret = drm_aperture_remove_framebuffers(&rockchip_drm_driver); 146 if (ret) { 147 DRM_DEV_ERROR(dev, 148 "Failed to remove existing framebuffers - %d.\n", 149 ret); 150 return ret; 151 } 152 153 drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev); 154 if (IS_ERR(drm_dev)) 155 return PTR_ERR(drm_dev); 156 157 dev_set_drvdata(dev, drm_dev); 158 159 private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL); 160 if (!private) { 161 ret = -ENOMEM; 162 goto err_free; 163 } 164 165 drm_dev->dev_private = private; 166 167 ret = drmm_mode_config_init(drm_dev); 168 if (ret) 169 goto err_free; 170 171 rockchip_drm_mode_config_init(drm_dev); 172 173 /* Try to bind all sub drivers. */ 174 ret = component_bind_all(dev, drm_dev); 175 if (ret) 176 goto err_free; 177 178 ret = rockchip_drm_init_iommu(drm_dev); 179 if (ret) 180 goto err_unbind_all; 181 182 ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc); 183 if (ret) 184 goto err_iommu_cleanup; 185 186 drm_mode_config_reset(drm_dev); 187 188 /* init kms poll for handling hpd */ 189 drm_kms_helper_poll_init(drm_dev); 190 191 ret = drm_dev_register(drm_dev, 0); 192 if (ret) 193 goto err_kms_helper_poll_fini; 194 195 drm_client_setup(drm_dev, NULL); 196 197 return 0; 198 err_kms_helper_poll_fini: 199 drm_kms_helper_poll_fini(drm_dev); 200 err_iommu_cleanup: 201 rockchip_iommu_cleanup(drm_dev); 202 err_unbind_all: 203 component_unbind_all(dev, drm_dev); 204 err_free: 205 drm_dev_put(drm_dev); 206 return ret; 207 } 208 209 static void rockchip_drm_unbind(struct device *dev) 210 { 211 struct drm_device *drm_dev = dev_get_drvdata(dev); 212 213 drm_dev_unregister(drm_dev); 214 215 drm_kms_helper_poll_fini(drm_dev); 216 217 drm_atomic_helper_shutdown(drm_dev); 218 component_unbind_all(dev, drm_dev); 219 rockchip_iommu_cleanup(drm_dev); 220 221 drm_dev_put(drm_dev); 222 } 223 224 DEFINE_DRM_GEM_FOPS(rockchip_drm_driver_fops); 225 226 static const struct drm_driver rockchip_drm_driver = { 227 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 228 .dumb_create = rockchip_gem_dumb_create, 229 .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table, 230 DRM_FBDEV_DMA_DRIVER_OPS, 231 .fops = &rockchip_drm_driver_fops, 232 .name = DRIVER_NAME, 233 .desc = DRIVER_DESC, 234 .date = DRIVER_DATE, 235 .major = DRIVER_MAJOR, 236 .minor = DRIVER_MINOR, 237 }; 238 239 #ifdef CONFIG_PM_SLEEP 240 static int rockchip_drm_sys_suspend(struct device *dev) 241 { 242 struct drm_device *drm = dev_get_drvdata(dev); 243 244 return drm_mode_config_helper_suspend(drm); 245 } 246 247 static int rockchip_drm_sys_resume(struct device *dev) 248 { 249 struct drm_device *drm = dev_get_drvdata(dev); 250 251 return drm_mode_config_helper_resume(drm); 252 } 253 #endif 254 255 static const struct dev_pm_ops rockchip_drm_pm_ops = { 256 SET_SYSTEM_SLEEP_PM_OPS(rockchip_drm_sys_suspend, 257 rockchip_drm_sys_resume) 258 }; 259 260 #define MAX_ROCKCHIP_SUB_DRIVERS 16 261 static struct platform_driver *rockchip_sub_drivers[MAX_ROCKCHIP_SUB_DRIVERS]; 262 static int num_rockchip_sub_drivers; 263 264 /* 265 * Get the endpoint id of the remote endpoint of the given encoder. This 266 * information is used by the VOP2 driver to identify the encoder. 267 * 268 * @rkencoder: The encoder to get the remote endpoint id from 269 * @np: The encoder device node 270 * @port: The number of the port leading to the VOP2 271 * @reg: The endpoint number leading to the VOP2 272 */ 273 int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rkencoder, 274 struct device_node *np, int port, int reg) 275 { 276 struct of_endpoint ep; 277 struct device_node *en, *ren; 278 int ret; 279 280 en = of_graph_get_endpoint_by_regs(np, port, reg); 281 if (!en) 282 return -ENOENT; 283 284 ren = of_graph_get_remote_endpoint(en); 285 if (!ren) 286 return -ENOENT; 287 288 ret = of_graph_parse_endpoint(ren, &ep); 289 if (ret) 290 return ret; 291 292 rkencoder->crtc_endpoint_id = ep.id; 293 294 return 0; 295 } 296 297 /* 298 * Check if a vop endpoint is leading to a rockchip subdriver or bridge. 299 * Should be called from the component bind stage of the drivers 300 * to ensure that all subdrivers are probed. 301 * 302 * @ep: endpoint of a rockchip vop 303 * 304 * returns true if subdriver, false if external bridge and -ENODEV 305 * if remote port does not contain a device. 306 */ 307 int rockchip_drm_endpoint_is_subdriver(struct device_node *ep) 308 { 309 struct device_node *node = of_graph_get_remote_port_parent(ep); 310 struct platform_device *pdev; 311 struct device_driver *drv; 312 int i; 313 314 if (!node) 315 return -ENODEV; 316 317 /* status disabled will prevent creation of platform-devices */ 318 if (!of_device_is_available(node)) { 319 of_node_put(node); 320 return -ENODEV; 321 } 322 323 pdev = of_find_device_by_node(node); 324 of_node_put(node); 325 326 /* enabled non-platform-devices can immediately return here */ 327 if (!pdev) 328 return false; 329 330 /* 331 * All rockchip subdrivers have probed at this point, so 332 * any device not having a driver now is an external bridge. 333 */ 334 drv = pdev->dev.driver; 335 if (!drv) { 336 platform_device_put(pdev); 337 return false; 338 } 339 340 for (i = 0; i < num_rockchip_sub_drivers; i++) { 341 if (rockchip_sub_drivers[i] == to_platform_driver(drv)) { 342 platform_device_put(pdev); 343 return true; 344 } 345 } 346 347 platform_device_put(pdev); 348 return false; 349 } 350 351 static void rockchip_drm_match_remove(struct device *dev) 352 { 353 struct device_link *link; 354 355 list_for_each_entry(link, &dev->links.consumers, s_node) 356 device_link_del(link); 357 } 358 359 /* list of preferred vop devices */ 360 static const char *const rockchip_drm_match_preferred[] = { 361 "rockchip,rk3399-vop-big", 362 NULL, 363 }; 364 365 static struct component_match *rockchip_drm_match_add(struct device *dev) 366 { 367 struct component_match *match = NULL; 368 struct device_node *port; 369 int i; 370 371 /* add preferred vop device match before adding driver device matches */ 372 for (i = 0; ; i++) { 373 port = of_parse_phandle(dev->of_node, "ports", i); 374 if (!port) 375 break; 376 377 if (of_device_is_available(port->parent) && 378 of_device_compatible_match(port->parent, 379 rockchip_drm_match_preferred)) 380 drm_of_component_match_add(dev, &match, 381 component_compare_of, 382 port->parent); 383 384 of_node_put(port); 385 } 386 387 for (i = 0; i < num_rockchip_sub_drivers; i++) { 388 struct platform_driver *drv = rockchip_sub_drivers[i]; 389 struct device *p = NULL, *d; 390 391 do { 392 d = platform_find_device_by_driver(p, &drv->driver); 393 put_device(p); 394 p = d; 395 396 if (!d) 397 break; 398 399 device_link_add(dev, d, DL_FLAG_STATELESS); 400 component_match_add(dev, &match, component_compare_dev, d); 401 } while (true); 402 } 403 404 if (IS_ERR(match)) 405 rockchip_drm_match_remove(dev); 406 407 return match ?: ERR_PTR(-ENODEV); 408 } 409 410 static const struct component_master_ops rockchip_drm_ops = { 411 .bind = rockchip_drm_bind, 412 .unbind = rockchip_drm_unbind, 413 }; 414 415 static int rockchip_drm_platform_of_probe(struct device *dev) 416 { 417 struct device_node *np = dev->of_node; 418 struct device_node *port; 419 bool found = false; 420 int i; 421 422 if (!np) 423 return -ENODEV; 424 425 for (i = 0;; i++) { 426 port = of_parse_phandle(np, "ports", i); 427 if (!port) 428 break; 429 430 if (!of_device_is_available(port->parent)) { 431 of_node_put(port); 432 continue; 433 } 434 435 found = true; 436 of_node_put(port); 437 } 438 439 if (i == 0) { 440 DRM_DEV_ERROR(dev, "missing 'ports' property\n"); 441 return -ENODEV; 442 } 443 444 if (!found) { 445 DRM_DEV_ERROR(dev, 446 "No available vop found for display-subsystem.\n"); 447 return -ENODEV; 448 } 449 450 return 0; 451 } 452 453 static int rockchip_drm_platform_probe(struct platform_device *pdev) 454 { 455 struct device *dev = &pdev->dev; 456 struct component_match *match = NULL; 457 int ret; 458 459 ret = rockchip_drm_platform_of_probe(dev); 460 if (ret) 461 return ret; 462 463 match = rockchip_drm_match_add(dev); 464 if (IS_ERR(match)) 465 return PTR_ERR(match); 466 467 ret = component_master_add_with_match(dev, &rockchip_drm_ops, match); 468 if (ret < 0) { 469 rockchip_drm_match_remove(dev); 470 return ret; 471 } 472 473 return 0; 474 } 475 476 static void rockchip_drm_platform_remove(struct platform_device *pdev) 477 { 478 component_master_del(&pdev->dev, &rockchip_drm_ops); 479 480 rockchip_drm_match_remove(&pdev->dev); 481 } 482 483 static void rockchip_drm_platform_shutdown(struct platform_device *pdev) 484 { 485 struct drm_device *drm = platform_get_drvdata(pdev); 486 487 if (drm) 488 drm_atomic_helper_shutdown(drm); 489 } 490 491 static const struct of_device_id rockchip_drm_dt_ids[] = { 492 { .compatible = "rockchip,display-subsystem", }, 493 { /* sentinel */ }, 494 }; 495 MODULE_DEVICE_TABLE(of, rockchip_drm_dt_ids); 496 497 static struct platform_driver rockchip_drm_platform_driver = { 498 .probe = rockchip_drm_platform_probe, 499 .remove_new = rockchip_drm_platform_remove, 500 .shutdown = rockchip_drm_platform_shutdown, 501 .driver = { 502 .name = "rockchip-drm", 503 .of_match_table = rockchip_drm_dt_ids, 504 .pm = &rockchip_drm_pm_ops, 505 }, 506 }; 507 508 #define ADD_ROCKCHIP_SUB_DRIVER(drv, cond) { \ 509 if (IS_ENABLED(cond) && \ 510 !WARN_ON(num_rockchip_sub_drivers >= MAX_ROCKCHIP_SUB_DRIVERS)) \ 511 rockchip_sub_drivers[num_rockchip_sub_drivers++] = &drv; \ 512 } 513 514 static int __init rockchip_drm_init(void) 515 { 516 int ret; 517 518 if (drm_firmware_drivers_only()) 519 return -ENODEV; 520 521 num_rockchip_sub_drivers = 0; 522 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP); 523 ADD_ROCKCHIP_SUB_DRIVER(vop2_platform_driver, CONFIG_ROCKCHIP_VOP2); 524 ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver, 525 CONFIG_ROCKCHIP_LVDS); 526 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, 527 CONFIG_ROCKCHIP_ANALOGIX_DP); 528 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP); 529 ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver, 530 CONFIG_ROCKCHIP_DW_HDMI); 531 ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver, 532 CONFIG_ROCKCHIP_DW_MIPI_DSI); 533 ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI); 534 ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver, 535 CONFIG_ROCKCHIP_RK3066_HDMI); 536 537 ret = platform_register_drivers(rockchip_sub_drivers, 538 num_rockchip_sub_drivers); 539 if (ret) 540 return ret; 541 542 ret = platform_driver_register(&rockchip_drm_platform_driver); 543 if (ret) 544 goto err_unreg_drivers; 545 546 return 0; 547 548 err_unreg_drivers: 549 platform_unregister_drivers(rockchip_sub_drivers, 550 num_rockchip_sub_drivers); 551 return ret; 552 } 553 554 static void __exit rockchip_drm_fini(void) 555 { 556 platform_driver_unregister(&rockchip_drm_platform_driver); 557 558 platform_unregister_drivers(rockchip_sub_drivers, 559 num_rockchip_sub_drivers); 560 } 561 562 module_init(rockchip_drm_init); 563 module_exit(rockchip_drm_fini); 564 565 MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>"); 566 MODULE_DESCRIPTION("ROCKCHIP DRM Driver"); 567 MODULE_LICENSE("GPL v2"); 568