All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex G." <mr.nuke.me@gmail.com>
To: andersson@kernel.org, mathieu.poirier@linaro.org,
	Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>,
	linux-kernel@vger.kernel.org
Cc: krzk+dt@kernel.org, Philipp Zabel <p.zabel@pengutronix.de>,
	linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org
Subject: Re: [PATCH 6/9] remoteproc: qcom_q6v5_wcss: support IPQ9574
Date: Tue, 23 Dec 2025 14:21:08 -0600	[thread overview]
Message-ID: <12223416.nUPlyArG6x@nukework.gtech> (raw)
In-Reply-To: <a14e40b7-b70b-4658-9dee-7e5e6265ad5f@oss.qualcomm.com>

On Friday, December 19, 2025 7:20:04 AM CST Konrad Dybcio wrote:
> On 12/19/25 5:34 AM, Alexandru Gagniuc wrote:
> > Q6 based firmware loading is also present on IPQ9574, when coupled
> > with a wifi-6 device, such as QCN5024. Populate driver data for
> > IPQ9574 with values from the downstream 5.4 kerrnel.
> > 
> > Add the new sequences for the WCSS reset and stop. The downstream
> > 5.4 kernel calls these "Q6V7", so keep the name. This is still worth
> > using with the "q6v5" driver because all other parts of the driver
> > can be seamlessly reused.
> > 
> > The IPQ9574 uses two sets of clocks. the first, dubbed "q6_clocks"
> > must be enabled before the Q6 is started by writing the Q6SS_RST_EVB
> > register. The second set of clocks, "clks" should only be enabled
> > after the Q6 is placed out of reset. Otherwise, the host CPU core that
> > tries to start the remoteproc will hang.
> > 
> > The downstream kernel had a funny comment, "Pray god and wait for
> > reset to complete", which I decided to keep for entertainment value.
> > 
> > Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> > ---
> 
> [...]
> 
> > @@ -128,6 +137,12 @@ struct q6v5_wcss {
> > 
> >  	struct clk *qdsp6ss_xo_cbcr;
> >  	struct clk *qdsp6ss_core_gfmux;
> >  	struct clk *lcc_bcr_sleep;
> > 
> > +	struct clk_bulk_data *clks;
> > +	/* clocks that must be started before the Q6 is booted */
> > +	struct clk_bulk_data *q6_clks;
> 
> "pre_boot_clks" or something along those lines?

I like "pre_boot_clocks".

> In general i'm not super stoked to see another platform where manual and
> through-TZ bringup of remoteprocs is supposed to be supported in parallel..
> 
> Are you sure your firmware doesn't allow you to just do a simple
> qcom_scm_pas_auth_and_reset() like in the multipd series?

I am approaching this from the perspective of an aftermarket OS, like OpenWRT. 
I don't know if the firmware will do the right thing. I can mitigate this for 
OS-loaded firmware, like ath11k 16/m3 firmware, because I can test the driver 
and firmware together. I can't do that for bootloader-loaded firmware, so I try 
to depend on it as little as possible. I hope that native remoterproc loading 
for IPQ9574 will be allowed.

> > +	int num_clks;
> > +	int num_q6_clks;
> > +
> > 
> >  	struct regulator *cx_supply;
> >  	struct qcom_sysmon *sysmon;
> > 
> > @@ -236,6 +251,87 @@ static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
> > 
> >  	return 0;
> >  
> >  }
> > 
> > +static int q6v7_wcss_reset(struct q6v5_wcss *wcss, struct rproc *rproc)
> > +{
> > +	int ret;
> > +	u32 val;
> > +
> > +	/*1. Set TCSR GLOBAL CFG1*/
> 
> Please add a space between the comment markers and the contents
> 
> > +	ret = regmap_update_bits(wcss->halt_map,
> > +				 wcss->halt_nc + 
TCSR_GLOBAL_CFG1,
> > +				 0xff00, 0x1100);
> 
> GENMASK(15, 8), BIT(8) | BIT(12)
 
I find GENMASK() and or'ed BIT()s harder to read than plain hex constants. 
Maybe we should use macros, but what should be the names of these two 
constants?

> > +	if (ret) {
> > +		dev_err(wcss->dev, "TCSE_GLOBAL_CFG1 failed\n");
> 
> I don't think we should count on regmap to ever fail

I was following q6v5_wcss_start(), which also handles regmap failures. Do you 
want me to ignore regmap return codes in the code that is added, at the cost 
of some  inconsistency??

> > +		return ret;
> > +	}
> > +
> > +	/* Enable Q6 clocks */
> 
> Right, this naming gets even more confusing

I'll name it "pre_boot_clocks" and drop the comment in the interest of self-
documenting code.

> > +	ret = clk_bulk_prepare_enable(wcss->num_q6_clks, wcss->q6_clks);
> > +	if (ret) {
> > +		dev_err(wcss->dev, "failed to enable clocks, err=%d\n", 
ret);
> > +		return ret;
> > +	};
> > +
> > +	/* Write bootaddr to EVB so that Q6WCSS will jump there after 
reset */
> 
> That's what a boot address is generally for, no? ;)

I used the same comment from q6v5_wcss_start(). I will shorten the comment.

> > +	writel(rproc->bootaddr >> 4, wcss->reg_base + Q6SS_RST_EVB);
> > +
> > +	/*2. Deassert AON Reset */
> > +	ret = reset_control_deassert(wcss->wcss_aon_reset);
> > +	if (ret) {
> > +		dev_err(wcss->dev, "wcss_aon_reset failed\n");
> > +		clk_bulk_disable_unprepare(wcss->num_clks, wcss->clks);
> > +		return ret;
> > +	}
> > +
> > +	/*8. Set mpm configs*/
> 
> "MPM"
> 
> Why are the indices of your comments not in numerical order?
 
I started with the spaghetti sequence from the downstream kernel. I unravelled 
it, and was so happy the code worked, that I forgot to check the numbering. 
I'll remove the numbers, as they don't add much value..

> > +	/*set CFG[18:15]=1*/
> > +	val = readl(wcss->rmb_base + SSCAON_CONFIG);
> > +	val &= ~SSCAON_MASK;
> > +	val |= SSCAON_BUS_EN;
> > +	writel(val, wcss->rmb_base + SSCAON_CONFIG);
> > +
> > +	/*9. Wait for SSCAON_STATUS */
> > +	ret = readl_poll_timeout(wcss->rmb_base + SSCAON_STATUS,
> > +				 val, (val & 0xffff) == 0x10, 1000,
> > +				 Q6SS_TIMEOUT_US * 1000);
> > +	if (ret) {
> > +		dev_err(wcss->dev, " Boot Error, SSCAON=0x%08X\n", 
val);
> > +		return ret;
> 
> You left the clocks on in this path

Good catch! I will use "goto" centralized exiting to turn off resources on 
failure.

> > +	}
> > +
> > +	/*3. BHS require xo cbcr to be enabled */
> > +	val = readl(wcss->reg_base + Q6SS_XO_CBCR);
> > +	val |= 0x1;
> 
> That's BIT(0)
> 
> In qcom_q6v5_mss.c you'll notice this is defined as Q6SS_CBCR_CLKEN
> 
> If you dig a little deeper, you'll also notice a similar name in
> drivers/clk/qcom/clk-branch.[ch].. I suppose they just reused the same
> kind of HW on the remoteproc side

I'll use the macro name as suggested. Thank you!

> > +	writel(val, wcss->reg_base + Q6SS_XO_CBCR);
> > +
> > +	/*4. Enable core cbcr*/
> > +	val = readl(wcss->reg_base + Q6SS_CORE_CBCR);
> > +	val |= 0x1;
> > +	writel(val, wcss->reg_base + Q6SS_CORE_CBCR);
> > +
> > +	/*5. Enable sleep cbcr*/
> > +	val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
> > +	val |= 0x1;
> > +	writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
> > +
> > +	/*6. Boot core start */
> > +	writel(0x1, wcss->reg_base + Q6SS_BOOT_CORE_START);
> > +	writel(0x1, wcss->reg_base + Q6SS_BOOT_CMD);
> > +
> > +	/*7. Pray god and wait for reset to complete*/
> 
> "ora et labora" - you've done your work, so I'd assume we can
> expect success now
> 
> > +	ret = readl_poll_timeout(wcss->reg_base + Q6SS_BOOT_STATUS, val,
> > +				 (val & 0x01), 20000, 1000);
> 
> The timeout is smaller than the retry delay value, this will only spin
> once
> 
> 0x01 is also BIT(0)
> 
> But since you never check whether that timeout has actually been
> reached, I assume you really stand by the comment!
> 
> (you need this hunk):
> if (ret) {
> 	dev_err(wcss->dev, "WCSS boot timed out\n");
> 	// cleanup
> 	return -ETIMEDOUT;
> }

Good catches! Yes, I definitely meant 20 millisecond timeout (not 1 ms). I will 
also add the error checking.

> > +
> > +	/* Enable non-Q6 clocks */
> > +	ret = clk_bulk_prepare_enable(wcss->num_clks, wcss->clks);
> > +	if (ret) {
> > +		dev_err(wcss->dev, "failed to enable clocks, err=%d\n", 
ret);
> 
> the previous set of clocks will be left enabled in this case too
> 
> > +		return ret;
> > +	};
> > +
> > +	return 0;
> 
> If you return ret here, you can drop the return in the above scope

This part will get changed a bit by the centralized exiting. It will be a 
"goto" (on error) followed by "return 0" (on success).

> > +}
> > +
> > 
> >  static int q6v5_wcss_start(struct rproc *rproc)
> >  {
> >  
> >  	struct q6v5_wcss *wcss = rproc->priv;
> > 
> > @@ -270,10 +366,20 @@ static int q6v5_wcss_start(struct rproc *rproc)
> > 
> >  	if (ret)
> >  	
> >  		goto wcss_q6_reset;
> > 
> > -	/* Write bootaddr to EVB so that Q6WCSS will jump there after 
reset */
> > -	writel(rproc->bootaddr >> 4, wcss->reg_base + Q6SS_RST_EVB);
> > +	switch (wcss->version) {
> > +	case WCSS_QCS404:
> > +	case WCSS_IPQ8074:
> > +		/* Write bootaddr to EVB so that Q6WCSS will jump there 
after
> > +		 * reset.
> > +		 */
> 
> /* foo */?

I was trying to keep it at 80 characters, but since I will shorten this 
comment on the new code paths, I will shorten it here too.

> [...]
> 
> > +static void q6v7_q6_powerdown(struct q6v5_wcss *wcss)
> > +{
> > +	uint32_t val;
> 
> "u32"

Okay.

> > +
> > +	q6v5_wcss_halt_axi_port(wcss, wcss->halt_map, wcss->halt_q6);
> > +
> > +	/* Disable Q6 Core clock -- we don't know what bit 0 means */
> 
> I would assume clearing it muxes the clocksource to XO
> 
> [...]
> 
> > +static int ipq9574_init_clocks(struct q6v5_wcss *wcss)
> > +{
> > +	static const char *const q6_clks[] = {
> > +		"anoc_wcss_axi_m", "q6_ahb", "q6_ahb_s", "q6_axim", 
"q6ss_boot",
> > +		"mem_noc_q6_axi", "sys_noc_wcss_ahb", "wcss_acmt", 
"wcss_ecahb",
> > +		"wcss_q6_tbu" };
> > +	static const char *const clks[] = {
> > +		"q6_axim2", "wcss_ahb_s", "wcss_axi_m" };
> 
> static local variables that we point to? eeeeeeh

I wanted "const char *clks[]" originally. I changed it to this in order to 
appease checkpatch. Should I use my original "const char * []" instead?

[...]

Alex




  reply	other threads:[~2025-12-23 20:21 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-19  4:34 [PATCH 1/9] dt-bindings: remoteproc: qcom,ipq8074-wcss-pil: convert to DT schema Alexandru Gagniuc
2025-12-19  4:34 ` [PATCH 2/9] dt-bindings: remoteproc: qcom: add IPQ9574 image loader Alexandru Gagniuc
2025-12-19  5:37   ` Rob Herring (Arm)
2025-12-19 14:44   ` Rob Herring
2025-12-20  8:54     ` Krzysztof Kozlowski
2025-12-23 19:45       ` Alex G.
2025-12-20  8:56   ` Krzysztof Kozlowski
2025-12-19  4:34 ` [PATCH 3/9] dt-bindings: clock: gcc-ipq9574: add wcss remoteproc clocks Alexandru Gagniuc
2025-12-19  4:34 ` [PATCH 4/9] arm64: dts: qcom: ipq9574: add wcss remoteproc nodes Alexandru Gagniuc
2025-12-19 13:43   ` Konrad Dybcio
2025-12-19  4:34 ` [PATCH 5/9] clk: qcom: gcc-ipq9574: add wcss remoteproc clocks Alexandru Gagniuc
2025-12-19  4:34 ` [PATCH 6/9] remoteproc: qcom_q6v5_wcss: support IPQ9574 Alexandru Gagniuc
2025-12-19 13:20   ` Konrad Dybcio
2025-12-23 20:21     ` Alex G. [this message]
2025-12-24  9:44       ` Vignesh Viswanathan
2025-12-24 17:36         ` Alex G.
2025-12-29 12:35       ` Konrad Dybcio
2026-01-05 16:09         ` mr.nuke.me
2026-01-05 17:57           ` Vignesh Viswanathan
2026-01-07 13:26           ` Konrad Dybcio
2026-01-07 18:25             ` Vignesh Viswanathan
2025-12-19  4:34 ` [PATCH 7/9] remoteproc: qcom_q6v5_wcss: support m3 firmware Alexandru Gagniuc
2025-12-19 13:29   ` Konrad Dybcio
2025-12-23 20:35     ` Alex G.
2025-12-29 12:37       ` Konrad Dybcio
2026-01-05 15:23         ` mr.nuke.me
2026-01-05 18:00           ` Vignesh Viswanathan
2026-01-07 11:55           ` Konrad Dybcio
2025-12-19  4:34 ` [PATCH 8/9] remoteproc: qcom_q6v5_wcss: drop unused clocks from q6v5 struct Alexandru Gagniuc
2025-12-19 13:31   ` Konrad Dybcio
2025-12-19  4:34 ` [PATCH 9/9] remoteproc: qcom_q6v5_wcss: use bulk clk API for q6 clocks in QCS404 Alexandru Gagniuc
2025-12-19 14:52 ` [PATCH 1/9] dt-bindings: remoteproc: qcom,ipq8074-wcss-pil: convert to DT schema Krzysztof Kozlowski
2025-12-20 18:40   ` Alex G.
2025-12-19 16:49 ` Rob Herring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=12223416.nUPlyArG6x@nukework.gtech \
    --to=mr.nuke.me@gmail.com \
    --cc=andersson@kernel.org \
    --cc=konrad.dybcio@oss.qualcomm.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=p.zabel@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.