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
;
39 if (!priv
->da_space_order
)
40 priv
->da_space_order
= EXYNOS_DEV_ADDR_ORDER
;
42 mapping
= arm_iommu_create_mapping(&platform_bus_type
, priv
->da_start
,
44 priv
->da_space_order
);
46 return PTR_ERR(mapping
);
48 dev
->dma_parms
= devm_kzalloc(dev
, sizeof(*dev
->dma_parms
),
53 dma_set_max_seg_size(dev
, 0xffffffffu
);
54 dev
->archdata
.mapping
= mapping
;
58 arm_iommu_release_mapping(mapping
);
63 * drm_release_iommu_mapping - release iommu mapping structure
65 * @drm_dev: DRM device
67 * if mapping->kref becomes 0 then all things related to iommu mapping
70 void drm_release_iommu_mapping(struct drm_device
*drm_dev
)
72 struct device
*dev
= drm_dev
->dev
;
74 arm_iommu_release_mapping(dev
->archdata
.mapping
);
78 * drm_iommu_attach_device- attach device to iommu mapping
80 * @drm_dev: DRM device
81 * @subdrv_dev: device to be attach
83 * This function should be called by sub drivers to attach it to iommu
86 int drm_iommu_attach_device(struct drm_device
*drm_dev
,
87 struct device
*subdrv_dev
)
89 struct device
*dev
= drm_dev
->dev
;
92 if (!dev
->archdata
.mapping
) {
93 DRM_ERROR("iommu_mapping is null.\n");
97 subdrv_dev
->dma_parms
= devm_kzalloc(subdrv_dev
,
98 sizeof(*subdrv_dev
->dma_parms
),
100 if (!subdrv_dev
->dma_parms
)
103 dma_set_max_seg_size(subdrv_dev
, 0xffffffffu
);
105 ret
= arm_iommu_attach_device(subdrv_dev
, dev
->archdata
.mapping
);
107 DRM_DEBUG_KMS("failed iommu attach.\n");
112 * Set dma_ops to drm_device just one time.
114 * The dma mapping api needs device object and the api is used
115 * to allocate physial memory and map it with iommu table.
116 * If iommu attach succeeded, the sub driver would have dma_ops
117 * for iommu and also all sub drivers have same dma_ops.
119 if (!dev
->archdata
.dma_ops
)
120 dev
->archdata
.dma_ops
= subdrv_dev
->archdata
.dma_ops
;
126 * drm_iommu_detach_device -detach device address space mapping from device
128 * @drm_dev: DRM device
129 * @subdrv_dev: device to be detached
131 * This function should be called by sub drivers to detach it from iommu
134 void drm_iommu_detach_device(struct drm_device
*drm_dev
,
135 struct device
*subdrv_dev
)
137 struct device
*dev
= drm_dev
->dev
;
138 struct dma_iommu_mapping
*mapping
= dev
->archdata
.mapping
;
140 if (!mapping
|| !mapping
->domain
)
143 iommu_detach_device(mapping
->domain
, subdrv_dev
);
144 drm_release_iommu_mapping(drm_dev
);