[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <aYY_72kT63lH1h2r@lizhi-Precision-Tower-5810>
Date: Fri, 6 Feb 2026 14:24:31 -0500
From: Frank Li <Frank.li@....com>
To: Md Sadre Alam <quic_mdalam@...cinc.com>
Cc: andersson@...nel.org, konradybcio@...nel.org, robh@...nel.org,
krzk+dt@...nel.org, conor+dt@...nel.org, vkoul@...nel.org,
Frank.Li@...nel.org, linux-arm-msm@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
dmaengine@...r.kernel.org, quic_varada@...cinc.com
Subject: Re: [PATCH v4 1/7] dma: qcom: bam_dma: Fix command element mask
field for BAM v1.6.0+
On Fri, Feb 06, 2026 at 03:31:56PM +0530, Md Sadre Alam wrote:
> BAM version 1.6.0 and later changed the behavior of the mask field in
> command elements for read operations. In newer BAM versions, the mask
> field for read commands contains the upper 4 bits of the destination
> address to support 36-bit addressing, while for write commands it
> continues to function as a traditional write mask.
>
> This change causes NAND enumeration failures on platforms like IPQ5424
> that use BAM v1.6.0+, because the current code sets mask=0xffffffff
> for all commands. For read commands on newer BAM versions, this results
> in the hardware interpreting the destination address as 0xf_xxxxxxxx
> (invalid high memory) instead of the intended 0x0_xxxxxxxx address.
>
> Fixed this issue by:
> 1. Updating the bam_cmd_element structure documentation to reflect the
> dual purpose of the mask field
> 2. Modifying bam_prep_ce_le32() to set appropriate mask values based on
> command type:
> - For read commands: mask = 0 (32-bit addressing, upper bits = 0)
> - For write commands: mask = 0xffffffff (traditional write mask)
> 3. Maintaining backward compatibility with older BAM versions
>
> This fix enables proper NAND functionality on IPQ5424 and other platforms
> using BAM v1.6.0+ while preserving compatibility with existing systems.
>
> Tested-by: Lakshmi Sowjanya D <quic_laksd@...cinc.com>
> Signed-off-by: Md Sadre Alam <quic_mdalam@...cinc.com>
> ---
>
> Change in [v4]
Reviewed-by: Frank Li <Frank.Li@....com>
>
> * No change
>
> Change in [v3]
>
> * Added Tested-by tag
>
> Change in [v2]
>
> * No change
>
> Change in [v1]
>
> * Updated bam_prep_ce_le32() to set the mask field conditionally based on
> command type
>
> * Enhanced kernel-doc comments to clarify mask behavior for BAM v1.6.0+
>
> include/linux/dma/qcom_bam_dma.h | 21 ++++++++++++++++-----
> 1 file changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/dma/qcom_bam_dma.h b/include/linux/dma/qcom_bam_dma.h
> index 68fc0e643b1b..d9d07a9ab313 100644
> --- a/include/linux/dma/qcom_bam_dma.h
> +++ b/include/linux/dma/qcom_bam_dma.h
> @@ -13,9 +13,12 @@
> * supported by BAM DMA Engine.
> *
> * @cmd_and_addr - upper 8 bits command and lower 24 bits register address.
> - * @data - for write command: content to be written into peripheral register.
> - * for read command: dest addr to write peripheral register value.
> - * @mask - register mask.
> + * @data - For write command: content to be written into peripheral register.
> + * For read command: lower 32 bits of destination address.
> + * @mask - For write command: register write mask.
> + * For read command on BAM v1.6.0+: upper 4 bits of destination address.
> + * For read command on BAM < v1.6.0: ignored by hardware.
> + * Setting to 0 ensures 32-bit addressing compatibility.
> * @reserved - for future usage.
> *
> */
> @@ -42,6 +45,10 @@ enum bam_command_type {
> * @addr: target address
> * @cmd: BAM command
> * @data: actual data for write and dest addr for read in le32
> + *
> + * For BAM v1.6.0+, the mask field behavior depends on command type:
> + * - Write commands: mask = write mask (typically 0xffffffff)
> + * - Read commands: mask = upper 4 bits of destination address (0 for 32-bit)
> */
> static inline void
> bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr,
> @@ -50,7 +57,11 @@ bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr,
> bam_ce->cmd_and_addr =
> cpu_to_le32((addr & 0xffffff) | ((cmd & 0xff) << 24));
> bam_ce->data = data;
> - bam_ce->mask = cpu_to_le32(0xffffffff);
> + if (cmd == BAM_READ_COMMAND)
> + bam_ce->mask = cpu_to_le32(0x0); /* 32-bit addressing */
> + else
> + bam_ce->mask = cpu_to_le32(0xffffffff); /* Write mask */
> + bam_ce->reserved = 0;
> }
>
> /*
> @@ -60,7 +71,7 @@ bam_prep_ce_le32(struct bam_cmd_element *bam_ce, u32 addr,
> * @bam_ce: BAM command element
> * @addr: target address
> * @cmd: BAM command
> - * @data: actual data for write and dest addr for read
> + * @data: actual data for write and destination address for read
> */
> static inline void
> bam_prep_ce(struct bam_cmd_element *bam_ce, u32 addr,
> --
> 2.34.1
>
Powered by blists - more mailing lists