• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sunxi_drm_iommu.h
2  *
3  * Copyright (C) 2022 Allwinnertech Co., Ltd.
4  * Authors: hongyaobin <hongyaobin@allwinnertech.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 
12 #ifndef _SUNXI_DRM_IOMMU_H_
13 #define _SUNXI_DRM_IOMMU_H_
14 
15 #ifdef CONFIG_AW_DRM_IOMMU
16 
17 #if defined(CONFIG_ARM_DMA_USE_IOMMU)
18 #include <asm/dma-iommu.h>
19 
__sunxi_iommu_create_mapping(struct sunxi_drm_private * priv,unsigned long start,unsigned long size)20 static inline int __sunxi_iommu_create_mapping(struct sunxi_drm_private *priv,
21 					unsigned long start, unsigned long size)
22 {
23 	DRM_INFO("[DRM-DRV] %s:arm_iommu_create_mapping\n", __func__);
24 	priv->mapping = arm_iommu_create_mapping(&platform_bus_type, start,
25 						 size);
26 	return IS_ERR(priv->mapping);
27 }
28 
29 static inline void
__sunxi_iommu_release_mapping(struct sunxi_drm_private * priv)30 __sunxi_iommu_release_mapping(struct sunxi_drm_private *priv)
31 {
32 	arm_iommu_release_mapping(priv->mapping);
33 }
34 
__sunxi_iommu_attach(struct sunxi_drm_private * priv,struct device * dev)35 static inline int __sunxi_iommu_attach(struct sunxi_drm_private *priv,
36 					struct device *dev)
37 {
38 	if (dev->archdata.mapping)
39 		arm_iommu_detach_device(dev);
40 
41 	return arm_iommu_attach_device(dev, priv->mapping);
42 }
43 
__sunxi_iommu_detach(struct sunxi_drm_private * priv,struct device * dev)44 static inline void __sunxi_iommu_detach(struct sunxi_drm_private *priv,
45 					 struct device *dev)
46 {
47 	arm_iommu_detach_device(dev);
48 }
49 
50 #elif defined(CONFIG_IOMMU_DMA)
51 #include <linux/dma-iommu.h>
52 
__sunxi_iommu_create_mapping(struct sunxi_drm_private * priv,unsigned long start,unsigned long size)53 static inline int __sunxi_iommu_create_mapping(struct sunxi_drm_private *priv,
54 					unsigned long start, unsigned long size)
55 {
56 	DRM_INFO("[DRM-DRV] %s\n", __func__);
57 	priv->mapping = iommu_get_domain_for_dev(priv->drm_dev->dev);
58 	if (priv->mapping == NULL)
59 		return -1;
60 	else
61 		return 0;
62 }
63 
__sunxi_iommu_release_mapping(struct sunxi_drm_private * priv)64 static inline void __sunxi_iommu_release_mapping(struct sunxi_drm_private *priv)
65 {
66 	priv->mapping = NULL;
67 }
68 
__sunxi_iommu_attach(struct sunxi_drm_private * priv,struct device * dev)69 static inline int __sunxi_iommu_attach(struct sunxi_drm_private *priv,
70 					struct device *dev)
71 {
72 	struct iommu_domain *domain = priv->mapping;
73 
74 	if (dev != priv->drm_dev->dev)
75 		return iommu_attach_device(domain, dev);
76 	return 0;
77 }
78 
__sunxi_iommu_detach(struct sunxi_drm_private * priv,struct device * dev)79 static inline void __sunxi_iommu_detach(struct sunxi_drm_private *priv,
80 					 struct device *dev)
81 {
82 	struct iommu_domain *domain = priv->mapping;
83 
84 	if (dev != priv->drm_dev->dev)
85 		iommu_detach_device(domain, dev);
86 }
87 #else
88 #error Unsupported architecture and IOMMU/DMA-mapping glue code
89 #endif
90 
91 int sunxi_drm_create_iommu_mapping(struct drm_device *drm_dev);
92 
93 void sunxi_drm_release_iommu_mapping(struct drm_device *drm_dev);
94 
95 int sunxi_drm_iommu_attach_device(struct drm_device *drm_dev,
96 				struct device *subdrv_dev);
97 
98 void sunxi_drm_iommu_detach_device(struct drm_device *dev_dev,
99 				struct device *subdrv_dev);
100 
is_drm_iommu_supported(struct drm_device * drm_dev)101 static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
102 {
103 	struct sunxi_drm_private *priv = drm_dev->dev_private;
104 
105 	return priv->mapping ? true : false;
106 }
107 
108 #else
109 
sunxi_drm_create_iommu_mapping(struct drm_device * drm_dev)110 static inline int sunxi_drm_create_iommu_mapping(struct drm_device *drm_dev)
111 {
112 	return 0;
113 }
114 
sunxi_drm_release_iommu_mapping(struct drm_device * drm_dev)115 static inline void sunxi_drm_release_iommu_mapping(struct drm_device *drm_dev)
116 {
117 }
118 
sunxi_drm_iommu_attach_device(struct drm_device * drm_dev,struct device * subdrv_dev)119 static inline int sunxi_drm_iommu_attach_device(struct drm_device *drm_dev,
120 						struct device *subdrv_dev)
121 {
122 	return 0;
123 }
124 
sunxi_drm_iommu_detach_device(struct drm_device * drm_dev,struct device * subdrv_dev)125 static inline void sunxi_drm_iommu_detach_device(struct drm_device *drm_dev,
126 						struct device *subdrv_dev)
127 {
128 }
129 
is_drm_iommu_supported(struct drm_device * drm_dev)130 static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
131 {
132 	return false;
133 }
134 
135 #endif
136 #endif
137