1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Generic on-chip SRAM allocation driver 4 * 5 * Copyright (C) 2012 Philipp Zabel, Pengutronix 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/delay.h> 10 #include <linux/genalloc.h> 11 #include <linux/io.h> 12 #include <linux/list_sort.h> 13 #include <linux/of.h> 14 #include <linux/of_address.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 #include <linux/slab.h> 18 #include <linux/mfd/syscon.h> 19 #include <soc/at91/atmel-secumod.h> 20 21 #include "sram.h" 22 23 #define SRAM_GRANULARITY 32 24 25 static ssize_t sram_read(struct file *filp, struct kobject *kobj, 26 const struct bin_attribute *attr, 27 char *buf, loff_t pos, size_t count) 28 { 29 struct sram_partition *part; 30 31 /* Cast away the const as the attribute is part of a larger structure */ 32 part = (struct sram_partition *)container_of(attr, struct sram_partition, battr); 33 34 mutex_lock(&part->lock); 35 memcpy_fromio(buf, part->base + pos, count); 36 mutex_unlock(&part->lock); 37 38 return count; 39 } 40 41 static ssize_t sram_write(struct file *filp, struct kobject *kobj, 42 const struct bin_attribute *attr, 43 char *buf, loff_t pos, size_t count) 44 { 45 struct sram_partition *part; 46 47 /* Cast away the const as the attribute is part of a larger structure */ 48 part = (struct sram_partition *)container_of(attr, struct sram_partition, battr); 49 50 mutex_lock(&part->lock); 51 memcpy_toio(part->base + pos, buf, count); 52 mutex_unlock(&part->lock); 53 54 return count; 55 } 56 57 static int sram_add_pool(struct sram_dev *sram, struct sram_reserve *block, 58 phys_addr_t start, struct sram_partition *part) 59 { 60 int ret; 61 62 part->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY), 63 NUMA_NO_NODE, block->label); 64 if (IS_ERR(part->pool)) 65 return PTR_ERR(part->pool); 66 67 ret = gen_pool_add_virt(part->pool, (unsigned long)part->base, start, 68 block->size, NUMA_NO_NODE); 69 if (ret < 0) { 70 dev_err(sram->dev, "failed to register subpool: %d\n", ret); 71 return ret; 72 } 73 74 return 0; 75 } 76 77 static int sram_add_export(struct sram_dev *sram, struct sram_reserve *block, 78 phys_addr_t start, struct sram_partition *part) 79 { 80 sysfs_bin_attr_init(&part->battr); 81 part->battr.attr.name = devm_kasprintf(sram->dev, GFP_KERNEL, 82 "%llx.sram", 83 (unsigned long long)start); 84 if (!part->battr.attr.name) 85 return -ENOMEM; 86 87 part->battr.attr.mode = S_IRUSR | S_IWUSR; 88 part->battr.read = sram_read; 89 part->battr.write = sram_write; 90 part->battr.size = block->size; 91 92 return device_create_bin_file(sram->dev, &part->battr); 93 } 94 95 static int sram_add_partition(struct sram_dev *sram, struct sram_reserve *block, 96 phys_addr_t start) 97 { 98 int ret; 99 struct sram_partition *part = &sram->partition[sram->partitions]; 100 101 mutex_init(&part->lock); 102 103 if (sram->config && sram->config->map_only_reserved) { 104 void __iomem *virt_base; 105 106 if (sram->no_memory_wc) 107 virt_base = devm_ioremap_resource(sram->dev, &block->res); 108 else 109 virt_base = devm_ioremap_resource_wc(sram->dev, &block->res); 110 111 if (IS_ERR(virt_base)) { 112 dev_err(sram->dev, "could not map SRAM at %pr\n", &block->res); 113 return PTR_ERR(virt_base); 114 } 115 116 part->base = virt_base; 117 } else { 118 part->base = sram->virt_base + block->start; 119 } 120 121 if (block->pool) { 122 ret = sram_add_pool(sram, block, start, part); 123 if (ret) 124 return ret; 125 } 126 if (block->export) { 127 ret = sram_add_export(sram, block, start, part); 128 if (ret) 129 return ret; 130 } 131 if (block->protect_exec) { 132 ret = sram_check_protect_exec(sram, block, part); 133 if (ret) 134 return ret; 135 136 ret = sram_add_pool(sram, block, start, part); 137 if (ret) 138 return ret; 139 140 sram_add_protect_exec(part); 141 } 142 143 sram->partitions++; 144 145 return 0; 146 } 147 148 static void sram_free_partitions(struct sram_dev *sram) 149 { 150 struct sram_partition *part; 151 152 if (!sram->partitions) 153 return; 154 155 part = &sram->partition[sram->partitions - 1]; 156 for (; sram->partitions; sram->partitions--, part--) { 157 if (part->battr.size) 158 device_remove_bin_file(sram->dev, &part->battr); 159 160 if (part->pool && 161 gen_pool_avail(part->pool) < gen_pool_size(part->pool)) 162 dev_err(sram->dev, "removed pool while SRAM allocated\n"); 163 } 164 } 165 166 static int sram_reserve_cmp(void *priv, const struct list_head *a, 167 const struct list_head *b) 168 { 169 const struct sram_reserve *ra = list_entry(a, struct sram_reserve, list); 170 const struct sram_reserve *rb = list_entry(b, struct sram_reserve, list); 171 172 return ra->start - rb->start; 173 } 174 175 static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) 176 { 177 struct device_node *np = sram->dev->of_node, *child; 178 unsigned long size, cur_start, cur_size; 179 struct sram_reserve *rblocks, *block; 180 struct list_head reserve_list; 181 unsigned int nblocks, exports = 0; 182 const char *label; 183 int ret = 0; 184 185 INIT_LIST_HEAD(&reserve_list); 186 187 size = resource_size(res); 188 189 /* 190 * We need an additional block to mark the end of the memory region 191 * after the reserved blocks from the dt are processed. 192 */ 193 nblocks = (np) ? of_get_available_child_count(np) + 1 : 1; 194 rblocks = kzalloc_objs(*rblocks, nblocks); 195 if (!rblocks) 196 return -ENOMEM; 197 198 block = &rblocks[0]; 199 for_each_available_child_of_node(np, child) { 200 struct resource child_res; 201 202 ret = of_address_to_resource(child, 0, &child_res); 203 if (ret < 0) { 204 dev_err(sram->dev, 205 "could not get address for node %pOF\n", 206 child); 207 goto err_chunks; 208 } 209 210 if (child_res.start < res->start || child_res.end > res->end) { 211 dev_err(sram->dev, 212 "reserved block %pOF outside the sram area\n", 213 child); 214 ret = -EINVAL; 215 goto err_chunks; 216 } 217 218 block->start = child_res.start - res->start; 219 block->size = resource_size(&child_res); 220 block->res = child_res; 221 list_add_tail(&block->list, &reserve_list); 222 223 block->export = of_property_read_bool(child, "export"); 224 block->pool = of_property_read_bool(child, "pool"); 225 block->protect_exec = of_property_read_bool(child, "protect-exec"); 226 227 if ((block->export || block->pool || block->protect_exec) && 228 block->size) { 229 exports++; 230 231 label = NULL; 232 ret = of_property_read_string(child, "label", &label); 233 if (ret && ret != -EINVAL) { 234 dev_err(sram->dev, 235 "%pOF has invalid label name\n", 236 child); 237 goto err_chunks; 238 } 239 if (!label) 240 block->label = devm_kasprintf(sram->dev, GFP_KERNEL, 241 "%s", of_node_full_name(child)); 242 else 243 block->label = devm_kstrdup(sram->dev, 244 label, GFP_KERNEL); 245 if (!block->label) { 246 ret = -ENOMEM; 247 goto err_chunks; 248 } 249 250 dev_dbg(sram->dev, "found %sblock '%s' 0x%x-0x%x\n", 251 block->export ? "exported " : "", block->label, 252 block->start, block->start + block->size); 253 } else { 254 dev_dbg(sram->dev, "found reserved block 0x%x-0x%x\n", 255 block->start, block->start + block->size); 256 } 257 258 block++; 259 } 260 child = NULL; 261 262 /* the last chunk marks the end of the region */ 263 rblocks[nblocks - 1].start = size; 264 rblocks[nblocks - 1].size = 0; 265 list_add_tail(&rblocks[nblocks - 1].list, &reserve_list); 266 267 list_sort(NULL, &reserve_list, sram_reserve_cmp); 268 269 if (exports) { 270 sram->partition = devm_kzalloc_objs(sram->dev, *sram->partition, 271 exports); 272 if (!sram->partition) { 273 ret = -ENOMEM; 274 goto err_chunks; 275 } 276 } 277 278 cur_start = 0; 279 list_for_each_entry(block, &reserve_list, list) { 280 /* can only happen if sections overlap */ 281 if (block->start < cur_start) { 282 dev_err(sram->dev, 283 "block at 0x%x starts after current offset 0x%lx\n", 284 block->start, cur_start); 285 ret = -EINVAL; 286 sram_free_partitions(sram); 287 goto err_chunks; 288 } 289 290 if ((block->export || block->pool || block->protect_exec) && 291 block->size) { 292 ret = sram_add_partition(sram, block, 293 res->start + block->start); 294 if (ret) { 295 sram_free_partitions(sram); 296 goto err_chunks; 297 } 298 } 299 300 /* current start is in a reserved block, so continue after it */ 301 if (block->start == cur_start) { 302 cur_start = block->start + block->size; 303 continue; 304 } 305 306 /* 307 * allocate the space between the current starting 308 * address and the following reserved block, or the 309 * end of the region. 310 */ 311 cur_size = block->start - cur_start; 312 313 if (sram->pool) { 314 dev_dbg(sram->dev, "adding chunk 0x%lx-0x%lx\n", 315 cur_start, cur_start + cur_size); 316 317 ret = gen_pool_add_virt(sram->pool, 318 (unsigned long)sram->virt_base + cur_start, 319 res->start + cur_start, cur_size, -1); 320 if (ret < 0) { 321 sram_free_partitions(sram); 322 goto err_chunks; 323 } 324 } 325 326 /* next allocation after this reserved block */ 327 cur_start = block->start + block->size; 328 } 329 330 err_chunks: 331 of_node_put(child); 332 kfree(rblocks); 333 334 return ret; 335 } 336 337 static int atmel_securam_wait(void) 338 { 339 struct regmap *regmap; 340 u32 val; 341 342 regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-secumod"); 343 if (IS_ERR(regmap)) 344 return -ENODEV; 345 346 return regmap_read_poll_timeout(regmap, AT91_SECUMOD_RAMRDY, val, 347 val & AT91_SECUMOD_RAMRDY_READY, 348 10000, 500000); 349 } 350 351 static const struct sram_config atmel_securam_config = { 352 .init = atmel_securam_wait, 353 }; 354 355 /* 356 * SYSRAM contains areas that are not accessible by the 357 * kernel, such as the first 256K that is reserved for TZ. 358 * Accesses to those areas (including speculative accesses) 359 * trigger SErrors. As such we must map only the areas of 360 * SYSRAM specified in the device tree. 361 */ 362 static const struct sram_config tegra_sysram_config = { 363 .map_only_reserved = true, 364 }; 365 366 static const struct of_device_id sram_dt_ids[] = { 367 { .compatible = "mmio-sram" }, 368 { .compatible = "atmel,sama5d2-securam", .data = &atmel_securam_config }, 369 { .compatible = "nvidia,tegra186-sysram", .data = &tegra_sysram_config }, 370 { .compatible = "nvidia,tegra194-sysram", .data = &tegra_sysram_config }, 371 { .compatible = "nvidia,tegra234-sysram", .data = &tegra_sysram_config }, 372 { } 373 }; 374 375 static int sram_probe(struct platform_device *pdev) 376 { 377 const struct sram_config *config; 378 struct sram_dev *sram; 379 int ret; 380 struct resource *res; 381 struct clk *clk; 382 383 config = of_device_get_match_data(&pdev->dev); 384 385 sram = devm_kzalloc_obj(&pdev->dev, *sram); 386 if (!sram) 387 return -ENOMEM; 388 389 sram->dev = &pdev->dev; 390 sram->no_memory_wc = of_property_read_bool(pdev->dev.of_node, "no-memory-wc"); 391 sram->config = config; 392 393 if (!config || !config->map_only_reserved) { 394 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 395 if (sram->no_memory_wc) 396 sram->virt_base = devm_ioremap_resource(&pdev->dev, res); 397 else 398 sram->virt_base = devm_ioremap_resource_wc(&pdev->dev, res); 399 if (IS_ERR(sram->virt_base)) { 400 dev_err(&pdev->dev, "could not map SRAM registers\n"); 401 return PTR_ERR(sram->virt_base); 402 } 403 404 sram->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY), 405 NUMA_NO_NODE, NULL); 406 if (IS_ERR(sram->pool)) 407 return PTR_ERR(sram->pool); 408 } 409 410 clk = devm_clk_get_optional_enabled(sram->dev, NULL); 411 if (IS_ERR(clk)) 412 return PTR_ERR(clk); 413 414 ret = sram_reserve_regions(sram, 415 platform_get_resource(pdev, IORESOURCE_MEM, 0)); 416 if (ret) 417 return ret; 418 419 platform_set_drvdata(pdev, sram); 420 421 if (config && config->init) { 422 ret = config->init(); 423 if (ret) 424 goto err_free_partitions; 425 } 426 427 if (sram->pool) 428 dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n", 429 gen_pool_size(sram->pool) / 1024, sram->virt_base); 430 431 return 0; 432 433 err_free_partitions: 434 sram_free_partitions(sram); 435 436 return ret; 437 } 438 439 static void sram_remove(struct platform_device *pdev) 440 { 441 struct sram_dev *sram = platform_get_drvdata(pdev); 442 443 sram_free_partitions(sram); 444 445 if (sram->pool && gen_pool_avail(sram->pool) < gen_pool_size(sram->pool)) 446 dev_err(sram->dev, "removed while SRAM allocated\n"); 447 } 448 449 static struct platform_driver sram_driver = { 450 .driver = { 451 .name = "sram", 452 .of_match_table = sram_dt_ids, 453 }, 454 .probe = sram_probe, 455 .remove = sram_remove, 456 }; 457 458 static int __init sram_init(void) 459 { 460 return platform_driver_register(&sram_driver); 461 } 462 463 postcore_initcall(sram_init); 464