From: Thomas Gleixner <tglx@linutronix.de>
To: Stephan Gerhold <stephan.gerhold@linaro.org>
Cc: Bjorn Andersson <andersson@kernel.org>,
Konrad Dybcio <konradybcio@kernel.org>,
Rajendra Nayak <quic_rjendra@quicinc.com>,
Maulik Shah <quic_mkshah@quicinc.com>,
Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
Abel Vesa <abel.vesa@linaro.org>,
Johan Hovold <johan.hovold@linaro.org>,
linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] irqchip/qcom-pdc: Workaround hardware register bug on X1E80100
Date: Fri, 14 Feb 2025 00:29:16 +0100 [thread overview]
Message-ID: <87h64xjuer.ffs@tglx> (raw)
In-Reply-To: <20250213-x1e80100-pdc-hw-wa-v1-1-f8c248a48cba@linaro.org>
On Thu, Feb 13 2025 at 18:04, Stephan Gerhold wrote:
> +
> +static void _pdc_reg_write(void __iomem *base, int reg, u32 i, u32 val)
Please use two leading underscores to make this easy to
distinguish. But ideally you provide a proper function name which makes
it clear that this function operates on a given base address contrary to
pdc_reg_write() which uses pdc_base unconditionally.
> +{
> + writel_relaxed(val, base + reg + i * sizeof(u32));
> +}
>
> static void pdc_reg_write(int reg, u32 i, u32 val)
> {
> - writel_relaxed(val, pdc_base + reg + i * sizeof(u32));
> + _pdc_reg_write(pdc_base, reg, i, val);
> }
>
> static u32 pdc_reg_read(int reg, u32 i)
> @@ -60,6 +69,26 @@ static u32 pdc_reg_read(int reg, u32 i)
> return readl_relaxed(pdc_base + reg + i * sizeof(u32));
> }
>
> +static void pdc_x1e_irq_enable_write(u32 bank, u32 enable)
> +{
> + void __iomem *base = pdc_base; /* DRV2 */
Please do not use tail comments. Also what is DRV2?
> +
> + /*
> + * Workaround hardware bug in the register logic on X1E80100:
> + * - For bank 0-1, writes need to be made to DRV1, bank 3 and 4.
> + * - For bank 2-4, writes need to be made to DRV2, bank 0-2.
> + * - Bank 5 works as expected.
> + */
> + if (bank <= 1) {
> + base = pdc_drv1;
> + bank += 3;
> + } else if (bank <= 4) {
> + bank -= 2;
> + }
This is confusing at best. You map two different base addresses:
1) The existing pdc_base, which magically is associated to DRV2
(whatever that means)
2) A new magic pdc_drv1 mapping
Then you implement the workaround logic in a pretty uncomprehensible
way. I had to stare at it more than once to make sure that it matches
the comment. What about:
/* Remap the bank access to work around the X1E hardware bug. */
switch (bank) {
case 0..1:
/* Use special mapping and shift to bank 3-4 */
base = pdc_base_x1e_quirk;
bank += 3;
break;
case 2..4:
/* Use regular mapping and shift to bank 0-2 */
base = pdc_base;
bank -= 2;
break;
case 5:
/* No fixup required */
base = pdc_base;
break;
}
which makes it obvious what this is about. Hmm?
> + _pdc_reg_write(base, IRQ_ENABLE_BANK, bank, enable);
> @@ -324,10 +357,21 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent)
> if (res_size > resource_size(&res))
> pr_warn("%pOF: invalid reg size, please fix DT\n", node);
>
> + if (of_device_is_compatible(node, "qcom,x1e80100-pdc")) {
> + pdc_drv1 = ioremap(res.start - PDC_DRV_OFFSET, IRQ_ENABLE_BANK_MAX);
What? This maps outside of the resource region. That's neither documented in
the change log nor explained here.
I assume this can't be properly fixed in the device tree for backwards
compability reasons, but leaving this undocumented is a recipe for head
scratching three month down the road.
PDC_DRV_OFFSET is not obvious either.
You really want to explain this properly at least in the change log,
i.e.:
X1E80100 has a hardware bug related to the address decoding of write
accesses to the IRQ_ENABLE_BANK register.
Correct implementations access it linear from the base address:
addr[bank] = base_addr + IRQ_ENABLE_BANK + bank * sizeof(u32);
The X1E80100 bug requires the following address mangling:
addr[bank0] = base_addr - 0x10000 + IRQ_ENABLE_BANK + 3 * sizeof(u32);
addr[bank1] = base_addr - 0x10000 + IRQ_ENABLE_BANK + 4 * sizeof(u32);
addr[bank2] = base_addr + IRQ_ENABLE_BANK + 0 * sizeof(u32);
addr[bank3] = base_addr + IRQ_ENABLE_BANK + 1 * sizeof(u32);
addr[bank4] = base_addr + IRQ_ENABLE_BANK + 2 * sizeof(u32);
addr[bank5] = base_addr + IRQ_ENABLE_BANK + 5 * sizeof(u32);
The offset (0x10000) is outside of the resource region and requires
therefore a seperate mapping. This can't be expressed in the device
tree for $sensible reasons.
Mapping this region is safe because $sensible reason.
I might have oracled this out of the patch/change log incorrectly, but
you get the idea.
Thanks,
tglx
prev parent reply other threads:[~2025-02-13 23:29 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-13 17:04 [PATCH] irqchip/qcom-pdc: Workaround hardware register bug on X1E80100 Stephan Gerhold
2025-02-13 17:14 ` Johan Hovold
2025-02-13 22:14 ` Dmitry Baryshkov
2025-02-13 23:29 ` Thomas Gleixner [this message]
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=87h64xjuer.ffs@tglx \
--to=tglx@linutronix.de \
--cc=abel.vesa@linaro.org \
--cc=andersson@kernel.org \
--cc=johan.hovold@linaro.org \
--cc=konradybcio@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=quic_mkshah@quicinc.com \
--cc=quic_rjendra@quicinc.com \
--cc=srinivas.kandagatla@linaro.org \
--cc=stephan.gerhold@linaro.org \
/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.