exynos_drm_dma.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Copyright (c) 2012 Samsung Electronics Co., Ltd.
  4. // Author: Inki Dae <inki.dae@samsung.com>
  5. // Author: Andrzej Hajda <a.hajda@samsung.com>
  6. #include <linux/dma-map-ops.h>
  7. #include <linux/iommu.h>
  8. #include <linux/platform_device.h>
  9. #include <drm/drm_print.h>
  10. #include <drm/exynos_drm.h>
  11. #include "exynos_drm_drv.h"
  12. #if defined(CONFIG_ARM_DMA_USE_IOMMU)
  13. #include <asm/dma-iommu.h>
  14. #else
  15. #define arm_iommu_create_mapping(...) ({ NULL; })
  16. #define arm_iommu_attach_device(...) ({ -ENODEV; })
  17. #define arm_iommu_release_mapping(...) ({ })
  18. #define arm_iommu_detach_device(...) ({ })
  19. #define to_dma_iommu_mapping(dev) NULL
  20. #endif
  21. #if !defined(CONFIG_IOMMU_DMA)
  22. #define iommu_dma_init_domain(...) ({ -EINVAL; })
  23. #endif
  24. #define EXYNOS_DEV_ADDR_START 0x20000000
  25. #define EXYNOS_DEV_ADDR_SIZE 0x40000000
  26. /*
  27. * drm_iommu_attach_device- attach device to iommu mapping
  28. *
  29. * @drm_dev: DRM device
  30. * @subdrv_dev: device to be attach
  31. *
  32. * This function should be called by sub drivers to attach it to iommu
  33. * mapping.
  34. */
  35. static int drm_iommu_attach_device(struct drm_device *drm_dev,
  36. struct device *subdrv_dev, void **dma_priv)
  37. {
  38. struct exynos_drm_private *priv = drm_dev->dev_private;
  39. int ret = 0;
  40. if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) {
  41. DRM_DEV_ERROR(subdrv_dev, "Device %s lacks support for IOMMU\n",
  42. dev_name(subdrv_dev));
  43. return -EINVAL;
  44. }
  45. dma_set_max_seg_size(subdrv_dev, DMA_BIT_MASK(32));
  46. if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
  47. /*
  48. * Keep the original DMA mapping of the sub-device and
  49. * restore it on Exynos DRM detach, otherwise the DMA
  50. * framework considers it as IOMMU-less during the next
  51. * probe (in case of deferred probe or modular build)
  52. */
  53. *dma_priv = to_dma_iommu_mapping(subdrv_dev);
  54. if (*dma_priv)
  55. arm_iommu_detach_device(subdrv_dev);
  56. ret = arm_iommu_attach_device(subdrv_dev, priv->mapping);
  57. } else if (IS_ENABLED(CONFIG_IOMMU_DMA)) {
  58. ret = iommu_attach_device(priv->mapping, subdrv_dev);
  59. }
  60. return ret;
  61. }
  62. /*
  63. * drm_iommu_detach_device -detach device address space mapping from device
  64. *
  65. * @drm_dev: DRM device
  66. * @subdrv_dev: device to be detached
  67. *
  68. * This function should be called by sub drivers to detach it from iommu
  69. * mapping
  70. */
  71. static void drm_iommu_detach_device(struct drm_device *drm_dev,
  72. struct device *subdrv_dev, void **dma_priv)
  73. {
  74. struct exynos_drm_private *priv = drm_dev->dev_private;
  75. if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
  76. arm_iommu_detach_device(subdrv_dev);
  77. arm_iommu_attach_device(subdrv_dev, *dma_priv);
  78. } else if (IS_ENABLED(CONFIG_IOMMU_DMA))
  79. iommu_detach_device(priv->mapping, subdrv_dev);
  80. }
  81. int exynos_drm_register_dma(struct drm_device *drm, struct device *dev,
  82. void **dma_priv)
  83. {
  84. struct exynos_drm_private *priv = drm->dev_private;
  85. if (!priv->dma_dev) {
  86. priv->dma_dev = dev;
  87. DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
  88. dev_name(dev));
  89. }
  90. if (!IS_ENABLED(CONFIG_EXYNOS_IOMMU))
  91. return 0;
  92. if (!priv->mapping) {
  93. void *mapping = NULL;
  94. if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))
  95. mapping = arm_iommu_create_mapping(dev,
  96. EXYNOS_DEV_ADDR_START, EXYNOS_DEV_ADDR_SIZE);
  97. else if (IS_ENABLED(CONFIG_IOMMU_DMA))
  98. mapping = iommu_get_domain_for_dev(priv->dma_dev);
  99. if (!mapping)
  100. return -ENODEV;
  101. priv->mapping = mapping;
  102. }
  103. return drm_iommu_attach_device(drm, dev, dma_priv);
  104. }
  105. void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev,
  106. void **dma_priv)
  107. {
  108. if (IS_ENABLED(CONFIG_EXYNOS_IOMMU))
  109. drm_iommu_detach_device(drm, dev, dma_priv);
  110. }
  111. void exynos_drm_cleanup_dma(struct drm_device *drm)
  112. {
  113. struct exynos_drm_private *priv = drm->dev_private;
  114. if (!IS_ENABLED(CONFIG_EXYNOS_IOMMU))
  115. return;
  116. arm_iommu_release_mapping(priv->mapping);
  117. priv->mapping = NULL;
  118. priv->dma_dev = NULL;
  119. }