0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/dma-mapping.h>
0010 #include <linux/pm_runtime.h>
0011 #include <linux/module.h>
0012 #include <linux/of_graph.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/component.h>
0015 #include <linux/console.h>
0016 #include <linux/iommu.h>
0017
0018 #include <drm/drm_aperture.h>
0019 #include <drm/drm_drv.h>
0020 #include <drm/drm_fb_helper.h>
0021 #include <drm/drm_gem_cma_helper.h>
0022 #include <drm/drm_of.h>
0023 #include <drm/drm_probe_helper.h>
0024 #include <drm/drm_vblank.h>
0025
0026 #if defined(CONFIG_ARM_DMA_USE_IOMMU)
0027 #include <asm/dma-iommu.h>
0028 #else
0029 #define arm_iommu_detach_device(...) ({ })
0030 #define arm_iommu_release_mapping(...) ({ })
0031 #define to_dma_iommu_mapping(dev) NULL
0032 #endif
0033
0034 #include "rockchip_drm_drv.h"
0035 #include "rockchip_drm_fb.h"
0036 #include "rockchip_drm_gem.h"
0037
0038 #define DRIVER_NAME "rockchip"
0039 #define DRIVER_DESC "RockChip Soc DRM"
0040 #define DRIVER_DATE "20140818"
0041 #define DRIVER_MAJOR 1
0042 #define DRIVER_MINOR 0
0043
0044 static const struct drm_driver rockchip_drm_driver;
0045
0046
0047
0048
0049
0050
0051 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
0052 struct device *dev)
0053 {
0054 struct rockchip_drm_private *private = drm_dev->dev_private;
0055 int ret;
0056
0057 if (!private->domain)
0058 return 0;
0059
0060 if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
0061 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
0062
0063 if (mapping) {
0064 arm_iommu_detach_device(dev);
0065 arm_iommu_release_mapping(mapping);
0066 }
0067 }
0068
0069 ret = iommu_attach_device(private->domain, dev);
0070 if (ret) {
0071 DRM_DEV_ERROR(dev, "Failed to attach iommu device\n");
0072 return ret;
0073 }
0074
0075 return 0;
0076 }
0077
0078 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
0079 struct device *dev)
0080 {
0081 struct rockchip_drm_private *private = drm_dev->dev_private;
0082
0083 if (!private->domain)
0084 return;
0085
0086 iommu_detach_device(private->domain, dev);
0087 }
0088
0089 void rockchip_drm_dma_init_device(struct drm_device *drm_dev,
0090 struct device *dev)
0091 {
0092 struct rockchip_drm_private *private = drm_dev->dev_private;
0093
0094 if (!device_iommu_mapped(dev))
0095 private->iommu_dev = ERR_PTR(-ENODEV);
0096 else if (!private->iommu_dev)
0097 private->iommu_dev = dev;
0098 }
0099
0100 static int rockchip_drm_init_iommu(struct drm_device *drm_dev)
0101 {
0102 struct rockchip_drm_private *private = drm_dev->dev_private;
0103 struct iommu_domain_geometry *geometry;
0104 u64 start, end;
0105
0106 if (IS_ERR_OR_NULL(private->iommu_dev))
0107 return 0;
0108
0109 private->domain = iommu_domain_alloc(private->iommu_dev->bus);
0110 if (!private->domain)
0111 return -ENOMEM;
0112
0113 geometry = &private->domain->geometry;
0114 start = geometry->aperture_start;
0115 end = geometry->aperture_end;
0116
0117 DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n",
0118 start, end);
0119 drm_mm_init(&private->mm, start, end - start + 1);
0120 mutex_init(&private->mm_lock);
0121
0122 return 0;
0123 }
0124
0125 static void rockchip_iommu_cleanup(struct drm_device *drm_dev)
0126 {
0127 struct rockchip_drm_private *private = drm_dev->dev_private;
0128
0129 if (!private->domain)
0130 return;
0131
0132 drm_mm_takedown(&private->mm);
0133 iommu_domain_free(private->domain);
0134 }
0135
0136 static int rockchip_drm_bind(struct device *dev)
0137 {
0138 struct drm_device *drm_dev;
0139 struct rockchip_drm_private *private;
0140 int ret;
0141
0142
0143 ret = drm_aperture_remove_framebuffers(false, &rockchip_drm_driver);
0144 if (ret) {
0145 DRM_DEV_ERROR(dev,
0146 "Failed to remove existing framebuffers - %d.\n",
0147 ret);
0148 return ret;
0149 }
0150
0151 drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev);
0152 if (IS_ERR(drm_dev))
0153 return PTR_ERR(drm_dev);
0154
0155 dev_set_drvdata(dev, drm_dev);
0156
0157 private = devm_kzalloc(drm_dev->dev, sizeof(*private), GFP_KERNEL);
0158 if (!private) {
0159 ret = -ENOMEM;
0160 goto err_free;
0161 }
0162
0163 drm_dev->dev_private = private;
0164
0165 ret = drmm_mode_config_init(drm_dev);
0166 if (ret)
0167 goto err_free;
0168
0169 rockchip_drm_mode_config_init(drm_dev);
0170
0171
0172 ret = component_bind_all(dev, drm_dev);
0173 if (ret)
0174 goto err_free;
0175
0176 ret = rockchip_drm_init_iommu(drm_dev);
0177 if (ret)
0178 goto err_unbind_all;
0179
0180 ret = drm_vblank_init(drm_dev, drm_dev->mode_config.num_crtc);
0181 if (ret)
0182 goto err_iommu_cleanup;
0183
0184 drm_mode_config_reset(drm_dev);
0185
0186
0187 drm_kms_helper_poll_init(drm_dev);
0188
0189 ret = drm_dev_register(drm_dev, 0);
0190 if (ret)
0191 goto err_kms_helper_poll_fini;
0192
0193 drm_fbdev_generic_setup(drm_dev, 0);
0194
0195 return 0;
0196 err_kms_helper_poll_fini:
0197 drm_kms_helper_poll_fini(drm_dev);
0198 err_iommu_cleanup:
0199 rockchip_iommu_cleanup(drm_dev);
0200 err_unbind_all:
0201 component_unbind_all(dev, drm_dev);
0202 err_free:
0203 drm_dev_put(drm_dev);
0204 return ret;
0205 }
0206
0207 static void rockchip_drm_unbind(struct device *dev)
0208 {
0209 struct drm_device *drm_dev = dev_get_drvdata(dev);
0210
0211 drm_dev_unregister(drm_dev);
0212
0213 drm_kms_helper_poll_fini(drm_dev);
0214
0215 drm_atomic_helper_shutdown(drm_dev);
0216 component_unbind_all(dev, drm_dev);
0217 rockchip_iommu_cleanup(drm_dev);
0218
0219 drm_dev_put(drm_dev);
0220 }
0221
0222 DEFINE_DRM_GEM_FOPS(rockchip_drm_driver_fops);
0223
0224 static const struct drm_driver rockchip_drm_driver = {
0225 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
0226 .dumb_create = rockchip_gem_dumb_create,
0227 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
0228 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
0229 .gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table,
0230 .gem_prime_mmap = drm_gem_prime_mmap,
0231 .fops = &rockchip_drm_driver_fops,
0232 .name = DRIVER_NAME,
0233 .desc = DRIVER_DESC,
0234 .date = DRIVER_DATE,
0235 .major = DRIVER_MAJOR,
0236 .minor = DRIVER_MINOR,
0237 };
0238
0239 #ifdef CONFIG_PM_SLEEP
0240 static int rockchip_drm_sys_suspend(struct device *dev)
0241 {
0242 struct drm_device *drm = dev_get_drvdata(dev);
0243
0244 return drm_mode_config_helper_suspend(drm);
0245 }
0246
0247 static int rockchip_drm_sys_resume(struct device *dev)
0248 {
0249 struct drm_device *drm = dev_get_drvdata(dev);
0250
0251 return drm_mode_config_helper_resume(drm);
0252 }
0253 #endif
0254
0255 static const struct dev_pm_ops rockchip_drm_pm_ops = {
0256 SET_SYSTEM_SLEEP_PM_OPS(rockchip_drm_sys_suspend,
0257 rockchip_drm_sys_resume)
0258 };
0259
0260 #define MAX_ROCKCHIP_SUB_DRIVERS 16
0261 static struct platform_driver *rockchip_sub_drivers[MAX_ROCKCHIP_SUB_DRIVERS];
0262 static int num_rockchip_sub_drivers;
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rkencoder,
0274 struct device_node *np, int port, int reg)
0275 {
0276 struct of_endpoint ep;
0277 struct device_node *en, *ren;
0278 int ret;
0279
0280 en = of_graph_get_endpoint_by_regs(np, port, reg);
0281 if (!en)
0282 return -ENOENT;
0283
0284 ren = of_graph_get_remote_endpoint(en);
0285 if (!ren)
0286 return -ENOENT;
0287
0288 ret = of_graph_parse_endpoint(ren, &ep);
0289 if (ret)
0290 return ret;
0291
0292 rkencoder->crtc_endpoint_id = ep.id;
0293
0294 return 0;
0295 }
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
0308 {
0309 struct device_node *node = of_graph_get_remote_port_parent(ep);
0310 struct platform_device *pdev;
0311 struct device_driver *drv;
0312 int i;
0313
0314 if (!node)
0315 return -ENODEV;
0316
0317
0318 if (!of_device_is_available(node)) {
0319 of_node_put(node);
0320 return -ENODEV;
0321 }
0322
0323 pdev = of_find_device_by_node(node);
0324 of_node_put(node);
0325
0326
0327 if (!pdev)
0328 return false;
0329
0330
0331
0332
0333
0334 drv = pdev->dev.driver;
0335 if (!drv) {
0336 platform_device_put(pdev);
0337 return false;
0338 }
0339
0340 for (i = 0; i < num_rockchip_sub_drivers; i++) {
0341 if (rockchip_sub_drivers[i] == to_platform_driver(drv)) {
0342 platform_device_put(pdev);
0343 return true;
0344 }
0345 }
0346
0347 platform_device_put(pdev);
0348 return false;
0349 }
0350
0351 static void rockchip_drm_match_remove(struct device *dev)
0352 {
0353 struct device_link *link;
0354
0355 list_for_each_entry(link, &dev->links.consumers, s_node)
0356 device_link_del(link);
0357 }
0358
0359 static struct component_match *rockchip_drm_match_add(struct device *dev)
0360 {
0361 struct component_match *match = NULL;
0362 int i;
0363
0364 for (i = 0; i < num_rockchip_sub_drivers; i++) {
0365 struct platform_driver *drv = rockchip_sub_drivers[i];
0366 struct device *p = NULL, *d;
0367
0368 do {
0369 d = platform_find_device_by_driver(p, &drv->driver);
0370 put_device(p);
0371 p = d;
0372
0373 if (!d)
0374 break;
0375
0376 device_link_add(dev, d, DL_FLAG_STATELESS);
0377 component_match_add(dev, &match, component_compare_dev, d);
0378 } while (true);
0379 }
0380
0381 if (IS_ERR(match))
0382 rockchip_drm_match_remove(dev);
0383
0384 return match ?: ERR_PTR(-ENODEV);
0385 }
0386
0387 static const struct component_master_ops rockchip_drm_ops = {
0388 .bind = rockchip_drm_bind,
0389 .unbind = rockchip_drm_unbind,
0390 };
0391
0392 static int rockchip_drm_platform_of_probe(struct device *dev)
0393 {
0394 struct device_node *np = dev->of_node;
0395 struct device_node *port;
0396 bool found = false;
0397 int i;
0398
0399 if (!np)
0400 return -ENODEV;
0401
0402 for (i = 0;; i++) {
0403 port = of_parse_phandle(np, "ports", i);
0404 if (!port)
0405 break;
0406
0407 if (!of_device_is_available(port->parent)) {
0408 of_node_put(port);
0409 continue;
0410 }
0411
0412 found = true;
0413 of_node_put(port);
0414 }
0415
0416 if (i == 0) {
0417 DRM_DEV_ERROR(dev, "missing 'ports' property\n");
0418 return -ENODEV;
0419 }
0420
0421 if (!found) {
0422 DRM_DEV_ERROR(dev,
0423 "No available vop found for display-subsystem.\n");
0424 return -ENODEV;
0425 }
0426
0427 return 0;
0428 }
0429
0430 static int rockchip_drm_platform_probe(struct platform_device *pdev)
0431 {
0432 struct device *dev = &pdev->dev;
0433 struct component_match *match = NULL;
0434 int ret;
0435
0436 ret = rockchip_drm_platform_of_probe(dev);
0437 if (ret)
0438 return ret;
0439
0440 match = rockchip_drm_match_add(dev);
0441 if (IS_ERR(match))
0442 return PTR_ERR(match);
0443
0444 ret = component_master_add_with_match(dev, &rockchip_drm_ops, match);
0445 if (ret < 0) {
0446 rockchip_drm_match_remove(dev);
0447 return ret;
0448 }
0449
0450 return 0;
0451 }
0452
0453 static int rockchip_drm_platform_remove(struct platform_device *pdev)
0454 {
0455 component_master_del(&pdev->dev, &rockchip_drm_ops);
0456
0457 rockchip_drm_match_remove(&pdev->dev);
0458
0459 return 0;
0460 }
0461
0462 static void rockchip_drm_platform_shutdown(struct platform_device *pdev)
0463 {
0464 struct drm_device *drm = platform_get_drvdata(pdev);
0465
0466 if (drm)
0467 drm_atomic_helper_shutdown(drm);
0468 }
0469
0470 static const struct of_device_id rockchip_drm_dt_ids[] = {
0471 { .compatible = "rockchip,display-subsystem", },
0472 { },
0473 };
0474 MODULE_DEVICE_TABLE(of, rockchip_drm_dt_ids);
0475
0476 static struct platform_driver rockchip_drm_platform_driver = {
0477 .probe = rockchip_drm_platform_probe,
0478 .remove = rockchip_drm_platform_remove,
0479 .shutdown = rockchip_drm_platform_shutdown,
0480 .driver = {
0481 .name = "rockchip-drm",
0482 .of_match_table = rockchip_drm_dt_ids,
0483 .pm = &rockchip_drm_pm_ops,
0484 },
0485 };
0486
0487 #define ADD_ROCKCHIP_SUB_DRIVER(drv, cond) { \
0488 if (IS_ENABLED(cond) && \
0489 !WARN_ON(num_rockchip_sub_drivers >= MAX_ROCKCHIP_SUB_DRIVERS)) \
0490 rockchip_sub_drivers[num_rockchip_sub_drivers++] = &drv; \
0491 }
0492
0493 static int __init rockchip_drm_init(void)
0494 {
0495 int ret;
0496
0497 if (drm_firmware_drivers_only())
0498 return -ENODEV;
0499
0500 num_rockchip_sub_drivers = 0;
0501 ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP);
0502 ADD_ROCKCHIP_SUB_DRIVER(vop2_platform_driver, CONFIG_ROCKCHIP_VOP2);
0503 ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver,
0504 CONFIG_ROCKCHIP_LVDS);
0505 ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver,
0506 CONFIG_ROCKCHIP_ANALOGIX_DP);
0507 ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP);
0508 ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver,
0509 CONFIG_ROCKCHIP_DW_HDMI);
0510 ADD_ROCKCHIP_SUB_DRIVER(dw_mipi_dsi_rockchip_driver,
0511 CONFIG_ROCKCHIP_DW_MIPI_DSI);
0512 ADD_ROCKCHIP_SUB_DRIVER(inno_hdmi_driver, CONFIG_ROCKCHIP_INNO_HDMI);
0513 ADD_ROCKCHIP_SUB_DRIVER(rk3066_hdmi_driver,
0514 CONFIG_ROCKCHIP_RK3066_HDMI);
0515
0516 ret = platform_register_drivers(rockchip_sub_drivers,
0517 num_rockchip_sub_drivers);
0518 if (ret)
0519 return ret;
0520
0521 ret = platform_driver_register(&rockchip_drm_platform_driver);
0522 if (ret)
0523 goto err_unreg_drivers;
0524
0525 return 0;
0526
0527 err_unreg_drivers:
0528 platform_unregister_drivers(rockchip_sub_drivers,
0529 num_rockchip_sub_drivers);
0530 return ret;
0531 }
0532
0533 static void __exit rockchip_drm_fini(void)
0534 {
0535 platform_driver_unregister(&rockchip_drm_platform_driver);
0536
0537 platform_unregister_drivers(rockchip_sub_drivers,
0538 num_rockchip_sub_drivers);
0539 }
0540
0541 module_init(rockchip_drm_init);
0542 module_exit(rockchip_drm_fini);
0543
0544 MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>");
0545 MODULE_DESCRIPTION("ROCKCHIP DRM Driver");
0546 MODULE_LICENSE("GPL v2");