Loading drivers/soc/qcom/pil-msa.c +76 −130 Original line number Diff line number Diff line Loading @@ -320,27 +320,18 @@ int __pil_mss_deinit_image(struct pil_desc *pil, bool err_path) if (q6_drv->ahb_clk_vote) clk_disable_unprepare(q6_drv->ahb_clk); /* In case of any failure where reclaim MBA memory /* In case of any failure where reclaiming MBA and DP memory * could not happen, free the memory here */ if (drv->q6->mba_virt) { if (drv->q6->mba_dp_virt) { if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->mba_phys, drv->q6->mba_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_size, drv->q6->mba_virt, drv->q6->mba_phys, pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys, drv->q6->mba_dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size, drv->q6->mba_dp_virt, drv->q6->mba_dp_phys, &drv->attrs_dma); drv->q6->mba_virt = NULL; drv->q6->mba_dp_virt = NULL; } if (drv->q6->dp_virt) { if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->dp_phys, drv->q6->dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->dp_size, drv->q6->dp_virt, drv->q6->dp_phys, &drv->attrs_dma); drv->q6->dp_virt = NULL; } return ret; } Loading Loading @@ -397,8 +388,8 @@ static int pil_mss_reset(struct pil_desc *pil) phys_addr_t start_addr = pil_get_entry_addr(pil); int ret; if (drv->mba_phys) start_addr = drv->mba_phys; if (drv->mba_dp_phys) start_addr = drv->mba_dp_phys; /* * Bring subsystem out of reset and enable required Loading Loading @@ -434,8 +425,8 @@ static int pil_mss_reset(struct pil_desc *pil) } /* Program DP Address */ if (drv->dp_virt) { writel_relaxed(drv->dp_phys, drv->rmb_base + if (drv->dp_size) { writel_relaxed(start_addr + SZ_1M, drv->rmb_base + RMB_PMI_CODE_START); writel_relaxed(drv->dp_size, drv->rmb_base + RMB_PMI_CODE_LENGTH); Loading Loading @@ -484,14 +475,12 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) char fw_name[10] = "mba.mbn"; char *dp_name = "msadp"; char *fw_name_p; void *mba_virt; dma_addr_t mba_phys, mba_phys_end; void *mba_dp_virt; dma_addr_t mba_dp_phys, mba_dp_phys_end; int ret, count; const u8 *data; bool mba_mem_unprotect = false; fw_name_p = drv->non_elf_image ? fw_name_legacy : fw_name; /* Load and authenticate mba image */ ret = request_firmware(&fw, fw_name_p, pil->dev); if (ret) { dev_err(pil->dev, "Failed to locate %s\n", Loading @@ -499,51 +488,22 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) return ret; } drv->mba_size = SZ_1M; md->mba_mem_dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8); init_dma_attrs(&md->attrs_dma); dma_set_attr(DMA_ATTR_STRONGLY_ORDERED, &md->attrs_dma); mba_virt = dma_alloc_attrs(&md->mba_mem_dev, drv->mba_size, &mba_phys, GFP_KERNEL, &md->attrs_dma); if (!mba_virt) { dev_err(pil->dev, "MBA metadata buffer allocation failed\n"); ret = -ENOMEM; goto err_dma_alloc; } drv->mba_phys = mba_phys; drv->mba_virt = mba_virt; mba_phys_end = mba_phys + drv->mba_size; dev_info(pil->dev, "MBA: loading from %pa to %pa\n", &mba_phys, &mba_phys_end); /* Load the MBA image into memory */ data = fw ? fw->data : NULL; if (!data) { dev_err(pil->dev, "MBA data is NULL\n"); ret = -ENOMEM; goto err_mba_data; goto err_invalid_fw; } count = fw->size; memcpy(mba_virt, data, count); wmb(); if (pil->subsys_vmid > 0) { ret = pil_assign_mem_to_subsys(pil, drv->mba_phys, drv->mba_size); if (ret) { pr_err("scm_call to unprotect MBA mem failed\n"); goto err_mba_data; } mba_mem_unprotect = true; } drv->mba_dp_size = SZ_1M; md->mba_mem_dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8); init_dma_attrs(&md->attrs_dma); dma_set_attr(DMA_ATTR_STRONGLY_ORDERED, &md->attrs_dma); /* Load modem debug policy */ ret = request_firmware(&dp_fw, dp_name, pil->dev); if (ret) { drv->dp_virt = NULL; dev_warn(pil->dev, "MBA: Debug policy not present - %s\n", dev_warn(pil->dev, "Debug policy not present - %s. Continue.\n", dp_name); } else { if (!dp_fw || !dp_fw->data) { Loading @@ -551,31 +511,44 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) ret = -ENOMEM; goto err_invalid_fw; } mba_virt = dma_alloc_attrs(&md->mba_mem_dev, dp_fw->size, &mba_phys, GFP_KERNEL, &md->attrs_dma); if (!mba_virt) { dev_err(pil->dev, "MBA: DP metadata buffer allocation failed\n"); drv->dp_size = dp_fw->size; drv->mba_dp_size += drv->dp_size; } mba_dp_virt = dma_alloc_attrs(&md->mba_mem_dev, drv->mba_dp_size, &mba_dp_phys, GFP_KERNEL, &md->attrs_dma); if (!mba_dp_virt) { dev_err(pil->dev, "MBA metadata buffer allocation failed\n"); ret = -ENOMEM; goto err_invalid_fw; } drv->dp_size = dp_fw->size; drv->dp_phys = mba_phys; drv->dp_virt = mba_virt; mba_phys_end = mba_phys + drv->dp_size; dev_info(pil->dev, "MBA: DP loading from %pa to %pa\n", &mba_phys, &mba_phys_end); memcpy(mba_virt, dp_fw->data, dp_fw->size); drv->mba_dp_phys = mba_dp_phys; drv->mba_dp_virt = mba_dp_virt; mba_dp_phys_end = mba_dp_phys + drv->mba_dp_size; dev_info(pil->dev, "Loading MBA and DP (if present) from %pa to %pa\n", &mba_dp_phys, &mba_dp_phys_end); /* Load the MBA image into memory */ count = fw->size; memcpy(mba_dp_virt, data, count); /* Ensure memcpy of the MBA memory is done before loading the DP */ wmb(); /* Load the DP image into memory */ if (drv->mba_dp_size > SZ_1M) { memcpy(mba_dp_virt + SZ_1M, dp_fw->data, dp_fw->size); /* Ensure memcpy is done before powering up modem */ wmb(); } if (pil->subsys_vmid > 0) { ret = pil_assign_mem_to_subsys(pil, drv->dp_phys, drv->dp_size); ret = pil_assign_mem_to_subsys(pil, drv->mba_dp_phys, drv->mba_dp_size); if (ret) { pr_err("scm_call to unprotect DP mem failed\n"); goto err_dp_scm; } pr_err("scm_call to unprotect MBA and DP mem failed\n"); goto err_mba_data; } } Loading @@ -585,32 +558,24 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) goto err_mss_reset; } if (drv->dp_virt) if (dp_fw) release_firmware(dp_fw); release_firmware(fw); return 0; err_mss_reset: if (drv->dp_virt && pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->dp_phys, drv->dp_size); err_dp_scm: if (drv->dp_virt) { dma_free_attrs(&md->mba_mem_dev, dp_fw->size, drv->dp_virt, drv->dp_phys, &md->attrs_dma); drv->dp_virt = NULL; } if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->mba_dp_phys, drv->mba_dp_size); err_mba_data: dma_free_attrs(&md->mba_mem_dev, drv->mba_dp_size, drv->mba_dp_virt, drv->mba_dp_phys, &md->attrs_dma); err_invalid_fw: if (dp_fw) release_firmware(dp_fw); err_mba_data: if (mba_mem_unprotect && pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->mba_phys, drv->mba_size); dma_free_attrs(&md->mba_mem_dev, drv->mba_size, drv->mba_virt, drv->mba_phys, &md->attrs_dma); drv->mba_virt = NULL; err_dma_alloc: release_firmware(fw); drv->mba_dp_virt = NULL; return ret; } Loading Loading @@ -680,22 +645,13 @@ fail: if (drv->q6) { pil_mss_shutdown(pil); if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->mba_phys, drv->q6->mba_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_size, drv->q6->mba_virt, drv->q6->mba_phys, pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys, drv->q6->mba_dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size, drv->q6->mba_dp_virt, drv->q6->mba_dp_phys, &drv->attrs_dma); drv->q6->mba_virt = NULL; drv->q6->mba_dp_virt = NULL; if (drv->q6->dp_virt) { if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->dp_phys, drv->q6->dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->dp_size, drv->q6->dp_virt, drv->q6->dp_phys, &drv->attrs_dma); drv->q6->dp_virt = NULL; } } return ret; } Loading Loading @@ -757,27 +713,17 @@ static int pil_msa_mba_auth(struct pil_desc *pil) } if (drv->q6) { if (drv->q6->mba_virt) { /* Reclaim MBA memory. */ if (drv->q6->mba_dp_virt) { /* Reclaim MBA and DP (if allocated) memory. */ if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->mba_phys, drv->q6->mba_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_size, drv->q6->mba_virt, drv->q6->mba_phys, &drv->attrs_dma); drv->q6->mba_virt = NULL; } if (drv->q6->dp_virt) { /* Reclaim Modem DP memory. */ if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->dp_phys, drv->q6->dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->dp_size, drv->q6->dp_virt, drv->q6->dp_phys, &drv->attrs_dma); drv->q6->dp_virt = NULL; pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys, drv->q6->mba_dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size, drv->q6->mba_dp_virt, drv->q6->mba_dp_phys, &drv->attrs_dma); drv->q6->mba_dp_virt = NULL; } } if (ret) Loading drivers/soc/qcom/pil-q6v5.h +3 −5 Original line number Diff line number Diff line Loading @@ -48,11 +48,9 @@ struct q6v5_data { bool is_booted; struct pil_desc desc; bool self_auth; phys_addr_t mba_phys; void *mba_virt; size_t mba_size; phys_addr_t dp_phys; void *dp_virt; phys_addr_t mba_dp_phys; void *mba_dp_virt; size_t mba_dp_size; size_t dp_size; bool qdsp6v55; bool qdsp6v5_2_0; Loading Loading
drivers/soc/qcom/pil-msa.c +76 −130 Original line number Diff line number Diff line Loading @@ -320,27 +320,18 @@ int __pil_mss_deinit_image(struct pil_desc *pil, bool err_path) if (q6_drv->ahb_clk_vote) clk_disable_unprepare(q6_drv->ahb_clk); /* In case of any failure where reclaim MBA memory /* In case of any failure where reclaiming MBA and DP memory * could not happen, free the memory here */ if (drv->q6->mba_virt) { if (drv->q6->mba_dp_virt) { if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->mba_phys, drv->q6->mba_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_size, drv->q6->mba_virt, drv->q6->mba_phys, pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys, drv->q6->mba_dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size, drv->q6->mba_dp_virt, drv->q6->mba_dp_phys, &drv->attrs_dma); drv->q6->mba_virt = NULL; drv->q6->mba_dp_virt = NULL; } if (drv->q6->dp_virt) { if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->dp_phys, drv->q6->dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->dp_size, drv->q6->dp_virt, drv->q6->dp_phys, &drv->attrs_dma); drv->q6->dp_virt = NULL; } return ret; } Loading Loading @@ -397,8 +388,8 @@ static int pil_mss_reset(struct pil_desc *pil) phys_addr_t start_addr = pil_get_entry_addr(pil); int ret; if (drv->mba_phys) start_addr = drv->mba_phys; if (drv->mba_dp_phys) start_addr = drv->mba_dp_phys; /* * Bring subsystem out of reset and enable required Loading Loading @@ -434,8 +425,8 @@ static int pil_mss_reset(struct pil_desc *pil) } /* Program DP Address */ if (drv->dp_virt) { writel_relaxed(drv->dp_phys, drv->rmb_base + if (drv->dp_size) { writel_relaxed(start_addr + SZ_1M, drv->rmb_base + RMB_PMI_CODE_START); writel_relaxed(drv->dp_size, drv->rmb_base + RMB_PMI_CODE_LENGTH); Loading Loading @@ -484,14 +475,12 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) char fw_name[10] = "mba.mbn"; char *dp_name = "msadp"; char *fw_name_p; void *mba_virt; dma_addr_t mba_phys, mba_phys_end; void *mba_dp_virt; dma_addr_t mba_dp_phys, mba_dp_phys_end; int ret, count; const u8 *data; bool mba_mem_unprotect = false; fw_name_p = drv->non_elf_image ? fw_name_legacy : fw_name; /* Load and authenticate mba image */ ret = request_firmware(&fw, fw_name_p, pil->dev); if (ret) { dev_err(pil->dev, "Failed to locate %s\n", Loading @@ -499,51 +488,22 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) return ret; } drv->mba_size = SZ_1M; md->mba_mem_dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8); init_dma_attrs(&md->attrs_dma); dma_set_attr(DMA_ATTR_STRONGLY_ORDERED, &md->attrs_dma); mba_virt = dma_alloc_attrs(&md->mba_mem_dev, drv->mba_size, &mba_phys, GFP_KERNEL, &md->attrs_dma); if (!mba_virt) { dev_err(pil->dev, "MBA metadata buffer allocation failed\n"); ret = -ENOMEM; goto err_dma_alloc; } drv->mba_phys = mba_phys; drv->mba_virt = mba_virt; mba_phys_end = mba_phys + drv->mba_size; dev_info(pil->dev, "MBA: loading from %pa to %pa\n", &mba_phys, &mba_phys_end); /* Load the MBA image into memory */ data = fw ? fw->data : NULL; if (!data) { dev_err(pil->dev, "MBA data is NULL\n"); ret = -ENOMEM; goto err_mba_data; goto err_invalid_fw; } count = fw->size; memcpy(mba_virt, data, count); wmb(); if (pil->subsys_vmid > 0) { ret = pil_assign_mem_to_subsys(pil, drv->mba_phys, drv->mba_size); if (ret) { pr_err("scm_call to unprotect MBA mem failed\n"); goto err_mba_data; } mba_mem_unprotect = true; } drv->mba_dp_size = SZ_1M; md->mba_mem_dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8); init_dma_attrs(&md->attrs_dma); dma_set_attr(DMA_ATTR_STRONGLY_ORDERED, &md->attrs_dma); /* Load modem debug policy */ ret = request_firmware(&dp_fw, dp_name, pil->dev); if (ret) { drv->dp_virt = NULL; dev_warn(pil->dev, "MBA: Debug policy not present - %s\n", dev_warn(pil->dev, "Debug policy not present - %s. Continue.\n", dp_name); } else { if (!dp_fw || !dp_fw->data) { Loading @@ -551,31 +511,44 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) ret = -ENOMEM; goto err_invalid_fw; } mba_virt = dma_alloc_attrs(&md->mba_mem_dev, dp_fw->size, &mba_phys, GFP_KERNEL, &md->attrs_dma); if (!mba_virt) { dev_err(pil->dev, "MBA: DP metadata buffer allocation failed\n"); drv->dp_size = dp_fw->size; drv->mba_dp_size += drv->dp_size; } mba_dp_virt = dma_alloc_attrs(&md->mba_mem_dev, drv->mba_dp_size, &mba_dp_phys, GFP_KERNEL, &md->attrs_dma); if (!mba_dp_virt) { dev_err(pil->dev, "MBA metadata buffer allocation failed\n"); ret = -ENOMEM; goto err_invalid_fw; } drv->dp_size = dp_fw->size; drv->dp_phys = mba_phys; drv->dp_virt = mba_virt; mba_phys_end = mba_phys + drv->dp_size; dev_info(pil->dev, "MBA: DP loading from %pa to %pa\n", &mba_phys, &mba_phys_end); memcpy(mba_virt, dp_fw->data, dp_fw->size); drv->mba_dp_phys = mba_dp_phys; drv->mba_dp_virt = mba_dp_virt; mba_dp_phys_end = mba_dp_phys + drv->mba_dp_size; dev_info(pil->dev, "Loading MBA and DP (if present) from %pa to %pa\n", &mba_dp_phys, &mba_dp_phys_end); /* Load the MBA image into memory */ count = fw->size; memcpy(mba_dp_virt, data, count); /* Ensure memcpy of the MBA memory is done before loading the DP */ wmb(); /* Load the DP image into memory */ if (drv->mba_dp_size > SZ_1M) { memcpy(mba_dp_virt + SZ_1M, dp_fw->data, dp_fw->size); /* Ensure memcpy is done before powering up modem */ wmb(); } if (pil->subsys_vmid > 0) { ret = pil_assign_mem_to_subsys(pil, drv->dp_phys, drv->dp_size); ret = pil_assign_mem_to_subsys(pil, drv->mba_dp_phys, drv->mba_dp_size); if (ret) { pr_err("scm_call to unprotect DP mem failed\n"); goto err_dp_scm; } pr_err("scm_call to unprotect MBA and DP mem failed\n"); goto err_mba_data; } } Loading @@ -585,32 +558,24 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) goto err_mss_reset; } if (drv->dp_virt) if (dp_fw) release_firmware(dp_fw); release_firmware(fw); return 0; err_mss_reset: if (drv->dp_virt && pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->dp_phys, drv->dp_size); err_dp_scm: if (drv->dp_virt) { dma_free_attrs(&md->mba_mem_dev, dp_fw->size, drv->dp_virt, drv->dp_phys, &md->attrs_dma); drv->dp_virt = NULL; } if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->mba_dp_phys, drv->mba_dp_size); err_mba_data: dma_free_attrs(&md->mba_mem_dev, drv->mba_dp_size, drv->mba_dp_virt, drv->mba_dp_phys, &md->attrs_dma); err_invalid_fw: if (dp_fw) release_firmware(dp_fw); err_mba_data: if (mba_mem_unprotect && pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->mba_phys, drv->mba_size); dma_free_attrs(&md->mba_mem_dev, drv->mba_size, drv->mba_virt, drv->mba_phys, &md->attrs_dma); drv->mba_virt = NULL; err_dma_alloc: release_firmware(fw); drv->mba_dp_virt = NULL; return ret; } Loading Loading @@ -680,22 +645,13 @@ fail: if (drv->q6) { pil_mss_shutdown(pil); if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->mba_phys, drv->q6->mba_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_size, drv->q6->mba_virt, drv->q6->mba_phys, pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys, drv->q6->mba_dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size, drv->q6->mba_dp_virt, drv->q6->mba_dp_phys, &drv->attrs_dma); drv->q6->mba_virt = NULL; drv->q6->mba_dp_virt = NULL; if (drv->q6->dp_virt) { if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->dp_phys, drv->q6->dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->dp_size, drv->q6->dp_virt, drv->q6->dp_phys, &drv->attrs_dma); drv->q6->dp_virt = NULL; } } return ret; } Loading Loading @@ -757,27 +713,17 @@ static int pil_msa_mba_auth(struct pil_desc *pil) } if (drv->q6) { if (drv->q6->mba_virt) { /* Reclaim MBA memory. */ if (drv->q6->mba_dp_virt) { /* Reclaim MBA and DP (if allocated) memory. */ if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->mba_phys, drv->q6->mba_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_size, drv->q6->mba_virt, drv->q6->mba_phys, &drv->attrs_dma); drv->q6->mba_virt = NULL; } if (drv->q6->dp_virt) { /* Reclaim Modem DP memory. */ if (pil->subsys_vmid > 0) pil_assign_mem_to_linux(pil, drv->q6->dp_phys, drv->q6->dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->dp_size, drv->q6->dp_virt, drv->q6->dp_phys, &drv->attrs_dma); drv->q6->dp_virt = NULL; pil_assign_mem_to_linux(pil, drv->q6->mba_dp_phys, drv->q6->mba_dp_size); dma_free_attrs(&drv->mba_mem_dev, drv->q6->mba_dp_size, drv->q6->mba_dp_virt, drv->q6->mba_dp_phys, &drv->attrs_dma); drv->q6->mba_dp_virt = NULL; } } if (ret) Loading
drivers/soc/qcom/pil-q6v5.h +3 −5 Original line number Diff line number Diff line Loading @@ -48,11 +48,9 @@ struct q6v5_data { bool is_booted; struct pil_desc desc; bool self_auth; phys_addr_t mba_phys; void *mba_virt; size_t mba_size; phys_addr_t dp_phys; void *dp_virt; phys_addr_t mba_dp_phys; void *mba_dp_virt; size_t mba_dp_size; size_t dp_size; bool qdsp6v55; bool qdsp6v5_2_0; Loading