Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1642710 > unrolled thread

[RESEND: PATCH v4 0/4] Add memory ownership switch support and enable mss rproc on msm8996

Started byAvaneesh Kumar Dwivedi <akdwived@codeaurora.org>
First post2017-05-16 20:10 +0200
Last post2017-05-16 20:10 +0200
Articles 8 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [RESEND: PATCH v4 0/4] Add memory ownership switch support and enable mss rproc on msm8996 Avaneesh Kumar Dwivedi <akdwived@codeaurora.org> - 2017-05-16 20:10 +0200
    [RESEND: PATCH v4 3/4] remoteproc: qcom: Make secure world call for mem ownership switch Avaneesh Kumar Dwivedi <akdwived@codeaurora.org> - 2017-05-16 20:10 +0200
    [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence Avaneesh Kumar Dwivedi <akdwived@codeaurora.org> - 2017-05-16 20:10 +0200
      Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image  loading sequence Sricharan R <sricharan@codeaurora.org> - 2017-05-20 05:00 +0200
        Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image  loading sequence "Dwivedi, Avaneesh Kumar (avani)" <akdwived@codeaurora.org> - 2017-05-22 11:40 +0200
          Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image  loading sequence Sricharan R <sricharan@codeaurora.org> - 2017-05-22 12:40 +0200
            Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image  loading sequence "Dwivedi, Avaneesh Kumar (avani)" <akdwived@codeaurora.org> - 2017-05-22 15:30 +0200
    [RESEND: PATCH v4 4/4] remoteproc: qcom: Add support for mss boot on msm8996 Avaneesh Kumar Dwivedi <akdwived@codeaurora.org> - 2017-05-16 20:10 +0200

#1642710 — [RESEND: PATCH v4 0/4] Add memory ownership switch support and enable mss rproc on msm8996

FromAvaneesh Kumar Dwivedi <akdwived@codeaurora.org>
Date2017-05-16 20:10 +0200
Subject[RESEND: PATCH v4 0/4] Add memory ownership switch support and enable mss rproc on msm8996
Message-ID<tHP50-vb-7@gated-at.bofh.it>
This patch does following
	1- Adds new scm call which helps in stage two translation of a memory region
	   so that memory ownership sharing and switching can be achieved on armv8 and later.
	2- Enable mss remoteproc on msm8996

Major changes since last patch:
	1- Refactored SCM API
	2- Changed SCM API Signature 
	3- Added cpu_to_le32() as and where required
	4- Elaborated documentation of new API added
	5- Refactored MSS rproc code which make the scm api call
	6- Refactored mss rproc code to first load all segments and then transfer ownership of
	   memory region to MSS for authentication and boot etc.
	7- Other Minor changes
	8- kbuild robot gave error so added dummy definition of __qcom_scm_assign_mem() in qcom_scm-32.c as well
Avaneesh Kumar Dwivedi (4):
  firmware: scm: Add new SCM call for switching memory ownership
  remoteproc: qcom: refactor mss fw image loading sequence
  remoteproc: qcom: Make secure world call for mem ownership switch
  remoteproc: qcom: Add support for mss boot on msm8996

 .../devicetree/bindings/remoteproc/qcom,q6v5.txt   |   4 +-
 drivers/firmware/qcom_scm-32.c                     |   6 +
 drivers/firmware/qcom_scm-64.c                     |  27 ++
 drivers/firmware/qcom_scm.c                        |  75 ++++++
 drivers/firmware/qcom_scm.h                        |   4 +
 drivers/remoteproc/qcom_q6v5_pil.c                 | 280 ++++++++++++++++++---
 include/linux/qcom_scm.h                           |  14 ++
 7 files changed, 370 insertions(+), 40 deletions(-)

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

[toc] | [next] | [standalone]


#1642712 — [RESEND: PATCH v4 3/4] remoteproc: qcom: Make secure world call for mem ownership switch

FromAvaneesh Kumar Dwivedi <akdwived@codeaurora.org>
Date2017-05-16 20:10 +0200
Subject[RESEND: PATCH v4 3/4] remoteproc: qcom: Make secure world call for mem ownership switch
Message-ID<tHP50-vb-15@gated-at.bofh.it>
In reply to#1642710
MSS proc on msm8996 can not access fw loaded region without stage
second translation of memory pages where mpss image are loaded.
This patch in order to enable mss boot on msm8996 invoke scm call
to switch or share ownership between apps and modem.

Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
---
 drivers/remoteproc/qcom_q6v5_pil.c | 84 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
index 2626954..57a4cfec 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -110,6 +110,7 @@ struct rproc_hexagon_res {
 	struct qcom_mss_reg_res *active_supply;
 	char **proxy_clk_names;
 	char **active_clk_names;
+	bool need_mem_protection;
 };
 
 struct q6v5 {
@@ -151,6 +152,7 @@ struct q6v5 {
 	phys_addr_t mpss_reloc;
 	void *mpss_region;
 	size_t mpss_size;
+	bool need_mem_protection;
 
 	struct qcom_rproc_subdev smd_subdev;
 };
@@ -288,6 +290,43 @@ static struct resource_table *q6v5_find_rsc_table(struct rproc *rproc,
 	return &table;
 }
 
+static int q6v5_assign_mem_to_subsys(struct q6v5 *qproc,
+		phys_addr_t addr, size_t size)
+{
+	struct qcom_scm_destVmPerm next[] = {{ QCOM_SCM_VMID_MSS_MSA,
+		(QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE)} };
+	int ret;
+
+	size = ALIGN(size, SZ_4K);
+	if (!qproc->need_mem_protection)
+		return 0;
+	ret = qcom_scm_assign_mem(addr, size,
+		BIT(QCOM_SCM_VMID_HLOS), next, sizeof(next));
+	if (ret)
+		pr_err("%s: Failed to assign memory access, ret = %d\n",
+			__func__, ret);
+	return ret;
+}
+
+static int q6v5_assign_mem_to_linux(struct q6v5 *qproc,
+		phys_addr_t addr, size_t size)
+{
+	struct qcom_scm_destVmPerm next[] = { { QCOM_SCM_VMID_HLOS,
+		(QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE | QCOM_SCM_PERM_EXEC)}
+		};
+	int ret;
+
+	size = ALIGN(size, SZ_4K);
+	if (!qproc->need_mem_protection)
+		return 0;
+	ret = qcom_scm_assign_mem(addr, size,
+		BIT(QCOM_SCM_VMID_MSS_MSA), next, sizeof(next));
+	if (ret)
+		pr_err("%s: Failed to assign memory access, ret = %d\n",
+			__func__, ret);
+	return ret;
+}
+
 static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
 {
 	struct q6v5 *qproc = rproc->priv;
@@ -461,6 +500,13 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
 
 	memcpy(ptr, fw->data, fw->size);
 
+	/* Hypervisor mapping to access metadata by modem */
+	ret = q6v5_assign_mem_to_subsys(qproc, phys, fw->size);
+	if (ret) {
+		dev_err(qproc->dev,
+			"Failed to assign metadata memory, ret - %d\n", ret);
+		return -ENOMEM;
+	}
 	writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG);
 	writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
 
@@ -471,6 +517,11 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
 		dev_err(qproc->dev,
 			"metadata authentication failed: %d\n", ret);
 
+	/* Metadata authentication done, remove modem access */
+	ret = q6v5_assign_mem_to_linux(qproc, phys, fw->size);
+	if (ret)
+		dev_err(qproc->dev,
+			"Failed to reclaim metadata memory, ret - %d\n", ret);
 	dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
 
 	return ret < 0 ? ret : 0;
@@ -581,6 +632,10 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
 	}
 	/* Transfer ownership of modem region with modem fw */
 	boot_addr = relocate ? qproc->mpss_phys : min_addr;
+	ret = q6v5_assign_mem_to_subsys(qproc,
+		qproc->mpss_phys, qproc->mpss_size);
+	if (ret)
+		return ret;
 	writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
 	writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
 	writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
@@ -600,6 +655,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
 static int q6v5_start(struct rproc *rproc)
 {
 	struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
+	int assign_mem_result;
 	int ret;
 
 	ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
@@ -635,6 +691,13 @@ static int q6v5_start(struct rproc *rproc)
 		goto assert_reset;
 	}
 
+	ret = q6v5_assign_mem_to_subsys(qproc,
+		qproc->mba_phys, qproc->mba_size);
+	if (ret) {
+		dev_err(qproc->dev,
+			"Failed to assign mba memory access, ret - %d\n", ret);
+		goto assert_reset;
+	}
 	writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG);
 
 	ret = q6v5proc_reset(qproc);
@@ -656,16 +719,21 @@ static int q6v5_start(struct rproc *rproc)
 
 	ret = q6v5_mpss_load(qproc);
 	if (ret)
-		goto halt_axi_ports;
+		goto reclaim_mem;
 
 	ret = wait_for_completion_timeout(&qproc->start_done,
 					  msecs_to_jiffies(5000));
 	if (ret == 0) {
 		dev_err(qproc->dev, "start timed out\n");
 		ret = -ETIMEDOUT;
-		goto halt_axi_ports;
+		goto reclaim_mem;
 	}
 
+	ret = q6v5_assign_mem_to_linux(qproc,
+		qproc->mba_phys, qproc->mba_size);
+	if (ret)
+		dev_err(qproc->dev,
+			"Failed to reclaim mba memory, ret - %d\n", ret);
 	qproc->running = true;
 
 	q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
@@ -675,12 +743,19 @@ static int q6v5_start(struct rproc *rproc)
 
 	return 0;
 
+reclaim_mem:
+	assign_mem_result =
+		q6v5_assign_mem_to_linux(qproc,
+		qproc->mpss_phys, qproc->mpss_size);
 halt_axi_ports:
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
 	q6v5_clk_disable(qproc->dev, qproc->active_clks,
 			 qproc->active_clk_count);
+	assign_mem_result =
+		q6v5_assign_mem_to_linux(qproc,
+		qproc->mba_phys, qproc->mba_size);
 assert_reset:
 	reset_control_assert(qproc->mss_restart);
 disable_vdd:
@@ -717,6 +792,8 @@ static int q6v5_stop(struct rproc *rproc)
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
 
+	ret = q6v5_assign_mem_to_linux(qproc,
+			qproc->mpss_phys, qproc->mpss_size);
 	reset_control_assert(qproc->mss_restart);
 	q6v5_clk_disable(qproc->dev, qproc->active_clks,
 			 qproc->active_clk_count);
@@ -1014,6 +1091,7 @@ static int q6v5_probe(struct platform_device *pdev)
 	if (ret)
 		goto free_rproc;
 
+	qproc->need_mem_protection = desc->need_mem_protection;
 	ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt);
 	if (ret < 0)
 		goto free_rproc;
@@ -1089,6 +1167,7 @@ static int q6v5_remove(struct platform_device *pdev)
 		"mem",
 		NULL
 	},
+	.need_mem_protection = false,
 };
 
 static const struct rproc_hexagon_res msm8974_mss = {
@@ -1126,6 +1205,7 @@ static int q6v5_remove(struct platform_device *pdev)
 		"mem",
 		NULL
 	},
+	.need_mem_protection = false,
 };
 
 static const struct of_device_id q6v5_of_match[] = {
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

[toc] | [prev] | [next] | [standalone]


#1642714 — [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence

FromAvaneesh Kumar Dwivedi <akdwived@codeaurora.org>
Date2017-05-16 20:10 +0200
Subject[RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence
Message-ID<tHP50-vb-25@gated-at.bofh.it>
In reply to#1642710
This patch refactor code to first load all firmware blobs
and then update modem proc to authenticate and boot fw.
Also make a trivial change in a error log.

Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
---
 drivers/remoteproc/qcom_q6v5_pil.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
index 8fd697a..2626954 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -466,9 +466,10 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
 
 	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
 	if (ret == -ETIMEDOUT)
-		dev_err(qproc->dev, "MPSS header authentication timed out\n");
+		dev_err(qproc->dev, "metadata authentication timed out\n");
 	else if (ret < 0)
-		dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
+		dev_err(qproc->dev,
+			"metadata authentication failed: %d\n", ret);
 
 	dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
 
@@ -503,7 +504,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
 	bool relocate = false;
 	char seg_name[10];
 	ssize_t offset;
-	size_t size;
+	size_t size = 0;
 	void *ptr;
 	int ret;
 	int i;
@@ -541,7 +542,9 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
 	}
 
 	mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
-
+	/* Load firmware completely before letting mss to start
+	 * authentication and then boot firmware
+	 */
 	for (i = 0; i < ehdr->e_phnum; i++) {
 		phdr = &phdrs[i];
 
@@ -574,17 +577,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
 			memset(ptr + phdr->p_filesz, 0,
 			       phdr->p_memsz - phdr->p_filesz);
 		}
-
-		size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
-		if (!size) {
-			boot_addr = relocate ? qproc->mpss_phys : min_addr;
-			writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
-			writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
-		}
-
 		size += phdr->p_memsz;
-		writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
 	}
+	/* Transfer ownership of modem region with modem fw */
+	boot_addr = relocate ? qproc->mpss_phys : min_addr;
+	writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
+	writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
+	writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
 
 	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
 	if (ret == -ETIMEDOUT)
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

[toc] | [prev] | [next] | [standalone]


#1646050 — Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence

FromSricharan R <sricharan@codeaurora.org>
Date2017-05-20 05:00 +0200
SubjectRe: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence
Message-ID<tJ2My-3sM-1@gated-at.bofh.it>
In reply to#1642714
Hi Bjorn/Avaneesh,

On 5/16/2017 11:32 PM, Avaneesh Kumar Dwivedi wrote:
> This patch refactor code to first load all firmware blobs
> and then update modem proc to authenticate and boot fw.
> Also make a trivial change in a error log.
> 
> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
> ---
>  drivers/remoteproc/qcom_q6v5_pil.c | 25 ++++++++++++-------------
>  1 file changed, 12 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
> index 8fd697a..2626954 100644
> --- a/drivers/remoteproc/qcom_q6v5_pil.c
> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
> @@ -466,9 +466,10 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
>  
>  	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
>  	if (ret == -ETIMEDOUT)
> -		dev_err(qproc->dev, "MPSS header authentication timed out\n");
> +		dev_err(qproc->dev, "metadata authentication timed out\n");
>  	else if (ret < 0)
> -		dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
> +		dev_err(qproc->dev,
> +			"metadata authentication failed: %d\n", ret);
>  
>  	dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
>  
> @@ -503,7 +504,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  	bool relocate = false;
>  	char seg_name[10];
>  	ssize_t offset;
> -	size_t size;
> +	size_t size = 0;
>  	void *ptr;
>  	int ret;
>  	int i;
> @@ -541,7 +542,9 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  	}
>  
>  	mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
> -
> +	/* Load firmware completely before letting mss to start
> +	 * authentication and then boot firmware
> +	 */
>  	for (i = 0; i < ehdr->e_phnum; i++) {
>  		phdr = &phdrs[i];
>  
> @@ -574,17 +577,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>  			memset(ptr + phdr->p_filesz, 0,
>  			       phdr->p_memsz - phdr->p_filesz);
>  		}
> -
> -		size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
> -		if (!size) {
> -			boot_addr = relocate ? qproc->mpss_phys : min_addr;
> -			writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
> -			writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
> -		}
> -
>  		size += phdr->p_memsz;
> -		writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>  	}

So while moving this down, can we use qcom_mdt_load instead for the mpss
image loading part above ?

> +	/* Transfer ownership of modem region with modem fw */
> +	boot_addr = relocate ? qproc->mpss_phys : min_addr;
> +	writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
> +	writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
> +	writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);

For ipq8074 [1], wcnss core has an Q6V5 version of the ip for which the
initialization/boot sequence is pretty much the same as that has been added
for msm8996 in this series. So wanted to understand if its better to
use this remoteproc itself by keeping the Q6 and mpss parts separately (or)
add a new remoteproc ?

[1] https://patchwork.kernel.org/patch/9711725/

Regards,
 Sricharan

>  
>  	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
>  	if (ret == -ETIMEDOUT)
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

[toc] | [prev] | [next] | [standalone]


#1646665 — Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence

From"Dwivedi, Avaneesh Kumar (avani)" <akdwived@codeaurora.org>
Date2017-05-22 11:40 +0200
SubjectRe: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence
Message-ID<tJRYJ-3Yq-1@gated-at.bofh.it>
In reply to#1646050

On 5/20/2017 8:25 AM, Sricharan R wrote:
> Hi Bjorn/Avaneesh,
>
> On 5/16/2017 11:32 PM, Avaneesh Kumar Dwivedi wrote:
>> This patch refactor code to first load all firmware blobs
>> and then update modem proc to authenticate and boot fw.
>> Also make a trivial change in a error log.
>>
>> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
>> ---
>>   drivers/remoteproc/qcom_q6v5_pil.c | 25 ++++++++++++-------------
>>   1 file changed, 12 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
>> index 8fd697a..2626954 100644
>> --- a/drivers/remoteproc/qcom_q6v5_pil.c
>> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
>> @@ -466,9 +466,10 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
>>   
>>   	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
>>   	if (ret == -ETIMEDOUT)
>> -		dev_err(qproc->dev, "MPSS header authentication timed out\n");
>> +		dev_err(qproc->dev, "metadata authentication timed out\n");
>>   	else if (ret < 0)
>> -		dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
>> +		dev_err(qproc->dev,
>> +			"metadata authentication failed: %d\n", ret);
>>   
>>   	dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
>>   
>> @@ -503,7 +504,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>   	bool relocate = false;
>>   	char seg_name[10];
>>   	ssize_t offset;
>> -	size_t size;
>> +	size_t size = 0;
>>   	void *ptr;
>>   	int ret;
>>   	int i;
>> @@ -541,7 +542,9 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>   	}
>>   
>>   	mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
>> -
>> +	/* Load firmware completely before letting mss to start
>> +	 * authentication and then boot firmware
>> +	 */
>>   	for (i = 0; i < ehdr->e_phnum; i++) {
>>   		phdr = &phdrs[i];
>>   
>> @@ -574,17 +577,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>   			memset(ptr + phdr->p_filesz, 0,
>>   			       phdr->p_memsz - phdr->p_filesz);
>>   		}
>> -
>> -		size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>> -		if (!size) {
>> -			boot_addr = relocate ? qproc->mpss_phys : min_addr;
>> -			writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
>> -			writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
>> -		}
>> -
>>   		size += phdr->p_memsz;
>> -		writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>>   	}
> So while moving this down, can we use qcom_mdt_load instead for the mpss
> image loading part above ?
qcom_mdt_load() can not be used to load segments for mpss, as MPSS blobs 
are self authenticated.
while qcom_mdt_load() is used in cases where authentication of loaded 
blobs is done by trustzone.
for that qcom_mdt_load() does extra steps to send pas_id to trustzone 
and mem_setup() etc.
>> +	/* Transfer ownership of modem region with modem fw */
>> +	boot_addr = relocate ? qproc->mpss_phys : min_addr;
>> +	writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
>> +	writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
>> +	writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
> For ipq8074 [1], wcnss core has an Q6V5 version of the ip for which the
> initialization/boot sequence is pretty much the same as that has been added
> for msm8996 in this series. So wanted to understand if its better to
> use this remoteproc itself by keeping the Q6 and mpss parts separately (or)
> add a new remoteproc ?
Bjorn can better answer this query, but i believe this remoteproc can be 
extended to load
mpss part by adding private initialization for the IP.
>
> [1] https://patchwork.kernel.org/patch/9711725/
>
> Regards,
>   Sricharan
>
>>   
>>   	ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
>>   	if (ret == -ETIMEDOUT)
>>

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

[toc] | [prev] | [next] | [standalone]


#1646714 — Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence

FromSricharan R <sricharan@codeaurora.org>
Date2017-05-22 12:40 +0200
SubjectRe: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence
Message-ID<tJSUO-4wq-15@gated-at.bofh.it>
In reply to#1646665
Hi,

On 5/22/2017 3:03 PM, Dwivedi, Avaneesh Kumar (avani) wrote:
> 
> 
> On 5/20/2017 8:25 AM, Sricharan R wrote:
>> Hi Bjorn/Avaneesh,
>>
>> On 5/16/2017 11:32 PM, Avaneesh Kumar Dwivedi wrote:
>>> This patch refactor code to first load all firmware blobs
>>> and then update modem proc to authenticate and boot fw.
>>> Also make a trivial change in a error log.
>>>
>>> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
>>> ---
>>>   drivers/remoteproc/qcom_q6v5_pil.c | 25 ++++++++++++-------------
>>>   1 file changed, 12 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
>>> index 8fd697a..2626954 100644
>>> --- a/drivers/remoteproc/qcom_q6v5_pil.c
>>> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
>>> @@ -466,9 +466,10 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
>>>         ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
>>>       if (ret == -ETIMEDOUT)
>>> -        dev_err(qproc->dev, "MPSS header authentication timed out\n");
>>> +        dev_err(qproc->dev, "metadata authentication timed out\n");
>>>       else if (ret < 0)
>>> -        dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
>>> +        dev_err(qproc->dev,
>>> +            "metadata authentication failed: %d\n", ret);
>>>         dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
>>>   @@ -503,7 +504,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>>       bool relocate = false;
>>>       char seg_name[10];
>>>       ssize_t offset;
>>> -    size_t size;
>>> +    size_t size = 0;
>>>       void *ptr;
>>>       int ret;
>>>       int i;
>>> @@ -541,7 +542,9 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>>       }
>>>         mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
>>> -
>>> +    /* Load firmware completely before letting mss to start
>>> +     * authentication and then boot firmware
>>> +     */
>>>       for (i = 0; i < ehdr->e_phnum; i++) {
>>>           phdr = &phdrs[i];
>>>   @@ -574,17 +577,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>>               memset(ptr + phdr->p_filesz, 0,
>>>                      phdr->p_memsz - phdr->p_filesz);
>>>           }
>>> -
>>> -        size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>>> -        if (!size) {
>>> -            boot_addr = relocate ? qproc->mpss_phys : min_addr;
>>> -            writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
>>> -            writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
>>> -        }
>>> -
>>>           size += phdr->p_memsz;
>>> -        writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>>>       }
>> So while moving this down, can we use qcom_mdt_load instead for the mpss
>> image loading part above ?
> qcom_mdt_load() can not be used to load segments for mpss, as MPSS blobs are self authenticated.
> while qcom_mdt_load() is used in cases where authentication of loaded blobs is done by trustzone.
> for that qcom_mdt_load() does extra steps to send pas_id to trustzone and mem_setup() etc.

Right, so my intention of asking this was if the code which does the calculation and
loads the segments in qcom_mdt_load can somehow be abstracted out, so that future
self authenticating rproc (even mpss in this case) can use them to load mdt ?

>>> +    /* Transfer ownership of modem region with modem fw */
>>> +    boot_addr = relocate ? qproc->mpss_phys : min_addr;
>>> +    writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
>>> +    writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
>>> +    writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>> For ipq8074 [1], wcnss core has an Q6V5 version of the ip for which the
>> initialization/boot sequence is pretty much the same as that has been added
>> for msm8996 in this series. So wanted to understand if its better to
>> use this remoteproc itself by keeping the Q6 and mpss parts separately (or)
>> add a new remoteproc ?
> Bjorn can better answer this query, but i believe this remoteproc can be extended to load
> mpss part by adding private initialization for the IP.

ya, the mpss part can be separated out, so that this can be a Q6 + MPSS (or) Q6 + WCNSS
remoteproc. Was asking this to get the right way for adding the Q6 + WCNSS remoteproc,
as the Q6 part is same what you have added for msm8996.

Regards,
 Sricharan

>>
>> [1] https://patchwork.kernel.org/patch/9711725/
>>
>> Regards,
>>   Sricharan
>>
>>>         ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
>>>       if (ret == -ETIMEDOUT)
>>>
> 

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

[toc] | [prev] | [next] | [standalone]


#1646886 — Re: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence

From"Dwivedi, Avaneesh Kumar (avani)" <akdwived@codeaurora.org>
Date2017-05-22 15:30 +0200
SubjectRe: [RESEND: PATCH v4 2/4] remoteproc: qcom: refactor mss fw image loading sequence
Message-ID<tJVzj-6fx-7@gated-at.bofh.it>
In reply to#1646714

On 5/22/2017 4:07 PM, Sricharan R wrote:
> Hi,
>
> On 5/22/2017 3:03 PM, Dwivedi, Avaneesh Kumar (avani) wrote:
>>
>> On 5/20/2017 8:25 AM, Sricharan R wrote:
>>> Hi Bjorn/Avaneesh,
>>>
>>> On 5/16/2017 11:32 PM, Avaneesh Kumar Dwivedi wrote:
>>>> This patch refactor code to first load all firmware blobs
>>>> and then update modem proc to authenticate and boot fw.
>>>> Also make a trivial change in a error log.
>>>>
>>>> Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
>>>> ---
>>>>    drivers/remoteproc/qcom_q6v5_pil.c | 25 ++++++++++++-------------
>>>>    1 file changed, 12 insertions(+), 13 deletions(-)
>>>>
>>>> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
>>>> index 8fd697a..2626954 100644
>>>> --- a/drivers/remoteproc/qcom_q6v5_pil.c
>>>> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
>>>> @@ -466,9 +466,10 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
>>>>          ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000);
>>>>        if (ret == -ETIMEDOUT)
>>>> -        dev_err(qproc->dev, "MPSS header authentication timed out\n");
>>>> +        dev_err(qproc->dev, "metadata authentication timed out\n");
>>>>        else if (ret < 0)
>>>> -        dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret);
>>>> +        dev_err(qproc->dev,
>>>> +            "metadata authentication failed: %d\n", ret);
>>>>          dma_free_attrs(qproc->dev, fw->size, ptr, phys, dma_attrs);
>>>>    @@ -503,7 +504,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>>>        bool relocate = false;
>>>>        char seg_name[10];
>>>>        ssize_t offset;
>>>> -    size_t size;
>>>> +    size_t size = 0;
>>>>        void *ptr;
>>>>        int ret;
>>>>        int i;
>>>> @@ -541,7 +542,9 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>>>        }
>>>>          mpss_reloc = relocate ? min_addr : qproc->mpss_phys;
>>>> -
>>>> +    /* Load firmware completely before letting mss to start
>>>> +     * authentication and then boot firmware
>>>> +     */
>>>>        for (i = 0; i < ehdr->e_phnum; i++) {
>>>>            phdr = &phdrs[i];
>>>>    @@ -574,17 +577,13 @@ static int q6v5_mpss_load(struct q6v5 *qproc)
>>>>                memset(ptr + phdr->p_filesz, 0,
>>>>                       phdr->p_memsz - phdr->p_filesz);
>>>>            }
>>>> -
>>>> -        size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>>>> -        if (!size) {
>>>> -            boot_addr = relocate ? qproc->mpss_phys : min_addr;
>>>> -            writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
>>>> -            writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
>>>> -        }
>>>> -
>>>>            size += phdr->p_memsz;
>>>> -        writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>>>>        }
>>> So while moving this down, can we use qcom_mdt_load instead for the mpss
>>> image loading part above ?
>> qcom_mdt_load() can not be used to load segments for mpss, as MPSS blobs are self authenticated.
>> while qcom_mdt_load() is used in cases where authentication of loaded blobs is done by trustzone.
>> for that qcom_mdt_load() does extra steps to send pas_id to trustzone and mem_setup() etc.
> Right, so my intention of asking this was if the code which does the calculation and
> loads the segments in qcom_mdt_load can somehow be abstracted out, so that future
> self authenticating rproc (even mpss in this case) can use them to load mdt ?
As i understand, you want to replace the piece of code which does parse 
mdt and load individual firmware blobs in a separate routine.
So that it can be called by any one without again doing parsing and 
loading for self authentication.?
Till now only MPSS does rely on self authentication, all other 
subsystems use qcom_mdt_load().
I think this is reason why the qcom_mdt_load() equivalent routine has 
not been used.
Bjorn may further add in this.
>
>>>> +    /* Transfer ownership of modem region with modem fw */
>>>> +    boot_addr = relocate ? qproc->mpss_phys : min_addr;
>>>> +    writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG);
>>>> +    writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG);
>>>> +    writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
>>> For ipq8074 [1], wcnss core has an Q6V5 version of the ip for which the
>>> initialization/boot sequence is pretty much the same as that has been added
>>> for msm8996 in this series. So wanted to understand if its better to
>>> use this remoteproc itself by keeping the Q6 and mpss parts separately (or)
>>> add a new remoteproc ?
>> Bjorn can better answer this query, but i believe this remoteproc can be extended to load
>> mpss part by adding private initialization for the IP.
> ya, the mpss part can be separated out, so that this can be a Q6 + MPSS (or) Q6 + WCNSS
> remoteproc. Was asking this to get the right way for adding the Q6 + WCNSS remoteproc,
> as the Q6 part is same what you have added for msm8996.
Again, i believe yes but leave Bjorn to make final comment.
>
> Regards,
>   Sricharan
>
>>> [1] https://patchwork.kernel.org/patch/9711725/
>>>
>>> Regards,
>>>    Sricharan
>>>
>>>>          ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000);
>>>>        if (ret == -ETIMEDOUT)
>>>>

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

[toc] | [prev] | [next] | [standalone]


#1642716 — [RESEND: PATCH v4 4/4] remoteproc: qcom: Add support for mss boot on msm8996

FromAvaneesh Kumar Dwivedi <akdwived@codeaurora.org>
Date2017-05-16 20:10 +0200
Subject[RESEND: PATCH v4 4/4] remoteproc: qcom: Add support for mss boot on msm8996
Message-ID<tHP50-vb-27@gated-at.bofh.it>
In reply to#1642710
This patch add support for mss boot on msm8996.
Major changes include initializing mss rproc for
msm8996, making appropriate change for executing
mss reset sequence etc.

Signed-off-by: Avaneesh Kumar Dwivedi <akdwived@codeaurora.org>
---
 .../devicetree/bindings/remoteproc/qcom,q6v5.txt   |   4 +-
 drivers/remoteproc/qcom_q6v5_pil.c                 | 171 ++++++++++++++++++---
 2 files changed, 150 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
index 92347fe..f9dfb6c 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
@@ -9,8 +9,8 @@ on the Qualcomm Hexagon core.
 	Definition: must be one of:
 		    "qcom,q6v5-pil",
 		    "qcom,msm8916-mss-pil",
-		    "qcom,msm8974-mss-pil"
-
+		    "qcom,msm8974-mss-pil",
+		"qcom,msm8996-mss-pil"
 - reg:
 	Usage: required
 	Value type: <prop-encoded-array>
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
index 57a4cfec..97da382 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -32,6 +32,7 @@
 #include <linux/soc/qcom/mdt_loader.h>
 #include <linux/soc/qcom/smem.h>
 #include <linux/soc/qcom/smem_state.h>
+#include <linux/iopoll.h>
 
 #include "remoteproc_internal.h"
 #include "qcom_common.h"
@@ -64,6 +65,8 @@
 #define QDSP6SS_RESET_REG		0x014
 #define QDSP6SS_GFMUX_CTL_REG		0x020
 #define QDSP6SS_PWR_CTL_REG		0x030
+#define QDSP6SS_MEM_PWR_CTL		0x0B0
+#define QDSP6SS_STRAP_ACC		0x110
 
 /* AXI Halt Register Offsets */
 #define AXI_HALTREQ_REG			0x0
@@ -92,6 +95,14 @@
 #define QDSS_BHS_ON			BIT(21)
 #define QDSS_LDO_BYP			BIT(22)
 
+/* QDSP6v56 parameters */
+#define QDSP6v56_LDO_BYP		BIT(25)
+#define QDSP6v56_BHS_ON		BIT(24)
+#define QDSP6v56_CLAMP_WL		BIT(21)
+#define QDSP6v56_CLAMP_QMC_MEM		BIT(22)
+#define HALT_CHECK_MAX_LOOPS		200
+#define QDSP6SS_XO_CBCR		0x0038
+#define QDSP6SS_ACC_OVERRIDE_VAL		0x20
 struct reg_info {
 	struct regulator *reg;
 	int uV;
@@ -110,6 +121,7 @@ struct rproc_hexagon_res {
 	struct qcom_mss_reg_res *active_supply;
 	char **proxy_clk_names;
 	char **active_clk_names;
+	int version;
 	bool need_mem_protection;
 };
 
@@ -155,6 +167,13 @@ struct q6v5 {
 	bool need_mem_protection;
 
 	struct qcom_rproc_subdev smd_subdev;
+	int version;
+};
+
+enum {
+	MSS_MSM8916,
+	MSS_MSM8974,
+	MSS_MSM8996,
 };
 
 static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
@@ -391,33 +410,97 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 {
 	u32 val;
 	int ret;
+	int i;
 
-	/* Assert resets, stop core */
-	val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
-	val |= (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE);
-	writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
 
-	/* Enable power block headswitch, and wait for it to stabilize */
-	val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-	val |= QDSS_BHS_ON | QDSS_LDO_BYP;
-	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-	udelay(1);
+	if (qproc->version == MSS_MSM8996) {
+		/* Override the ACC value if required */
+		writel(QDSP6SS_ACC_OVERRIDE_VAL,
+			qproc->reg_base + QDSP6SS_STRAP_ACC);
 
-	/*
-	 * Turn on memories. L2 banks should be done individually
-	 * to minimize inrush current.
-	 */
-	val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-	val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
-		Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
-	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-	val |= Q6SS_L2DATA_SLP_NRET_N_2;
-	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-	val |= Q6SS_L2DATA_SLP_NRET_N_1;
-	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
-	val |= Q6SS_L2DATA_SLP_NRET_N_0;
-	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		/* Assert resets, stop core */
+		val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
+		val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
+		writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
+
+		/* BHS require xo cbcr to be enabled */
+		val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
+		val |= 0x1;
+		writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
 
+		/* Read CLKOFF bit to go low indicating CLK is enabled */
+		ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
+				val, !(val & BIT(31)), 1, HALT_CHECK_MAX_LOOPS);
+		if (ret) {
+			dev_err(qproc->dev,
+				"xo cbcr enabling timed out (rc:%d)\n", ret);
+			return ret;
+		}
+		/* Enable power block headswitch and wait for it to stabilize */
+		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= QDSP6v56_BHS_ON;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		udelay(1);
+
+		/* Put LDO in bypass mode */
+		val |= QDSP6v56_LDO_BYP;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+		/* Deassert QDSP6 compiler memory clamp */
+		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val &= ~QDSP6v56_CLAMP_QMC_MEM;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+		/* Deassert memory peripheral sleep and L2 memory standby */
+		val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+
+		/* Turn on L1, L2, ETB and JU memories 1 at a time */
+		val = readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL);
+		for (i = 19; i >= 0; i--) {
+			val |= BIT(i);
+			writel(val, qproc->reg_base +
+						QDSP6SS_MEM_PWR_CTL);
+			/*
+			 * Read back value to ensure the write is done then
+			 * wait for 1us for both memory peripheral and data
+			 * array to turn on.
+			 */
+			val |= readl(qproc->reg_base + QDSP6SS_MEM_PWR_CTL);
+			udelay(1);
+		}
+		/* Remove word line clamp */
+		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val &= ~QDSP6v56_CLAMP_WL;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+	} else {
+		/* Assert resets, stop core */
+		val = readl(qproc->reg_base + QDSP6SS_RESET_REG);
+		val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
+		writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
+
+		/* Enable power block headswitch and wait for it to stabilize */
+		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= QDSS_BHS_ON | QDSS_LDO_BYP;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		udelay(1);
+		/*
+		 * Turn on memories. L2 banks should be done individually
+		 * to minimize inrush current.
+		 */
+		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N |
+			Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= Q6SS_L2DATA_SLP_NRET_N_2;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= Q6SS_L2DATA_SLP_NRET_N_1;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= Q6SS_L2DATA_SLP_NRET_N_0;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+	}
 	/* Remove IO clamp */
 	val &= ~Q6SS_CLAMP_IO;
 	writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
@@ -775,6 +858,7 @@ static int q6v5_stop(struct rproc *rproc)
 {
 	struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
 	int ret;
+	u32 val;
 
 	qproc->running = false;
 
@@ -792,6 +876,15 @@ static int q6v5_stop(struct rproc *rproc)
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
 	q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
 
+	if (qproc->version == MSS_MSM8996) {
+		/*
+		 * To avoid high MX current during LPASS/MSS restart.
+		 */
+		val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+		val |= Q6SS_CLAMP_IO | QDSP6v56_CLAMP_WL |
+			QDSP6v56_CLAMP_QMC_MEM;
+		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
+	}
 	ret = q6v5_assign_mem_to_linux(qproc,
 			qproc->mpss_phys, qproc->mpss_size);
 	reset_control_assert(qproc->mss_restart);
@@ -1091,6 +1184,7 @@ static int q6v5_probe(struct platform_device *pdev)
 	if (ret)
 		goto free_rproc;
 
+	qproc->version = desc->version;
 	qproc->need_mem_protection = desc->need_mem_protection;
 	ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt);
 	if (ret < 0)
@@ -1140,6 +1234,34 @@ static int q6v5_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct rproc_hexagon_res msm8996_mss = {
+	.hexagon_mba_image = "mba.mbn",
+	.proxy_supply = (struct qcom_mss_reg_res[]) {
+			{}
+	},
+	.active_supply = (struct qcom_mss_reg_res[]) {
+			{},
+			{}
+	},
+	.proxy_clk_names = (char*[]){
+			"xo",
+			"pnoc",
+			"qdss",
+			NULL
+	},
+	.active_clk_names = (char*[]){
+			"iface",
+			"bus",
+			"mem",
+			"gpll0_mss_clk",
+			"snoc_axi_clk",
+			"mnoc_axi_clk",
+			NULL
+	},
+	.need_mem_protection = true,
+	.version = MSS_MSM8996,
+};
+
 static const struct rproc_hexagon_res msm8916_mss = {
 	.hexagon_mba_image = "mba.mbn",
 	.proxy_supply = (struct qcom_mss_reg_res[]) {
@@ -1168,6 +1290,7 @@ static int q6v5_remove(struct platform_device *pdev)
 		NULL
 	},
 	.need_mem_protection = false,
+	.version = MSS_MSM8916,
 };
 
 static const struct rproc_hexagon_res msm8974_mss = {
@@ -1206,12 +1329,14 @@ static int q6v5_remove(struct platform_device *pdev)
 		NULL
 	},
 	.need_mem_protection = false,
+	.version = MSS_MSM8974,
 };
 
 static const struct of_device_id q6v5_of_match[] = {
 	{ .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
 	{ .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
 	{ .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
+	{ .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, q6v5_of_match);
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web