1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 /* 3 * Apple SART device driver 4 * Copyright (C) The Asahi Linux Contributors 5 * 6 * Apple SART is a simple address filter for some DMA transactions. 7 * Regions of physical memory must be added to the SART's allow 8 * list before any DMA can target these. Unlike a proper 9 * IOMMU no remapping can be done and special support in the 10 * consumer driver is required since not all DMA transactions of 11 * a single device are subject to SART filtering. 12 */ 13 14 #include <linux/soc/apple/sart.h> 15 #include <linux/atomic.h> 16 #include <linux/bits.h> 17 #include <linux/bitfield.h> 18 #include <linux/device.h> 19 #include <linux/io.h> 20 #include <linux/module.h> 21 #include <linux/of.h> 22 #include <linux/of_platform.h> 23 #include <linux/platform_device.h> 24 #include <linux/types.h> 25 26 #define APPLE_SART_MAX_ENTRIES 16 27 28 /* This is probably a bitfield but the exact meaning of each bit is unknown. */ 29 #define APPLE_SART_FLAGS_ALLOW 0xff 30 31 /* SARTv2 registers */ 32 #define APPLE_SART2_CONFIG(idx) (0x00 + 4 * (idx)) 33 #define APPLE_SART2_CONFIG_FLAGS GENMASK(31, 24) 34 #define APPLE_SART2_CONFIG_SIZE GENMASK(23, 0) 35 #define APPLE_SART2_CONFIG_SIZE_SHIFT 12 36 #define APPLE_SART2_CONFIG_SIZE_MAX GENMASK(23, 0) 37 38 #define APPLE_SART2_PADDR(idx) (0x40 + 4 * (idx)) 39 #define APPLE_SART2_PADDR_SHIFT 12 40 41 /* SARTv3 registers */ 42 #define APPLE_SART3_CONFIG(idx) (0x00 + 4 * (idx)) 43 44 #define APPLE_SART3_PADDR(idx) (0x40 + 4 * (idx)) 45 #define APPLE_SART3_PADDR_SHIFT 12 46 47 #define APPLE_SART3_SIZE(idx) (0x80 + 4 * (idx)) 48 #define APPLE_SART3_SIZE_SHIFT 12 49 #define APPLE_SART3_SIZE_MAX GENMASK(29, 0) 50 51 struct apple_sart_ops { 52 void (*get_entry)(struct apple_sart *sart, int index, u8 *flags, 53 phys_addr_t *paddr, size_t *size); 54 void (*set_entry)(struct apple_sart *sart, int index, u8 flags, 55 phys_addr_t paddr_shifted, size_t size_shifted); 56 unsigned int size_shift; 57 unsigned int paddr_shift; 58 size_t size_max; 59 }; 60 61 struct apple_sart { 62 struct device *dev; 63 void __iomem *regs; 64 65 const struct apple_sart_ops *ops; 66 67 unsigned long protected_entries; 68 unsigned long used_entries; 69 }; 70 71 static void sart2_get_entry(struct apple_sart *sart, int index, u8 *flags, 72 phys_addr_t *paddr, size_t *size) 73 { 74 u32 cfg = readl(sart->regs + APPLE_SART2_CONFIG(index)); 75 phys_addr_t paddr_ = readl(sart->regs + APPLE_SART2_PADDR(index)); 76 size_t size_ = FIELD_GET(APPLE_SART2_CONFIG_SIZE, cfg); 77 78 *flags = FIELD_GET(APPLE_SART2_CONFIG_FLAGS, cfg); 79 *size = size_ << APPLE_SART2_CONFIG_SIZE_SHIFT; 80 *paddr = paddr_ << APPLE_SART2_PADDR_SHIFT; 81 } 82 83 static void sart2_set_entry(struct apple_sart *sart, int index, u8 flags, 84 phys_addr_t paddr_shifted, size_t size_shifted) 85 { 86 u32 cfg; 87 88 cfg = FIELD_PREP(APPLE_SART2_CONFIG_FLAGS, flags); 89 cfg |= FIELD_PREP(APPLE_SART2_CONFIG_SIZE, size_shifted); 90 91 writel(paddr_shifted, sart->regs + APPLE_SART2_PADDR(index)); 92 writel(cfg, sart->regs + APPLE_SART2_CONFIG(index)); 93 } 94 95 static struct apple_sart_ops sart_ops_v2 = { 96 .get_entry = sart2_get_entry, 97 .set_entry = sart2_set_entry, 98 .size_shift = APPLE_SART2_CONFIG_SIZE_SHIFT, 99 .paddr_shift = APPLE_SART2_PADDR_SHIFT, 100 .size_max = APPLE_SART2_CONFIG_SIZE_MAX, 101 }; 102 103 static void sart3_get_entry(struct apple_sart *sart, int index, u8 *flags, 104 phys_addr_t *paddr, size_t *size) 105 { 106 phys_addr_t paddr_ = readl(sart->regs + APPLE_SART3_PADDR(index)); 107 size_t size_ = readl(sart->regs + APPLE_SART3_SIZE(index)); 108 109 *flags = readl(sart->regs + APPLE_SART3_CONFIG(index)); 110 *size = size_ << APPLE_SART3_SIZE_SHIFT; 111 *paddr = paddr_ << APPLE_SART3_PADDR_SHIFT; 112 } 113 114 static void sart3_set_entry(struct apple_sart *sart, int index, u8 flags, 115 phys_addr_t paddr_shifted, size_t size_shifted) 116 { 117 writel(paddr_shifted, sart->regs + APPLE_SART3_PADDR(index)); 118 writel(size_shifted, sart->regs + APPLE_SART3_SIZE(index)); 119 writel(flags, sart->regs + APPLE_SART3_CONFIG(index)); 120 } 121 122 static struct apple_sart_ops sart_ops_v3 = { 123 .get_entry = sart3_get_entry, 124 .set_entry = sart3_set_entry, 125 .size_shift = APPLE_SART3_SIZE_SHIFT, 126 .paddr_shift = APPLE_SART3_PADDR_SHIFT, 127 .size_max = APPLE_SART3_SIZE_MAX, 128 }; 129 130 static int apple_sart_probe(struct platform_device *pdev) 131 { 132 int i; 133 struct apple_sart *sart; 134 struct device *dev = &pdev->dev; 135 136 sart = devm_kzalloc(dev, sizeof(*sart), GFP_KERNEL); 137 if (!sart) 138 return -ENOMEM; 139 140 sart->dev = dev; 141 sart->ops = of_device_get_match_data(dev); 142 143 sart->regs = devm_platform_ioremap_resource(pdev, 0); 144 if (IS_ERR(sart->regs)) 145 return PTR_ERR(sart->regs); 146 147 for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) { 148 u8 flags; 149 size_t size; 150 phys_addr_t paddr; 151 152 sart->ops->get_entry(sart, i, &flags, &paddr, &size); 153 154 if (!flags) 155 continue; 156 157 dev_dbg(sart->dev, 158 "SART bootloader entry: index %02d; flags: 0x%02x; paddr: %pa; size: 0x%zx\n", 159 i, flags, &paddr, size); 160 set_bit(i, &sart->protected_entries); 161 } 162 163 platform_set_drvdata(pdev, sart); 164 return 0; 165 } 166 167 static void apple_sart_put_device(void *dev) 168 { 169 put_device(dev); 170 } 171 172 struct apple_sart *devm_apple_sart_get(struct device *dev) 173 { 174 struct device_node *sart_node; 175 struct platform_device *sart_pdev; 176 struct apple_sart *sart; 177 int ret; 178 179 sart_node = of_parse_phandle(dev->of_node, "apple,sart", 0); 180 if (!sart_node) 181 return ERR_PTR(-ENODEV); 182 183 sart_pdev = of_find_device_by_node(sart_node); 184 of_node_put(sart_node); 185 186 if (!sart_pdev) 187 return ERR_PTR(-ENODEV); 188 189 sart = dev_get_drvdata(&sart_pdev->dev); 190 if (!sart) { 191 put_device(&sart_pdev->dev); 192 return ERR_PTR(-EPROBE_DEFER); 193 } 194 195 ret = devm_add_action_or_reset(dev, apple_sart_put_device, 196 &sart_pdev->dev); 197 if (ret) 198 return ERR_PTR(ret); 199 200 device_link_add(dev, &sart_pdev->dev, 201 DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER); 202 203 return sart; 204 } 205 EXPORT_SYMBOL_GPL(devm_apple_sart_get); 206 207 static int sart_set_entry(struct apple_sart *sart, int index, u8 flags, 208 phys_addr_t paddr, size_t size) 209 { 210 if (size & ((1 << sart->ops->size_shift) - 1)) 211 return -EINVAL; 212 if (paddr & ((1 << sart->ops->paddr_shift) - 1)) 213 return -EINVAL; 214 215 paddr >>= sart->ops->size_shift; 216 size >>= sart->ops->paddr_shift; 217 218 if (size > sart->ops->size_max) 219 return -EINVAL; 220 221 sart->ops->set_entry(sart, index, flags, paddr, size); 222 return 0; 223 } 224 225 int apple_sart_add_allowed_region(struct apple_sart *sart, phys_addr_t paddr, 226 size_t size) 227 { 228 int i, ret; 229 230 for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) { 231 if (test_bit(i, &sart->protected_entries)) 232 continue; 233 if (test_and_set_bit(i, &sart->used_entries)) 234 continue; 235 236 ret = sart_set_entry(sart, i, APPLE_SART_FLAGS_ALLOW, paddr, 237 size); 238 if (ret) { 239 dev_dbg(sart->dev, 240 "unable to set entry %d to [%pa, 0x%zx]\n", 241 i, &paddr, size); 242 clear_bit(i, &sart->used_entries); 243 return ret; 244 } 245 246 dev_dbg(sart->dev, "wrote [%pa, 0x%zx] to %d\n", &paddr, size, 247 i); 248 return 0; 249 } 250 251 dev_warn(sart->dev, 252 "no free entries left to add [paddr: 0x%pa, size: 0x%zx]\n", 253 &paddr, size); 254 255 return -EBUSY; 256 } 257 EXPORT_SYMBOL_GPL(apple_sart_add_allowed_region); 258 259 int apple_sart_remove_allowed_region(struct apple_sart *sart, phys_addr_t paddr, 260 size_t size) 261 { 262 int i; 263 264 dev_dbg(sart->dev, 265 "will remove [paddr: %pa, size: 0x%zx] from allowed regions\n", 266 &paddr, size); 267 268 for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) { 269 u8 eflags; 270 size_t esize; 271 phys_addr_t epaddr; 272 273 if (test_bit(i, &sart->protected_entries)) 274 continue; 275 276 sart->ops->get_entry(sart, i, &eflags, &epaddr, &esize); 277 278 if (epaddr != paddr || esize != size) 279 continue; 280 281 sart->ops->set_entry(sart, i, 0, 0, 0); 282 283 clear_bit(i, &sart->used_entries); 284 dev_dbg(sart->dev, "cleared entry %d\n", i); 285 return 0; 286 } 287 288 dev_warn(sart->dev, "entry [paddr: 0x%pa, size: 0x%zx] not found\n", 289 &paddr, size); 290 291 return -EINVAL; 292 } 293 EXPORT_SYMBOL_GPL(apple_sart_remove_allowed_region); 294 295 static void apple_sart_shutdown(struct platform_device *pdev) 296 { 297 struct apple_sart *sart = dev_get_drvdata(&pdev->dev); 298 int i; 299 300 for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) { 301 if (test_bit(i, &sart->protected_entries)) 302 continue; 303 304 sart->ops->set_entry(sart, i, 0, 0, 0); 305 } 306 } 307 308 static const struct of_device_id apple_sart_of_match[] = { 309 { 310 .compatible = "apple,t6000-sart", 311 .data = &sart_ops_v3, 312 }, 313 { 314 .compatible = "apple,t8103-sart", 315 .data = &sart_ops_v2, 316 }, 317 {} 318 }; 319 MODULE_DEVICE_TABLE(of, apple_sart_of_match); 320 321 static struct platform_driver apple_sart_driver = { 322 .driver = { 323 .name = "apple-sart", 324 .of_match_table = apple_sart_of_match, 325 }, 326 .probe = apple_sart_probe, 327 .shutdown = apple_sart_shutdown, 328 }; 329 module_platform_driver(apple_sart_driver); 330 331 MODULE_LICENSE("Dual MIT/GPL"); 332 MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>"); 333 MODULE_DESCRIPTION("Apple SART driver"); 334