exynos_drm_iommu.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* exynos_drm_iommu.c
  2. *
  3. * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  4. * Author: Inki Dae <inki.dae@samsung.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. */
  11. #include <drm/drmP.h>
  12. #include <drm/exynos_drm.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/iommu.h>
  15. #include "exynos_drm_drv.h"
  16. #include "exynos_drm_iommu.h"
  17. static inline int configure_dma_max_seg_size(struct device *dev)
  18. {
  19. if (!dev->dma_parms)
  20. dev->dma_parms = kzalloc(sizeof(*dev->dma_parms), GFP_KERNEL);
  21. if (!dev->dma_parms)
  22. return -ENOMEM;
  23. dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
  24. return 0;
  25. }
  26. static inline void clear_dma_max_seg_size(struct device *dev)
  27. {
  28. kfree(dev->dma_parms);
  29. dev->dma_parms = NULL;
  30. }
  31. /*
  32. * drm_create_iommu_mapping - create a mapping structure
  33. *
  34. * @drm_dev: DRM device
  35. */
  36. int drm_create_iommu_mapping(struct drm_device *drm_dev)
  37. {
  38. struct exynos_drm_private *priv = drm_dev->dev_private;
  39. return __exynos_iommu_create_mapping(priv, EXYNOS_DEV_ADDR_START,
  40. EXYNOS_DEV_ADDR_SIZE);
  41. }
  42. /*
  43. * drm_release_iommu_mapping - release iommu mapping structure
  44. *
  45. * @drm_dev: DRM device
  46. */
  47. void drm_release_iommu_mapping(struct drm_device *drm_dev)
  48. {
  49. struct exynos_drm_private *priv = drm_dev->dev_private;
  50. __exynos_iommu_release_mapping(priv);
  51. }
  52. /*
  53. * drm_iommu_attach_device- attach device to iommu mapping
  54. *
  55. * @drm_dev: DRM device
  56. * @subdrv_dev: device to be attach
  57. *
  58. * This function should be called by sub drivers to attach it to iommu
  59. * mapping.
  60. */
  61. int drm_iommu_attach_device(struct drm_device *drm_dev,
  62. struct device *subdrv_dev)
  63. {
  64. struct exynos_drm_private *priv = drm_dev->dev_private;
  65. int ret;
  66. if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) {
  67. DRM_ERROR("Device %s lacks support for IOMMU\n",
  68. dev_name(subdrv_dev));
  69. return -EINVAL;
  70. }
  71. ret = configure_dma_max_seg_size(subdrv_dev);
  72. if (ret)
  73. return ret;
  74. ret = __exynos_iommu_attach(priv, subdrv_dev);
  75. if (ret)
  76. clear_dma_max_seg_size(subdrv_dev);
  77. return 0;
  78. }
  79. /*
  80. * drm_iommu_detach_device -detach device address space mapping from device
  81. *
  82. * @drm_dev: DRM device
  83. * @subdrv_dev: device to be detached
  84. *
  85. * This function should be called by sub drivers to detach it from iommu
  86. * mapping
  87. */
  88. void drm_iommu_detach_device(struct drm_device *drm_dev,
  89. struct device *subdrv_dev)
  90. {
  91. struct exynos_drm_private *priv = drm_dev->dev_private;
  92. __exynos_iommu_detach(priv, subdrv_dev);
  93. clear_dma_max_seg_size(subdrv_dev);
  94. }