diff options
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_dp.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_dpi.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.c | 241 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_dsi.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 1 |
7 files changed, 126 insertions, 123 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 1ef0be338b85..b445b50a5dc4 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c | |||
| @@ -101,7 +101,6 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, | |||
| 101 | struct exynos_dp_device *dp = to_dp(plat_data); | 101 | struct exynos_dp_device *dp = to_dp(plat_data); |
| 102 | int ret; | 102 | int ret; |
| 103 | 103 | ||
| 104 | drm_connector_register(connector); | ||
| 105 | dp->connector = connector; | 104 | dp->connector = connector; |
| 106 | 105 | ||
| 107 | /* Pre-empt DP connector creation if there's a bridge */ | 106 | /* Pre-empt DP connector creation if there's a bridge */ |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index ad6b73c7fc59..3aab71a485ba 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c | |||
| @@ -114,7 +114,6 @@ static int exynos_dpi_create_connector(struct drm_encoder *encoder) | |||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | drm_connector_helper_add(connector, &exynos_dpi_connector_helper_funcs); | 116 | drm_connector_helper_add(connector, &exynos_dpi_connector_helper_funcs); |
| 117 | drm_connector_register(connector); | ||
| 118 | drm_mode_connector_attach_encoder(connector, encoder); | 117 | drm_mode_connector_attach_encoder(connector, encoder); |
| 119 | 118 | ||
| 120 | return 0; | 119 | return 0; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 035d02ecffcd..497714c8e970 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -40,118 +40,6 @@ | |||
| 40 | 40 | ||
| 41 | static struct device *exynos_drm_get_dma_device(void); | 41 | static struct device *exynos_drm_get_dma_device(void); |
| 42 | 42 | ||
| 43 | static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | ||
| 44 | { | ||
| 45 | struct exynos_drm_private *private; | ||
| 46 | struct drm_encoder *encoder; | ||
| 47 | unsigned int clone_mask; | ||
| 48 | int cnt, ret; | ||
| 49 | |||
| 50 | private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); | ||
| 51 | if (!private) | ||
| 52 | return -ENOMEM; | ||
| 53 | |||
| 54 | init_waitqueue_head(&private->wait); | ||
| 55 | spin_lock_init(&private->lock); | ||
| 56 | |||
| 57 | dev_set_drvdata(dev->dev, dev); | ||
| 58 | dev->dev_private = (void *)private; | ||
| 59 | |||
| 60 | /* the first real CRTC device is used for all dma mapping operations */ | ||
| 61 | private->dma_dev = exynos_drm_get_dma_device(); | ||
| 62 | if (!private->dma_dev) { | ||
| 63 | DRM_ERROR("no device found for DMA mapping operations.\n"); | ||
| 64 | ret = -ENODEV; | ||
| 65 | goto err_free_private; | ||
| 66 | } | ||
| 67 | DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n", | ||
| 68 | dev_name(private->dma_dev)); | ||
| 69 | |||
| 70 | /* create common IOMMU mapping for all devices attached to Exynos DRM */ | ||
| 71 | ret = drm_create_iommu_mapping(dev); | ||
| 72 | if (ret < 0) { | ||
| 73 | DRM_ERROR("failed to create iommu mapping.\n"); | ||
| 74 | goto err_free_private; | ||
| 75 | } | ||
| 76 | |||
| 77 | drm_mode_config_init(dev); | ||
| 78 | |||
| 79 | exynos_drm_mode_config_init(dev); | ||
| 80 | |||
| 81 | /* setup possible_clones. */ | ||
| 82 | cnt = 0; | ||
| 83 | clone_mask = 0; | ||
| 84 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | ||
| 85 | clone_mask |= (1 << (cnt++)); | ||
| 86 | |||
| 87 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | ||
| 88 | encoder->possible_clones = clone_mask; | ||
| 89 | |||
| 90 | platform_set_drvdata(dev->platformdev, dev); | ||
| 91 | |||
| 92 | /* Try to bind all sub drivers. */ | ||
| 93 | ret = component_bind_all(dev->dev, dev); | ||
| 94 | if (ret) | ||
| 95 | goto err_mode_config_cleanup; | ||
| 96 | |||
| 97 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | ||
| 98 | if (ret) | ||
| 99 | goto err_unbind_all; | ||
| 100 | |||
| 101 | /* Probe non kms sub drivers and virtual display driver. */ | ||
| 102 | ret = exynos_drm_device_subdrv_probe(dev); | ||
| 103 | if (ret) | ||
| 104 | goto err_cleanup_vblank; | ||
| 105 | |||
| 106 | drm_mode_config_reset(dev); | ||
| 107 | |||
| 108 | /* | ||
| 109 | * enable drm irq mode. | ||
| 110 | * - with irq_enabled = true, we can use the vblank feature. | ||
| 111 | * | ||
| 112 | * P.S. note that we wouldn't use drm irq handler but | ||
| 113 | * just specific driver own one instead because | ||
| 114 | * drm framework supports only one irq handler. | ||
| 115 | */ | ||
| 116 | dev->irq_enabled = true; | ||
| 117 | |||
| 118 | /* init kms poll for handling hpd */ | ||
| 119 | drm_kms_helper_poll_init(dev); | ||
| 120 | |||
| 121 | /* force connectors detection */ | ||
| 122 | drm_helper_hpd_irq_event(dev); | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | |||
| 126 | err_cleanup_vblank: | ||
| 127 | drm_vblank_cleanup(dev); | ||
| 128 | err_unbind_all: | ||
| 129 | component_unbind_all(dev->dev, dev); | ||
| 130 | err_mode_config_cleanup: | ||
| 131 | drm_mode_config_cleanup(dev); | ||
| 132 | drm_release_iommu_mapping(dev); | ||
| 133 | err_free_private: | ||
| 134 | kfree(private); | ||
| 135 | |||
| 136 | return ret; | ||
| 137 | } | ||
| 138 | |||
| 139 | static void exynos_drm_unload(struct drm_device *dev) | ||
| 140 | { | ||
| 141 | exynos_drm_device_subdrv_remove(dev); | ||
| 142 | |||
| 143 | exynos_drm_fbdev_fini(dev); | ||
| 144 | drm_kms_helper_poll_fini(dev); | ||
| 145 | |||
| 146 | drm_vblank_cleanup(dev); | ||
| 147 | component_unbind_all(dev->dev, dev); | ||
| 148 | drm_mode_config_cleanup(dev); | ||
| 149 | drm_release_iommu_mapping(dev); | ||
| 150 | |||
| 151 | kfree(dev->dev_private); | ||
| 152 | dev->dev_private = NULL; | ||
| 153 | } | ||
| 154 | |||
| 155 | int exynos_atomic_check(struct drm_device *dev, | 43 | int exynos_atomic_check(struct drm_device *dev, |
| 156 | struct drm_atomic_state *state) | 44 | struct drm_atomic_state *state) |
| 157 | { | 45 | { |
| @@ -257,8 +145,6 @@ static const struct file_operations exynos_drm_driver_fops = { | |||
| 257 | static struct drm_driver exynos_drm_driver = { | 145 | static struct drm_driver exynos_drm_driver = { |
| 258 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | 146 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
| 259 | | DRIVER_ATOMIC | DRIVER_RENDER, | 147 | | DRIVER_ATOMIC | DRIVER_RENDER, |
| 260 | .load = exynos_drm_load, | ||
| 261 | .unload = exynos_drm_unload, | ||
| 262 | .open = exynos_drm_open, | 148 | .open = exynos_drm_open, |
| 263 | .preclose = exynos_drm_preclose, | 149 | .preclose = exynos_drm_preclose, |
| 264 | .lastclose = exynos_drm_lastclose, | 150 | .lastclose = exynos_drm_lastclose, |
| @@ -436,12 +322,135 @@ static struct component_match *exynos_drm_match_add(struct device *dev) | |||
| 436 | 322 | ||
| 437 | static int exynos_drm_bind(struct device *dev) | 323 | static int exynos_drm_bind(struct device *dev) |
| 438 | { | 324 | { |
| 439 | return drm_platform_init(&exynos_drm_driver, to_platform_device(dev)); | 325 | struct exynos_drm_private *private; |
| 326 | struct drm_encoder *encoder; | ||
| 327 | struct drm_device *drm; | ||
| 328 | unsigned int clone_mask; | ||
| 329 | int cnt, ret; | ||
| 330 | |||
| 331 | drm = drm_dev_alloc(&exynos_drm_driver, dev); | ||
| 332 | if (IS_ERR(drm)) | ||
| 333 | return PTR_ERR(drm); | ||
| 334 | |||
| 335 | private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); | ||
| 336 | if (!private) { | ||
| 337 | ret = -ENOMEM; | ||
| 338 | goto err_free_drm; | ||
| 339 | } | ||
| 340 | |||
| 341 | init_waitqueue_head(&private->wait); | ||
| 342 | spin_lock_init(&private->lock); | ||
| 343 | |||
| 344 | dev_set_drvdata(dev, drm); | ||
| 345 | drm->dev_private = (void *)private; | ||
| 346 | |||
| 347 | /* the first real CRTC device is used for all dma mapping operations */ | ||
| 348 | private->dma_dev = exynos_drm_get_dma_device(); | ||
| 349 | if (!private->dma_dev) { | ||
| 350 | DRM_ERROR("no device found for DMA mapping operations.\n"); | ||
| 351 | ret = -ENODEV; | ||
| 352 | goto err_free_private; | ||
| 353 | } | ||
| 354 | DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n", | ||
| 355 | dev_name(private->dma_dev)); | ||
| 356 | |||
| 357 | /* create common IOMMU mapping for all devices attached to Exynos DRM */ | ||
| 358 | ret = drm_create_iommu_mapping(drm); | ||
| 359 | if (ret < 0) { | ||
| 360 | DRM_ERROR("failed to create iommu mapping.\n"); | ||
| 361 | goto err_free_private; | ||
| 362 | } | ||
| 363 | |||
| 364 | drm_mode_config_init(drm); | ||
| 365 | |||
| 366 | exynos_drm_mode_config_init(drm); | ||
| 367 | |||
| 368 | /* setup possible_clones. */ | ||
| 369 | cnt = 0; | ||
| 370 | clone_mask = 0; | ||
| 371 | list_for_each_entry(encoder, &drm->mode_config.encoder_list, head) | ||
| 372 | clone_mask |= (1 << (cnt++)); | ||
| 373 | |||
| 374 | list_for_each_entry(encoder, &drm->mode_config.encoder_list, head) | ||
| 375 | encoder->possible_clones = clone_mask; | ||
| 376 | |||
| 377 | /* Try to bind all sub drivers. */ | ||
| 378 | ret = component_bind_all(drm->dev, drm); | ||
| 379 | if (ret) | ||
| 380 | goto err_mode_config_cleanup; | ||
| 381 | |||
| 382 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | ||
| 383 | if (ret) | ||
| 384 | goto err_unbind_all; | ||
| 385 | |||
| 386 | /* Probe non kms sub drivers and virtual display driver. */ | ||
| 387 | ret = exynos_drm_device_subdrv_probe(drm); | ||
| 388 | if (ret) | ||
| 389 | goto err_cleanup_vblank; | ||
| 390 | |||
| 391 | drm_mode_config_reset(drm); | ||
| 392 | |||
| 393 | /* | ||
| 394 | * enable drm irq mode. | ||
| 395 | * - with irq_enabled = true, we can use the vblank feature. | ||
| 396 | * | ||
| 397 | * P.S. note that we wouldn't use drm irq handler but | ||
| 398 | * just specific driver own one instead because | ||
| 399 | * drm framework supports only one irq handler. | ||
| 400 | */ | ||
| 401 | drm->irq_enabled = true; | ||
| 402 | |||
| 403 | /* init kms poll for handling hpd */ | ||
| 404 | drm_kms_helper_poll_init(drm); | ||
| 405 | |||
| 406 | /* force connectors detection */ | ||
| 407 | drm_helper_hpd_irq_event(drm); | ||
| 408 | |||
| 409 | /* register the DRM device */ | ||
| 410 | ret = drm_dev_register(drm, 0); | ||
| 411 | if (ret < 0) | ||
| 412 | goto err_cleanup_fbdev; | ||
| 413 | |||
| 414 | return 0; | ||
| 415 | |||
| 416 | err_cleanup_fbdev: | ||
| 417 | exynos_drm_fbdev_fini(drm); | ||
| 418 | drm_kms_helper_poll_fini(drm); | ||
| 419 | exynos_drm_device_subdrv_remove(drm); | ||
| 420 | err_cleanup_vblank: | ||
| 421 | drm_vblank_cleanup(drm); | ||
| 422 | err_unbind_all: | ||
| 423 | component_unbind_all(drm->dev, drm); | ||
| 424 | err_mode_config_cleanup: | ||
| 425 | drm_mode_config_cleanup(drm); | ||
| 426 | drm_release_iommu_mapping(drm); | ||
| 427 | err_free_private: | ||
| 428 | kfree(private); | ||
| 429 | err_free_drm: | ||
| 430 | drm_dev_unref(drm); | ||
| 431 | |||
| 432 | return ret; | ||
| 440 | } | 433 | } |
| 441 | 434 | ||
| 442 | static void exynos_drm_unbind(struct device *dev) | 435 | static void exynos_drm_unbind(struct device *dev) |
| 443 | { | 436 | { |
| 444 | drm_put_dev(dev_get_drvdata(dev)); | 437 | struct drm_device *drm = dev_get_drvdata(dev); |
| 438 | |||
| 439 | drm_dev_unregister(drm); | ||
| 440 | |||
| 441 | exynos_drm_device_subdrv_remove(drm); | ||
| 442 | |||
| 443 | exynos_drm_fbdev_fini(drm); | ||
| 444 | drm_kms_helper_poll_fini(drm); | ||
| 445 | |||
| 446 | component_unbind_all(drm->dev, drm); | ||
| 447 | drm_mode_config_cleanup(drm); | ||
| 448 | drm_release_iommu_mapping(drm); | ||
| 449 | |||
| 450 | kfree(drm->dev_private); | ||
| 451 | drm->dev_private = NULL; | ||
| 452 | |||
| 453 | drm_dev_unref(drm); | ||
| 445 | } | 454 | } |
| 446 | 455 | ||
| 447 | static const struct component_master_ops exynos_drm_ops = { | 456 | static const struct component_master_ops exynos_drm_ops = { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 812e2ec0761d..43a45abc524f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c | |||
| @@ -1587,7 +1587,6 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) | |||
| 1587 | } | 1587 | } |
| 1588 | 1588 | ||
| 1589 | drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs); | 1589 | drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs); |
| 1590 | drm_connector_register(connector); | ||
| 1591 | drm_mode_connector_attach_encoder(connector, encoder); | 1590 | drm_mode_connector_attach_encoder(connector, encoder); |
| 1592 | 1591 | ||
| 1593 | return 0; | 1592 | return 0; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index bcdb2720b68e..114ba4073524 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
| @@ -120,7 +120,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, | |||
| 120 | struct exynos_drm_gem *exynos_gem; | 120 | struct exynos_drm_gem *exynos_gem; |
| 121 | struct drm_device *dev = helper->dev; | 121 | struct drm_device *dev = helper->dev; |
| 122 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; | 122 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; |
| 123 | struct platform_device *pdev = dev->platformdev; | ||
| 124 | unsigned long size; | 123 | unsigned long size; |
| 125 | int ret; | 124 | int ret; |
| 126 | 125 | ||
| @@ -143,7 +142,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, | |||
| 143 | * memory area. | 142 | * memory area. |
| 144 | */ | 143 | */ |
| 145 | if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) { | 144 | if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) { |
| 146 | dev_warn(&pdev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n"); | 145 | dev_warn(dev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n"); |
| 147 | exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG, | 146 | exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG, |
| 148 | size); | 147 | size); |
| 149 | } | 148 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 57fe514d5c5b..6bbb0ea8a6af 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
| @@ -359,7 +359,6 @@ static int vidi_create_connector(struct drm_encoder *encoder) | |||
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | drm_connector_helper_add(connector, &vidi_connector_helper_funcs); | 361 | drm_connector_helper_add(connector, &vidi_connector_helper_funcs); |
| 362 | drm_connector_register(connector); | ||
| 363 | drm_mode_connector_attach_encoder(connector, encoder); | 362 | drm_mode_connector_attach_encoder(connector, encoder); |
| 364 | 363 | ||
| 365 | return 0; | 364 | return 0; |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 88ccc0469316..74f725067140 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -921,7 +921,6 @@ static int hdmi_create_connector(struct drm_encoder *encoder) | |||
| 921 | } | 921 | } |
| 922 | 922 | ||
| 923 | drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); | 923 | drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); |
| 924 | drm_connector_register(connector); | ||
| 925 | drm_mode_connector_attach_encoder(connector, encoder); | 924 | drm_mode_connector_attach_encoder(connector, encoder); |
| 926 | 925 | ||
| 927 | if (hdata->bridge) { | 926 | if (hdata->bridge) { |
