[PATCH v2 3/9] remoteproc: qcom_q6v5_mss: Add MDM9607

Barnabás Czémán posted 9 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH v2 3/9] remoteproc: qcom_q6v5_mss: Add MDM9607
Posted by Barnabás Czémán 1 month, 1 week ago
From: Stephan Gerhold <stephan@gerhold.net>

Add support for MDM9607 MSS it have different ACC settings
and it needs mitigation for inrush current issue.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
[Reword the commit, add has_ext_bhs_reg]
Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
---
 drivers/remoteproc/qcom_q6v5_mss.c | 70 ++++++++++++++++++++++++++++++++++----
 1 file changed, 63 insertions(+), 7 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index 3c404118b322..a64e57544efb 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -124,6 +124,7 @@
 #define QDSP6v56_CLAMP_QMC_MEM		BIT(22)
 #define QDSP6SS_XO_CBCR		0x0038
 #define QDSP6SS_ACC_OVERRIDE_VAL		0x20
+#define QDSP6SS_ACC_OVERRIDE_VAL_9607	0x80800000
 #define QDSP6v55_BHS_EN_REST_ACK	BIT(0)
 
 /* QDSP6v65 parameters */
@@ -256,6 +257,7 @@ struct q6v5 {
 };
 
 enum {
+	MSS_MDM9607,
 	MSS_MSM8226,
 	MSS_MSM8909,
 	MSS_MSM8916,
@@ -747,15 +749,19 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 			return ret;
 		}
 		goto pbl_wait;
-	} else if (qproc->version == MSS_MSM8909 ||
+	} else if (qproc->version == MSS_MDM9607 ||
+		   qproc->version == MSS_MSM8909 ||
 		   qproc->version == MSS_MSM8953 ||
 		   qproc->version == MSS_MSM8996 ||
 		   qproc->version == MSS_MSM8998 ||
 		   qproc->version == MSS_SDM660) {
 
-		if (qproc->version != MSS_MSM8909 &&
-		    qproc->version != MSS_MSM8953)
-			/* Override the ACC value if required */
+		/* Override the ACC value if required */
+		if (qproc->version == MSS_MDM9607)
+			writel(QDSP6SS_ACC_OVERRIDE_VAL_9607,
+			       qproc->reg_base + QDSP6SS_STRAP_ACC);
+		else if (qproc->version != MSS_MSM8909 &&
+			 qproc->version != MSS_MSM8953)
 			writel(QDSP6SS_ACC_OVERRIDE_VAL,
 			       qproc->reg_base + QDSP6SS_STRAP_ACC);
 
@@ -800,7 +806,7 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 		writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
 
 		if (qproc->version != MSS_MSM8909) {
-			int mem_pwr_ctl;
+			int mem_pwr_ctl, reverse = 0;
 
 			/* Deassert QDSP6 compiler memory clamp */
 			val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
@@ -812,17 +818,25 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 			writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG);
 
 			/* Turn on L1, L2, ETB and JU memories 1 at a time */
-			if (qproc->version == MSS_MSM8953 ||
+			if (qproc->version == MSS_MDM9607 ||
+			    qproc->version == MSS_MSM8953 ||
 			    qproc->version == MSS_MSM8996) {
 				mem_pwr_ctl = QDSP6SS_MEM_PWR_CTL;
 				i = 19;
+
+				/*
+				 * Set first 5 bits in reverse to avoid
+				 * "inrush current" issues.
+				 */
+				if (qproc->version == MSS_MDM9607)
+					reverse = 6;
 			} else {
 				/* MSS_MSM8998, MSS_SDM660 */
 				mem_pwr_ctl = QDSP6V6SS_MEM_PWR_CTL;
 				i = 28;
 			}
 			val = readl(qproc->reg_base + mem_pwr_ctl);
-			for (; i >= 0; i--) {
+			for (; i >= reverse; i--) {
 				val |= BIT(i);
 				writel(val, qproc->reg_base + mem_pwr_ctl);
 				/*
@@ -833,6 +847,12 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 				val |= readl(qproc->reg_base + mem_pwr_ctl);
 				udelay(1);
 			}
+			for (i = 0; i < reverse; i++) {
+				val |= BIT(i);
+				writel(val, qproc->reg_base + mem_pwr_ctl);
+				val |= readl(qproc->reg_base + mem_pwr_ctl);
+				udelay(1);
+			}
 		} else {
 			/* Turn on memories */
 			val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG);
@@ -2410,6 +2430,41 @@ static const struct rproc_hexagon_res msm8996_mss = {
 	.version = MSS_MSM8996,
 };
 
+static const struct rproc_hexagon_res mdm9607_mss = {
+	.hexagon_mba_image = "mba.mbn",
+	.proxy_supply = (struct qcom_mss_reg_res[]) {
+		{
+			.supply = "pll",
+			.uA = 100000,
+		},
+		{}
+	},
+	.proxy_clk_names = (char*[]){
+		"xo",
+		NULL
+	},
+	.active_clk_names = (char*[]){
+		"iface",
+		"bus",
+		"mem",
+		NULL
+	},
+	.proxy_pd_names = (char*[]){
+		"mx",
+		"cx",
+		NULL
+	},
+	.need_mem_protection = false,
+	.has_alt_reset = false,
+	.has_mba_logs = false,
+	.has_spare_reg = false,
+	.has_qaccept_regs = false,
+	.has_ext_bhs_reg = false,
+	.has_ext_cntl_regs = false,
+	.has_vq6 = false,
+	.version = MSS_MDM9607,
+};
+
 static const struct rproc_hexagon_res msm8909_mss = {
 	.hexagon_mba_image = "mba.mbn",
 	.proxy_supply = (struct qcom_mss_reg_res[]) {
@@ -2672,6 +2727,7 @@ static const struct rproc_hexagon_res msm8926_mss = {
 
 static const struct of_device_id q6v5_of_match[] = {
 	{ .compatible = "qcom,q6v5-pil", .data = &msm8916_mss},
+	{ .compatible = "qcom,mdm9607-mss-pil", .data = &mdm9607_mss},
 	{ .compatible = "qcom,msm8226-mss-pil", .data = &msm8226_mss},
 	{ .compatible = "qcom,msm8909-mss-pil", .data = &msm8909_mss},
 	{ .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},

-- 
2.52.0

Re: [PATCH v2 3/9] remoteproc: qcom_q6v5_mss: Add MDM9607
Posted by Konrad Dybcio 1 month, 1 week ago
On 12/31/25 3:29 AM, Barnabás Czémán wrote:
> From: Stephan Gerhold <stephan@gerhold.net>
> 
> Add support for MDM9607 MSS it have different ACC settings
> and it needs mitigation for inrush current issue.
> 
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> [Reword the commit, add has_ext_bhs_reg]
> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
> ---

[...]

>  			val = readl(qproc->reg_base + mem_pwr_ctl);
> -			for (; i >= 0; i--) {
> +			for (; i >= reverse; i--) {
>  				val |= BIT(i);
>  				writel(val, qproc->reg_base + mem_pwr_ctl);
>  				/*
> @@ -833,6 +847,12 @@ static int q6v5proc_reset(struct q6v5 *qproc)
>  				val |= readl(qproc->reg_base + mem_pwr_ctl);
>  				udelay(1);
>  			}
> +			for (i = 0; i < reverse; i++) {
> +				val |= BIT(i);
> +				writel(val, qproc->reg_base + mem_pwr_ctl);
> +				val |= readl(qproc->reg_base + mem_pwr_ctl);

Downstream doesn't do val |= readl() in the inrush-current-mitigation
case

Konrad
Re: [PATCH v2 3/9] remoteproc: qcom_q6v5_mss: Add MDM9607
Posted by barnabas.czeman@mainlining.org 1 month, 1 week ago
On 2025-12-31 13:27, Konrad Dybcio wrote:
> On 12/31/25 3:29 AM, Barnabás Czémán wrote:
>> From: Stephan Gerhold <stephan@gerhold.net>
>> 
>> Add support for MDM9607 MSS it have different ACC settings
>> and it needs mitigation for inrush current issue.
>> 
>> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
>> [Reword the commit, add has_ext_bhs_reg]
>> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
>> ---
> 
> [...]
> 
>>  			val = readl(qproc->reg_base + mem_pwr_ctl);
>> -			for (; i >= 0; i--) {
>> +			for (; i >= reverse; i--) {
>>  				val |= BIT(i);
>>  				writel(val, qproc->reg_base + mem_pwr_ctl);
>>  				/*
>> @@ -833,6 +847,12 @@ static int q6v5proc_reset(struct q6v5 *qproc)
>>  				val |= readl(qproc->reg_base + mem_pwr_ctl);
>>  				udelay(1);
>>  			}
>> +			for (i = 0; i < reverse; i++) {
>> +				val |= BIT(i);
>> +				writel(val, qproc->reg_base + mem_pwr_ctl);
>> +				val |= readl(qproc->reg_base + mem_pwr_ctl);
> 
> Downstream doesn't do val |= readl() in the inrush-current-mitigation
> case
I have checked you are right, thanks. 1_8 reset sequence have it but 
1_8_inrush_current have not.
As i understanding from downstream it should be handled in both for 
loop, i could add an if for
handle this or implement 1_8_inrush_current reset separately. Which one 
would be the preferred?
> 
> Konrad
Re: [PATCH v2 3/9] remoteproc: qcom_q6v5_mss: Add MDM9607
Posted by Konrad Dybcio 1 month, 1 week ago
On 12/31/25 3:50 PM, barnabas.czeman@mainlining.org wrote:
> On 2025-12-31 13:27, Konrad Dybcio wrote:
>> On 12/31/25 3:29 AM, Barnabás Czémán wrote:
>>> From: Stephan Gerhold <stephan@gerhold.net>
>>>
>>> Add support for MDM9607 MSS it have different ACC settings
>>> and it needs mitigation for inrush current issue.
>>>
>>> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
>>> [Reword the commit, add has_ext_bhs_reg]
>>> Signed-off-by: Barnabás Czémán <barnabas.czeman@mainlining.org>
>>> ---
>>
>> [...]
>>
>>>              val = readl(qproc->reg_base + mem_pwr_ctl);
>>> -            for (; i >= 0; i--) {
>>> +            for (; i >= reverse; i--) {
>>>                  val |= BIT(i);
>>>                  writel(val, qproc->reg_base + mem_pwr_ctl);
>>>                  /*
>>> @@ -833,6 +847,12 @@ static int q6v5proc_reset(struct q6v5 *qproc)
>>>                  val |= readl(qproc->reg_base + mem_pwr_ctl);
>>>                  udelay(1);
>>>              }
>>> +            for (i = 0; i < reverse; i++) {
>>> +                val |= BIT(i);
>>> +                writel(val, qproc->reg_base + mem_pwr_ctl);
>>> +                val |= readl(qproc->reg_base + mem_pwr_ctl);
>>
>> Downstream doesn't do val |= readl() in the inrush-current-mitigation
>> case
> I have checked you are right, thanks. 1_8 reset sequence have it but 1_8_inrush_current have not.
> As i understanding from downstream it should be handled in both for loop, i could add an if for
> handle this or implement 1_8_inrush_current reset separately. Which one would be the preferred?

Let's do the latter - there's enough nested 'if's in here already

Konrad