Re: [PATCH v4 2/3] i3c: mipi-i3c-hci: Add PIO queue management support for HCI v1.2

Frank Li <[email protected]>
Newsgroups org.infradead.lists.linux-i3c
Message-ID <aoS1poPng3geJo03@lizhi-Precision-Tower-5810>
On Tue, Aug 18, 2026 at 06:41:05PM +0800, Jian-Ming Liao wrote:
> Support explicit enablement and starting of PIO queues as required by
> HCI v1.2.
> Handle alternate PIO queue sizes via ALT_QUEUE_SIZE register.
> Implement explicit PIO queue stopping/disabling and restart logic after
> errors.
>
> Co-developed-by: Patrick Yen <[email protected]>
> Signed-off-by: Patrick Yen <[email protected]>
> Signed-off-by: Jian-Ming Liao <[email protected]>
> ---

Reviewed-by: Frank Li <[email protected]>

> v4:
>  - No content changes. Resent to fix From:/Signed-off-by: address
>    mismatch caused by mail relay configuration (Frank).
> v3:
>  - No functional code changes.
>  - Aligned From: and Signed-off-by: email addresses (Adrian).
> v2:
>  - Removed '-' prefixes from commit message (Frank).
>  - Aligned GENMASK bit definitions with existing macro styles (Frank).
>  - Reverted unnecessary dev_dbg line movements (Frank).
>  - Removed manual kfree(pio) as pio is devm managed (Frank).
>  - Introduced helper macro for HCI version checks (Frank).
>
>  drivers/i3c/master/mipi-i3c-hci/core.c |  1 +
>  drivers/i3c/master/mipi-i3c-hci/hci.h  |  5 ++
>  drivers/i3c/master/mipi-i3c-hci/pio.c  | 67 ++++++++++++++++++++++++--
>  3 files changed, 69 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c
> index e80aa1f5722e..dccc974ef15a 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/core.c
> +++ b/drivers/i3c/master/mipi-i3c-hci/core.c
> @@ -1031,6 +1031,7 @@ static int i3c_hci_init(struct i3c_hci *hci)
>  	switch (regval & ~0xf) {
>  	case 0x100:	/* version 1.0 */
>  	case 0x110:	/* version 1.1 */
> +	case 0x120:	/* version 1.2 */
>  	case 0x200:	/* version 2.0 */
>  		break;
>  	default:
> diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h
> index b3d9803b1968..becccb1a8cf5 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/hci.h
> +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h
> @@ -30,6 +30,11 @@
>  #define reg_set(r, v)		reg_write(r, reg_read(r) | (v))
>  #define reg_clear(r, v)		reg_write(r, reg_read(r) & ~(v))
>
> +/* helper macro for HCI version check */
> +#define hci_version_at_least(hci, maj, min) \
> +	((hci)->version_major > (maj) || \
> +	((hci)->version_major == (maj) && (hci)->version_minor >= (min)))
> +
>  struct hci_cmd_ops;
>
>  struct dat_words {
> diff --git a/drivers/i3c/master/mipi-i3c-hci/pio.c b/drivers/i3c/master/mipi-i3c-hci/pio.c
> index a1341d66bc65..439578a6eb54 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/pio.c
> +++ b/drivers/i3c/master/mipi-i3c-hci/pio.c
> @@ -45,6 +45,11 @@
>  #define IBI_STATUS_SIZE			GENMASK(15, 8)
>  #define CR_QUEUE_SIZE			GENMASK(7, 0)
>
> +#define PIO_ALT_QUEUE_SIZE		0x1C
> +#define EXT_IBI_QUEUE_EN		BIT(28)
> +#define ALT_RESP_QUEUE_EN		BIT(24)
> +#define ALT_RESP_QUEUE_SIZE		GENMASK(7, 0)
> +
>  #define PIO_INTR_STATUS			0x20
>  #define PIO_INTR_STATUS_ENABLE		0x24
>  #define PIO_INTR_SIGNAL_ENABLE		0x28
> @@ -72,6 +77,11 @@
>  #define STAT_RX_THLD			BIT(1)
>  #define STAT_TX_THLD			BIT(0)
>
> +#define PIO_CONTROL			0x30
> +#define PIO_CONTROL_ABORT		BIT(2)
> +#define PIO_CONTROL_RS			BIT(1)
> +#define PIO_CONTROL_ENABLE		BIT(0)
> +
>  #define PIO_QUEUE_CUR_STATUS		0x38
>  #define CUR_IBI_Q_LEVEL			GENMASK(28, 20)
>  #define CUR_RESP_Q_LEVEL		GENMASK(18, 10)
> @@ -173,6 +183,14 @@ static void __hci_pio_init(struct i3c_hci *hci, u32 *size_val_ptr)
>  	 * IBI queue size within allowed bounds.
>  	 */
>  	ibi_val = FIELD_GET(IBI_STATUS_SIZE, size_val);
> +	/* Adjust actual IBI queue size based on v1.2 ALT_QUEUE_SIZE */
> +	if (hci_version_at_least(hci, 1, 2)) {
> +		u32 alt_val = pio_reg_read(ALT_QUEUE_SIZE);
> +
> +		if (alt_val & EXT_IBI_QUEUE_EN)
> +			ibi_val *= 8;
> +	}
> +
>  	pio->max_ibi_thresh = clamp_val(ibi_val/2, 1, 63);
>  	val = FIELD_PREP(QUEUE_IBI_STATUS_THLD, 1) |
>  	      FIELD_PREP(QUEUE_IBI_DATA_THLD, pio->max_ibi_thresh) |
> @@ -190,6 +208,17 @@ static void __hci_pio_init(struct i3c_hci *hci, u32 *size_val_ptr)
>  	 * (will be activated on first xfer).
>  	 */
>  	pio->enabled_irqs = STAT_ALL_ERRORS | STAT_IBI_STATUS_THLD;
> +
> +	/* MIPI I3C HCI v1.2 requires explicitly enabling and starting PIO queues */
> +	if (hci_version_at_least(hci, 1, 2)) {
> +		u32 ctl_val = pio_reg_read(CONTROL);
> +
> +		if (!(ctl_val & PIO_CONTROL_ENABLE)) {
> +			ctl_val |= PIO_CONTROL_ENABLE;
> +			pio_reg_write(CONTROL, ctl_val);
> +		}
> +		pio_reg_write(CONTROL, ctl_val | PIO_CONTROL_RS);
> +	}
>  }
>
>  static void hci_pio_suspend(struct i3c_hci *hci)
> @@ -208,6 +237,7 @@ static int hci_pio_init(struct i3c_hci *hci)
>  {
>  	struct hci_pio_data *pio;
>  	u32 size_val;
> +	u32 cmd_sz, resp_sz, ibi_val;
>
>  	pio = devm_kzalloc(hci->master.dev.parent, sizeof(*pio), GFP_KERNEL);
>  	if (!pio)
> @@ -217,10 +247,24 @@ static int hci_pio_init(struct i3c_hci *hci)
>
>  	__hci_pio_init(hci, &size_val);
>
> -	dev_dbg(&hci->master.dev, "CMD/RESP FIFO = %ld entries\n",
> -		FIELD_GET(CR_QUEUE_SIZE, size_val));
> -	dev_dbg(&hci->master.dev, "IBI FIFO = %ld bytes\n",
> -		4 * FIELD_GET(IBI_STATUS_SIZE, size_val));
> +	cmd_sz = FIELD_GET(CR_QUEUE_SIZE, size_val);
> +	resp_sz = cmd_sz;
> +	ibi_val = FIELD_GET(IBI_STATUS_SIZE, size_val);
> +
> +	/* MIPI I3C HCI v1.2 supports alternate RESP/IBI queue size */
> +	if (hci_version_at_least(hci, 1, 2)) {
> +		u32 alt_val = pio_reg_read(ALT_QUEUE_SIZE);
> +
> +		if (alt_val & ALT_RESP_QUEUE_EN)
> +			resp_sz = FIELD_GET(ALT_RESP_QUEUE_SIZE, alt_val);
> +		if (alt_val & EXT_IBI_QUEUE_EN)
> +			ibi_val *= 8;
> +	}
> +
> +	dev_dbg(&hci->master.dev, "CMD FIFO = %u, RESP FIFO = %u entries\n",
> +		cmd_sz, resp_sz);
> +	dev_dbg(&hci->master.dev, "IBI FIFO = %u bytes\n",
> +		4 * ibi_val);
>  	dev_dbg(&hci->master.dev, "RX data FIFO = %d bytes\n",
>  		4 * (2 << FIELD_GET(RX_DATA_BUFFER_SIZE, size_val)));
>  	dev_dbg(&hci->master.dev, "TX data FIFO = %d bytes\n",
> @@ -244,6 +288,9 @@ static void hci_pio_cleanup(struct i3c_hci *hci)
>  		BUG_ON(pio->curr_rx);
>  		BUG_ON(pio->curr_tx);
>  		BUG_ON(pio->curr_resp);
> +		/* MIPI I3C HCI v1.2 requires explicitly stopping and disabling PIO queues */
> +		if (hci_version_at_least(hci, 1, 2))
> +			pio_reg_write(CONTROL, 0x0);
>  	}
>  }
>
> @@ -764,6 +811,18 @@ static void hci_pio_err(struct i3c_hci *hci, struct hci_pio_data *pio,
>  		hci_pio_dequeue_xfer_common(hci, pio, pio->curr_tx, 1);
>  	/* then reset the hardware */
>  	mipi_i3c_hci_pio_reset(hci);
> +
> +	/* MIPI I3C HCI v1.2 requires explicitly restarting PIO queues after error/abort */
> +	if (hci_version_at_least(hci, 1, 2)) {
> +		u32 ctl_val = pio_reg_read(CONTROL);
> +
> +		if (!(ctl_val & PIO_CONTROL_ENABLE)) {
> +			ctl_val |= PIO_CONTROL_ENABLE;
> +			pio_reg_write(CONTROL, ctl_val);
> +		}
> +		pio_reg_write(CONTROL, ctl_val | PIO_CONTROL_RS);
> +	}
> +
>  	mipi_i3c_hci_resume(hci);
>
>  	dev_dbg(&hci->master.dev, "status=%#x/%#x",
> --
> 2.43.0
>
> ==================================================================================================================
> This email and any attachments to it contain confidential information and are intended solely for the use of the individual to whom it
> is addressed.If you are not the intended recipient or receive it accidentally, please immediately notify the sender by e-mail and delete
> the message and any attachments from your computer system, and destroy all hard copies. If any, please be advised that any unauthorized
> disclosure, copying, distribution or any action taken or omitted in reliance on this, is illegal and prohibited. Furthermore, any views
> or opinions expressed are solely those of the author and do not represent those of ASMedia Technology Inc. Thank you for your cooperation.
> ==================================================================================================================
> --
> linux-i3c mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-i3c

-- 
linux-i3c mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-i3c
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.