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