Lines Matching full:smem
16 #include <linux/soc/qcom/smem.h>
38 * (@smem_ptable), that is found 4kB from the end of the main smem region. The
55 * region with partition type (SMEM_GLOBAL_HOST) and the max smem item count is
65 * The version member of the smem header contains an array of versions for the
104 * struct smem_global_entry - entry to reference smem items on the heap
120 * struct smem_header - header found in beginning of primary smem region
123 * @initialized: boolean to indicate that smem is initialized
124 * @free_offset: index of the first unallocated byte in smem
200 * struct smem_partition - describes smem partition
218 * @item: identifying number of the smem item
235 * struct smem_info - smem region info located after the table of contents
237 * @size: size of the smem region
238 * @base_addr: base address of the smem region
253 * struct smem_region - representation of a chunk of memory used for smem
265 * struct qcom_smem - device data for the smem device
356 /* Pointer to the one and only smem handle */
362 /* The qcom hwspinlock id is always plus one from the smem host id */
366 * qcom_smem_bust_hwspin_lock_by_host() - bust the smem hwspinlock for a host
369 * Busts the hwspin_lock for the given smem host id. This helper is intended
370 * for remoteproc drivers that manage remoteprocs with an equivalent smem
372 * smem hwspin_lock if the rproc unexpectedly goes into a bad state.
389 * qcom_smem_is_available() - Check if SMEM is available
391 * Return: true if SMEM is available, false otherwise.
399 static int qcom_smem_alloc_private(struct qcom_smem *smem, in qcom_smem_alloc_private() argument
435 dev_err(smem->dev, "Out of memory\n"); in qcom_smem_alloc_private()
455 dev_err(smem->dev, "Found invalid canary in hosts %hu:%hu partition\n", in qcom_smem_alloc_private()
461 static int qcom_smem_alloc_global(struct qcom_smem *smem, in qcom_smem_alloc_global() argument
468 header = smem->regions[0].virt_base; in qcom_smem_alloc_global()
495 * qcom_smem_alloc() - allocate space for a smem item
497 * @item: smem item handle
500 * Allocate space for a given smem item of size @size, given that the item is
545 static void *qcom_smem_get_global(struct qcom_smem *smem, in qcom_smem_get_global() argument
557 header = smem->regions[0].virt_base; in qcom_smem_get_global()
564 for (i = 0; i < smem->num_regions; i++) { in qcom_smem_get_global()
565 region = &smem->regions[i]; in qcom_smem_get_global()
584 static void *qcom_smem_get_private(struct qcom_smem *smem, in qcom_smem_get_private() argument
668 dev_err(smem->dev, "Found invalid canary in hosts %hu:%hu partition\n", in qcom_smem_get_private()
675 * qcom_smem_get() - resolve ptr of size of a smem item
677 * @item: smem item handle
680 * Looks up smem item and returns pointer to it. Size of smem
683 * Return: a pointer to an SMEM item on success, ERR_PTR() on failure.
714 * To be used by smem clients as a quick way to determine if any new
764 * with an smem item pointer (previously returned by qcom_smem_get()
767 * Return: physical address of the SMEM item (if found), 0 otherwise
834 * Look up the feature code identifier from SMEM and return it.
863 static int qcom_smem_get_sbl_version(struct qcom_smem *smem) in qcom_smem_get_sbl_version() argument
868 header = smem->regions[0].virt_base; in qcom_smem_get_sbl_version()
874 static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem) in qcom_smem_get_ptable() argument
879 ptable = smem->ptable; in qcom_smem_get_ptable()
885 dev_err(smem->dev, in qcom_smem_get_ptable()
892 static u32 qcom_smem_get_item_count(struct qcom_smem *smem) in qcom_smem_get_item_count() argument
897 ptable = qcom_smem_get_ptable(smem); in qcom_smem_get_item_count()
914 qcom_smem_partition_header(struct qcom_smem *smem, in qcom_smem_partition_header() argument
921 phys_addr = smem->regions[0].aux_base + le32_to_cpu(entry->offset); in qcom_smem_partition_header()
922 header = devm_ioremap_wc(smem->dev, phys_addr, le32_to_cpu(entry->size)); in qcom_smem_partition_header()
928 dev_err(smem->dev, "bad partition magic %4ph\n", header->magic); in qcom_smem_partition_header()
933 dev_err(smem->dev, "bad host0 (%hu != %hu)\n", in qcom_smem_partition_header()
938 dev_err(smem->dev, "bad host1 (%hu != %hu)\n", in qcom_smem_partition_header()
945 dev_err(smem->dev, "bad partition size (%u != %u)\n", in qcom_smem_partition_header()
951 dev_err(smem->dev, "bad partition free uncached (%u > %u)\n", in qcom_smem_partition_header()
959 static int qcom_smem_set_global_partition(struct qcom_smem *smem) in qcom_smem_set_global_partition() argument
967 if (smem->global_partition.virt_base) { in qcom_smem_set_global_partition()
968 dev_err(smem->dev, "Already found the global partition\n"); in qcom_smem_set_global_partition()
972 ptable = qcom_smem_get_ptable(smem); in qcom_smem_set_global_partition()
993 dev_err(smem->dev, "Missing entry for global partition\n"); in qcom_smem_set_global_partition()
997 header = qcom_smem_partition_header(smem, entry, in qcom_smem_set_global_partition()
1002 smem->global_partition.virt_base = (void __iomem *)header; in qcom_smem_set_global_partition()
1003 smem->global_partition.phys_base = smem->regions[0].aux_base + in qcom_smem_set_global_partition()
1005 smem->global_partition.size = le32_to_cpu(entry->size); in qcom_smem_set_global_partition()
1006 smem->global_partition.cacheline = le32_to_cpu(entry->cacheline); in qcom_smem_set_global_partition()
1012 qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) in qcom_smem_enumerate_partitions() argument
1021 ptable = qcom_smem_get_ptable(smem); in qcom_smem_enumerate_partitions()
1042 dev_err(smem->dev, "bad host %u\n", remote_host); in qcom_smem_enumerate_partitions()
1046 if (smem->partitions[remote_host].virt_base) { in qcom_smem_enumerate_partitions()
1047 dev_err(smem->dev, "duplicate host %u\n", remote_host); in qcom_smem_enumerate_partitions()
1051 header = qcom_smem_partition_header(smem, entry, host0, host1); in qcom_smem_enumerate_partitions()
1055 smem->partitions[remote_host].virt_base = (void __iomem *)header; in qcom_smem_enumerate_partitions()
1056 smem->partitions[remote_host].phys_base = smem->regions[0].aux_base + in qcom_smem_enumerate_partitions()
1058 smem->partitions[remote_host].size = le32_to_cpu(entry->size); in qcom_smem_enumerate_partitions()
1059 smem->partitions[remote_host].cacheline = le32_to_cpu(entry->cacheline); in qcom_smem_enumerate_partitions()
1065 static int qcom_smem_map_toc(struct qcom_smem *smem, struct smem_region *region) in qcom_smem_map_toc() argument
1069 /* map starting 4K for smem header */ in qcom_smem_map_toc()
1070 region->virt_base = devm_ioremap_wc(smem->dev, region->aux_base, SZ_4K); in qcom_smem_map_toc()
1073 smem->ptable = devm_ioremap_wc(smem->dev, ptable_start, SZ_4K); in qcom_smem_map_toc()
1075 if (!region->virt_base || !smem->ptable) in qcom_smem_map_toc()
1081 static int qcom_smem_map_global(struct qcom_smem *smem, u32 size) in qcom_smem_map_global() argument
1085 phys_addr = smem->regions[0].aux_base; in qcom_smem_map_global()
1087 smem->regions[0].size = size; in qcom_smem_map_global()
1088 smem->regions[0].virt_base = devm_ioremap_wc(smem->dev, phys_addr, size); in qcom_smem_map_global()
1090 if (!smem->regions[0].virt_base) in qcom_smem_map_global()
1096 static int qcom_smem_resolve_mem(struct qcom_smem *smem, const char *name, in qcom_smem_resolve_mem() argument
1099 struct device *dev = smem->dev; in qcom_smem_resolve_mem()
1125 struct qcom_smem *smem; in qcom_smem_probe() local
1138 smem = devm_kzalloc(&pdev->dev, struct_size(smem, regions, num_regions), in qcom_smem_probe()
1140 if (!smem) in qcom_smem_probe()
1143 smem->dev = &pdev->dev; in qcom_smem_probe()
1144 smem->num_regions = num_regions; in qcom_smem_probe()
1148 smem->regions[0].aux_base = rmem->base; in qcom_smem_probe()
1149 smem->regions[0].size = rmem->size; in qcom_smem_probe()
1155 ret = qcom_smem_resolve_mem(smem, "memory-region", &smem->regions[0]); in qcom_smem_probe()
1161 ret = qcom_smem_resolve_mem(smem, "qcom,rpm-msg-ram", &smem->regions[1]); in qcom_smem_probe()
1167 ret = qcom_smem_map_toc(smem, &smem->regions[0]); in qcom_smem_probe()
1172 smem->regions[i].virt_base = devm_ioremap_wc(&pdev->dev, in qcom_smem_probe()
1173 smem->regions[i].aux_base, in qcom_smem_probe()
1174 smem->regions[i].size); in qcom_smem_probe()
1175 if (!smem->regions[i].virt_base) { in qcom_smem_probe()
1176 dev_err(&pdev->dev, "failed to remap %pa\n", &smem->regions[i].aux_base); in qcom_smem_probe()
1181 header = smem->regions[0].virt_base; in qcom_smem_probe()
1184 dev_err(&pdev->dev, "SMEM is not initialized by SBL\n"); in qcom_smem_probe()
1193 smem->hwlock = hwspin_lock_request_specific(hwlock_id); in qcom_smem_probe()
1194 if (!smem->hwlock) in qcom_smem_probe()
1197 ret = hwspin_lock_timeout_irqsave(smem->hwlock, HWSPINLOCK_TIMEOUT, &flags); in qcom_smem_probe()
1201 hwspin_unlock_irqrestore(smem->hwlock, &flags); in qcom_smem_probe()
1203 version = qcom_smem_get_sbl_version(smem); in qcom_smem_probe()
1205 * smem header mapping is required only in heap version scheme, so unmap in qcom_smem_probe()
1209 devm_iounmap(smem->dev, smem->regions[0].virt_base); in qcom_smem_probe()
1212 ret = qcom_smem_set_global_partition(smem); in qcom_smem_probe()
1215 smem->item_count = qcom_smem_get_item_count(smem); in qcom_smem_probe()
1218 qcom_smem_map_global(smem, size); in qcom_smem_probe()
1219 smem->item_count = SMEM_ITEM_COUNT; in qcom_smem_probe()
1222 dev_err(&pdev->dev, "Unsupported SMEM version 0x%x\n", version); in qcom_smem_probe()
1227 ret = qcom_smem_enumerate_partitions(smem, SMEM_HOST_APPS); in qcom_smem_probe()
1231 __smem = smem; in qcom_smem_probe()
1233 smem->socinfo = platform_device_register_data(&pdev->dev, "qcom-socinfo", in qcom_smem_probe()
1236 if (IS_ERR(smem->socinfo)) in qcom_smem_probe()
1251 { .compatible = "qcom,smem" },
1260 .name = "qcom-smem",