3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 * Author: Inki Dae <inki.dae@samsung.com>
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.
13 #include <drm/exynos_drm.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/iommu.h>
17 #include <linux/kref.h>
19 #include <asm/dma-iommu.h>
21 #include "exynos_drm_drv.h"
22 #include "exynos_drm_iommu.h"
25 * drm_create_iommu_mapping - create a mapping structure
27 * @drm_dev: DRM device
29 int drm_create_iommu_mapping(struct drm_device
*drm_dev
)
31 struct dma_iommu_mapping
*mapping
= NULL
;
32 struct exynos_drm_private
*priv
= drm_dev
->dev_private
;
33 struct device
*dev
= drm_dev
->dev
;
36 priv
->da_start
= EXYNOS_DEV_ADDR_START
;
37 if (!priv
->da_space_size
)
38 priv
->da_space_size
= EXYNOS_DEV_ADDR_SIZE
;
40 mapping
= arm_iommu_create_mapping(&platform_bus_type
, priv
->da_start
,
44 return PTR_ERR(mapping
);
46 dev
->dma_parms
= devm_kzalloc(dev
, sizeof(*dev
->dma_parms
),
51 dma_set_max_seg_size(dev
, 0xffffffffu
);
52 dev
->archdata
.mapping
= mapping
;
56 arm_iommu_release_mapping(mapping
);
61 * drm_release_iommu_mapping - release iommu mapping structure
63 * @drm_dev: DRM device
65 * if mapping->kref becomes 0 then all things related to iommu mapping
68 void drm_release_iommu_mapping(struct drm_device
*drm_dev
)
70 struct device
*dev
= drm_dev
->dev
;
72 arm_iommu_release_mapping(dev
->archdata
.mapping
);
76 * drm_iommu_attach_device- attach device to iommu mapping
78 * @drm_dev: DRM device
79 * @subdrv_dev: device to be attach
81 * This function should be called by sub drivers to attach it to iommu
84 int drm_iommu_attach_device(struct drm_device
*drm_dev
,
85 struct device
*subdrv_dev
)
87 struct device
*dev
= drm_dev
->dev
;
90 if (!dev
->archdata
.mapping
) {
91 DRM_ERROR("iommu_mapping is null.\n");
95 subdrv_dev
->dma_parms
= devm_kzalloc(subdrv_dev
,
96 sizeof(*subdrv_dev
->dma_parms
),
98 if (!subdrv_dev
->dma_parms
)
101 dma_set_max_seg_size(subdrv_dev
, 0xffffffffu
);
103 if (subdrv_dev
->archdata
.mapping
)
104 arm_iommu_detach_device(subdrv_dev
);
106 ret
= arm_iommu_attach_device(subdrv_dev
, dev
->archdata
.mapping
);
108 DRM_DEBUG_KMS("failed iommu attach.\n");
113 * Set dma_ops to drm_device just one time.
115 * The dma mapping api needs device object and the api is used
116 * to allocate physial memory and map it with iommu table.
117 * If iommu attach succeeded, the sub driver would have dma_ops
118 * for iommu and also all sub drivers have same dma_ops.
120 if (get_dma_ops(dev
) == get_dma_ops(NULL
))
121 set_dma_ops(dev
, get_dma_ops(subdrv_dev
));
127 * drm_iommu_detach_device -detach device address space mapping from device
129 * @drm_dev: DRM device
130 * @subdrv_dev: device to be detached
132 * This function should be called by sub drivers to detach it from iommu
135 void drm_iommu_detach_device(struct drm_device
*drm_dev
,
136 struct device
*subdrv_dev
)
138 struct device
*dev
= drm_dev
->dev
;
139 struct dma_iommu_mapping
*mapping
= dev
->archdata
.mapping
;
141 if (!mapping
|| !mapping
->domain
)
144 iommu_detach_device(mapping
->domain
, subdrv_dev
);
145 drm_release_iommu_mapping(drm_dev
);
148 int drm_iommu_attach_device_if_possible(struct exynos_drm_crtc
*exynos_crtc
,
149 struct drm_device
*drm_dev
, struct device
*subdrv_dev
)
153 if (is_drm_iommu_supported(drm_dev
)) {
154 if (exynos_crtc
->ops
->clear_channels
)
155 exynos_crtc
->ops
->clear_channels(exynos_crtc
);
156 return drm_iommu_attach_device(drm_dev
, subdrv_dev
);