Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

misc: fastrpc: Add support for new DSP IOVA formatting

Implement the new IOVA formatting required by the DSP architecture change
on Kaanapali SoC. Place the SID for DSP DMA transactions at bit 56 in the
physical address. This placement is necessary for the DSPs to correctly
identify streams and operate as intended.
To address this, set SID position to bit 56 via OF matching on the fastrpc
node; otherwise, default to legacy 32-bit placement.
This change ensures consistent SID placement across DSPs.

Signed-off-by: Kumari Pallavi <kumari.pallavi@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20251226070534.602021-4-kumari.pallavi@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Kumari Pallavi and committed by
Greg Kroah-Hartman
1d94ce89 428b2f2b

+51 -11
+51 -11
drivers/misc/fastrpc.c
··· 22 22 #include <linux/firmware/qcom/qcom_scm.h> 23 23 #include <uapi/misc/fastrpc.h> 24 24 #include <linux/of_reserved_mem.h> 25 + #include <linux/bits.h> 25 26 26 27 #define ADSP_DOMAIN_ID (0) 27 28 #define MDSP_DOMAIN_ID (1) ··· 34 33 #define FASTRPC_ALIGN 128 35 34 #define FASTRPC_MAX_FDLIST 16 36 35 #define FASTRPC_MAX_CRCLIST 64 37 - #define FASTRPC_PHYS(p) ((p) & 0xffffffff) 38 36 #define FASTRPC_CTX_MAX (256) 39 37 #define FASTRPC_INIT_HANDLE 1 40 38 #define FASTRPC_DSP_UTILITIES_HANDLE 2 ··· 257 257 bool valid; 258 258 }; 259 259 260 + struct fastrpc_soc_data { 261 + u32 sid_pos; 262 + }; 263 + 260 264 struct fastrpc_channel_ctx { 261 265 int domain_id; 262 266 int sesscount; ··· 282 278 bool secure; 283 279 bool unsigned_support; 284 280 u64 dma_mask; 281 + const struct fastrpc_soc_data *soc_data; 285 282 }; 286 283 287 284 struct fastrpc_device { ··· 309 304 /* lock for allocations */ 310 305 struct mutex mutex; 311 306 }; 307 + 308 + /* Extract SMMU PA from consolidated IOVA */ 309 + static inline dma_addr_t fastrpc_ipa_to_dma_addr(struct fastrpc_channel_ctx *cctx, dma_addr_t iova) 310 + { 311 + if (!cctx->soc_data->sid_pos) 312 + return 0; 313 + return iova & GENMASK_ULL(cctx->soc_data->sid_pos - 1, 0); 314 + } 315 + 316 + /* 317 + * Prepare the consolidated iova to send to DSP by prepending the SID 318 + * to smmu PA at the appropriate position 319 + */ 320 + static inline u64 fastrpc_sid_offset(struct fastrpc_channel_ctx *cctx, 321 + struct fastrpc_session_ctx *sctx) 322 + { 323 + return (u64)sctx->sid << cctx->soc_data->sid_pos; 324 + } 312 325 313 326 static void fastrpc_free_map(struct kref *ref) 314 327 { ··· 413 390 static void fastrpc_buf_free(struct fastrpc_buf *buf) 414 391 { 415 392 dma_free_coherent(buf->dev, buf->size, buf->virt, 416 - FASTRPC_PHYS(buf->dma_addr)); 393 + fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr)); 417 394 kfree(buf); 418 395 } 419 396 ··· 463 440 buf = *obuf; 464 441 465 442 if (fl->sctx && fl->sctx->sid) 466 - buf->dma_addr += ((u64)fl->sctx->sid << 32); 443 + buf->dma_addr += fastrpc_sid_offset(fl->cctx, fl->sctx); 467 444 468 445 return 0; 469 446 } ··· 708 685 return -ENOMEM; 709 686 710 687 ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt, 711 - FASTRPC_PHYS(buffer->dma_addr), buffer->size); 688 + fastrpc_ipa_to_dma_addr(buffer->fl->cctx, buffer->dma_addr), 689 + buffer->size); 712 690 if (ret < 0) { 713 691 dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); 714 692 kfree(a); ··· 758 734 dma_resv_assert_held(dmabuf->resv); 759 735 760 736 return dma_mmap_coherent(buf->dev, vma, buf->virt, 761 - FASTRPC_PHYS(buf->dma_addr), size); 737 + fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr), size); 762 738 } 763 739 764 740 static const struct dma_buf_ops fastrpc_dma_buf_ops = { ··· 770 746 .vmap = fastrpc_vmap, 771 747 .release = fastrpc_release, 772 748 }; 749 + 750 + static dma_addr_t fastrpc_compute_dma_addr(struct fastrpc_user *fl, dma_addr_t sg_dma_addr) 751 + { 752 + return sg_dma_addr + fastrpc_sid_offset(fl->cctx, fl->sctx); 753 + } 773 754 774 755 static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, 775 756 u64 len, u32 attr, struct fastrpc_map **ppmap) ··· 814 785 } 815 786 map->table = table; 816 787 817 - if (attr & FASTRPC_ATTR_SECUREMAP) { 788 + if (attr & FASTRPC_ATTR_SECUREMAP) 818 789 map->dma_addr = sg_phys(map->table->sgl); 819 - } else { 820 - map->dma_addr = sg_dma_address(map->table->sgl); 821 - map->dma_addr += ((u64)fl->sctx->sid << 32); 822 - } 790 + else 791 + map->dma_addr = fastrpc_compute_dma_addr(fl, sg_dma_address(map->table->sgl)); 823 792 for_each_sg(map->table->sgl, sgl, map->table->nents, 824 793 sgl_index) 825 794 map->size += sg_dma_len(sgl); ··· 2317 2290 return -EINVAL; 2318 2291 } 2319 2292 2293 + static const struct fastrpc_soc_data kaanapali_soc_data = { 2294 + .sid_pos = 56, 2295 + }; 2296 + 2297 + static const struct fastrpc_soc_data default_soc_data = { 2298 + .sid_pos = 32, 2299 + }; 2300 + 2320 2301 static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) 2321 2302 { 2322 2303 struct device *rdev = &rpdev->dev; ··· 2333 2298 const char *domain; 2334 2299 bool secure_dsp; 2335 2300 unsigned int vmids[FASTRPC_MAX_VMIDS]; 2301 + const struct fastrpc_soc_data *soc_data; 2302 + 2303 + soc_data = device_get_match_data(rdev); 2336 2304 2337 2305 err = of_property_read_string(rdev->of_node, "label", &domain); 2338 2306 if (err) { ··· 2388 2350 2389 2351 secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain")); 2390 2352 data->secure = secure_dsp; 2353 + data->soc_data = soc_data; 2391 2354 2392 2355 switch (domain_id) { 2393 2356 case ADSP_DOMAIN_ID: ··· 2526 2487 } 2527 2488 2528 2489 static const struct of_device_id fastrpc_rpmsg_of_match[] = { 2529 - { .compatible = "qcom,fastrpc" }, 2490 + { .compatible = "qcom,kaanapali-fastrpc", .data = &kaanapali_soc_data }, 2491 + { .compatible = "qcom,fastrpc", .data = &default_soc_data }, 2530 2492 { }, 2531 2493 }; 2532 2494 MODULE_DEVICE_TABLE(of, fastrpc_rpmsg_of_match);