Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47bd9ba7 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: pil-msa: Allocate and load MBA and DP images at one location"

parents cfa06d80 0ade9aae
Loading
Loading
Loading
Loading
+76 −130
Original line number Diff line number Diff line
@@ -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;
}

@@ -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
@@ -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);
@@ -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",
@@ -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) {
@@ -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;
		}
	}

@@ -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;
}

@@ -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;
}
@@ -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)
+3 −5
Original line number Diff line number Diff line
@@ -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;