public inbox for linux-i3c@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver
@ 2024-10-17 15:03 Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 1/6] i3c: dw: Add support for AMDI0015 ACPI ID Shyam Sundar S K
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

The AMD EPYC platform design has DIMMs connected over the I3C bus, with
each DIMM containing three components: SPD, PMIC, and RCD.

To access component-specific information within the DIMMs, such as initial
dynamic address, static address, and provisional ID, ACPI support is
necessary for the I3C core. This requires adding ACPI binding to the
dw-i3c-master driver and retrieving slave information from the AMD ASL.

Currently, the code is closely tied to dt-bindings. This initial set aims
to decouple some of these bindings by adding the AMD-specific _HID,
enabling the current driver to support ACPI-enabled x86 systems.

In this series, support for following features has been added.
- X86/ACPI support to i3c core
- Support for SETAASA CCC command
- Add routines to plugin a SPD device to the i3c bus
- Workaround for AMD hardware
- Add dw-i3c-master driver with ACPI bindings

Shyam Sundar S K (6):
  i3c: dw: Add support for AMDI0015 ACPI ID
  i3c: dw: Use IRQF_SHARED flag for dw-i3c-master
  i3c: master: Add ACPI support to i3c subsystem
  i3c: master: Add a routine to include the I3C SPD device
  i3c: master: Add support for SETAASA CCC
  i3c: dw: Add quirk to address OD/PP timing issue on AMD platform

 drivers/i3c/internals.h            |   2 +
 drivers/i3c/master.c               | 151 +++++++++++++++++++++++++++++
 drivers/i3c/master/dw-i3c-master.c |  42 +++++++-
 drivers/i3c/master/dw-i3c-master.h |   1 +
 include/linux/i3c/ccc.h            |   1 +
 include/linux/i3c/master.h         |   2 +
 6 files changed, 198 insertions(+), 1 deletion(-)

-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/6] i3c: dw: Add support for AMDI0015 ACPI ID
  2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
@ 2024-10-17 15:03 ` Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 2/6] i3c: dw: Use IRQF_SHARED flag for dw-i3c-master Shyam Sundar S K
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

Add AMDI0015 _HID for Designware I3C driver so that the dw-i3c-master
driver can be probed on AMD platforms.

Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
 drivers/i3c/master/dw-i3c-master.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 8d694672c110..1a7c300b6d45 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1748,12 +1748,19 @@ static const struct of_device_id dw_i3c_master_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
 
+static const struct acpi_device_id amd_i3c_device_match[] = {
+	{ "AMDI0015" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, amd_i3c_device_match);
+
 static struct platform_driver dw_i3c_driver = {
 	.probe = dw_i3c_probe,
 	.remove_new = dw_i3c_remove,
 	.driver = {
 		.name = "dw-i3c-master",
 		.of_match_table = dw_i3c_master_of_match,
+		.acpi_match_table = amd_i3c_device_match,
 		.pm = &dw_i3c_pm_ops,
 	},
 };
-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/6] i3c: dw: Use IRQF_SHARED flag for dw-i3c-master
  2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 1/6] i3c: dw: Add support for AMDI0015 ACPI ID Shyam Sundar S K
@ 2024-10-17 15:03 ` Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem Shyam Sundar S K
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

On AMD platforms, the IRQ lines are shared between two instances of I3C.
Add IRQF_SHARED flag during the interrupt registration process.

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
 drivers/i3c/master/dw-i3c-master.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 1a7c300b6d45..fd58a95ae1c3 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1578,7 +1578,7 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
 	writel(INTR_ALL, master->regs + INTR_STATUS);
 	irq = platform_get_irq(pdev, 0);
 	ret = devm_request_irq(&pdev->dev, irq,
-			       dw_i3c_master_irq_handler, 0,
+			       dw_i3c_master_irq_handler, IRQF_SHARED,
 			       dev_name(&pdev->dev), master);
 	if (ret)
 		goto err_assert_rst;
-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem
  2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 1/6] i3c: dw: Add support for AMDI0015 ACPI ID Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 2/6] i3c: dw: Use IRQF_SHARED flag for dw-i3c-master Shyam Sundar S K
@ 2024-10-17 15:03 ` Shyam Sundar S K
  2024-10-20  7:46   ` kernel test robot
  2024-10-20  8:17   ` kernel test robot
  2024-10-17 15:03 ` [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device Shyam Sundar S K
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

As of now, the I3C subsystem only has ARM-specific initialization, and
there is no corresponding ACPI plumbing present. To address this, ACPI
support needs to be added to both the I3C core and DW driver.

Add support to get the ACPI handle from the _HID probed and parse the apci
object to retrieve the slave information from BIOS.

Based on the acpi object information propogated via BIOS, build the i3c
board information so that the same information can be used across the
driver to handle the slave requests.

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
 drivers/i3c/internals.h            |  2 +
 drivers/i3c/master.c               | 80 ++++++++++++++++++++++++++++++
 drivers/i3c/master/dw-i3c-master.c |  5 ++
 include/linux/i3c/master.h         |  1 +
 4 files changed, 88 insertions(+)

diff --git a/drivers/i3c/internals.h b/drivers/i3c/internals.h
index 433f6088b7ce..d2d6c69b19dd 100644
--- a/drivers/i3c/internals.h
+++ b/drivers/i3c/internals.h
@@ -10,6 +10,8 @@
 
 #include <linux/i3c/master.h>
 
+#define AMD_I3C_GET_SLAVE_ADDR		0x30
+
 void i3c_bus_normaluse_lock(struct i3c_bus *bus);
 void i3c_bus_normaluse_unlock(struct i3c_bus *bus);
 
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 6f3eb710a75d..20b83ca52d31 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -2251,6 +2251,80 @@ static int of_i3c_master_add_dev(struct i3c_master_controller *master,
 	return ret;
 }
 
+static int i3c_acpi_configure_master(struct i3c_master_controller *master)
+{
+	struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
+	enum i3c_addr_slot_status addrstatus;
+	struct i3c_dev_boardinfo *boardinfo;
+	struct device *dev = &master->dev;
+	struct fwnode_handle *fwnode;
+	struct acpi_device *adev;
+	u32 slv_addr, num_dev;
+	acpi_status status;
+	u64 val;
+
+	status = acpi_evaluate_object_typed(master->ahandle, "_DSD", NULL, &buf, ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status)) {
+		dev_err(&master->dev, "Error reading _DSD:%s\n", acpi_format_exception(status));
+		return -ENODEV;
+	}
+
+	num_dev = device_get_child_node_count(dev);
+	if (!num_dev) {
+		dev_err(&master->dev, "Error: no child node present\n");
+		return -EINVAL;
+	}
+
+	device_for_each_child_node(dev, fwnode) {
+		adev = to_acpi_device_node(fwnode);
+		if (!adev)
+			return -ENODEV;
+
+		status = acpi_evaluate_integer(adev->handle, "_ADR", NULL, &val);
+		if (ACPI_FAILURE(status)) {
+			dev_err(&master->dev, "Error: eval _ADR failed\n");
+			return -EINVAL;
+		}
+		slv_addr = val >> AMD_I3C_GET_SLAVE_ADDR;
+
+		boardinfo = devm_kzalloc(dev, sizeof(*boardinfo), GFP_KERNEL);
+		if (!boardinfo)
+			return -ENOMEM;
+
+		if (slv_addr) {
+			if (slv_addr > I3C_MAX_ADDR)
+				return -EINVAL;
+
+			addrstatus = i3c_bus_get_addr_slot_status(&master->bus, slv_addr);
+			if (addrstatus != I3C_ADDR_SLOT_FREE)
+				return -EINVAL;
+		}
+
+		boardinfo->static_addr = slv_addr;
+		if (boardinfo->static_addr > I3C_MAX_ADDR)
+			return -EINVAL;
+
+		addrstatus = i3c_bus_get_addr_slot_status(&master->bus,	boardinfo->static_addr);
+		if (addrstatus != I3C_ADDR_SLOT_FREE)
+			return -EINVAL;
+
+		boardinfo->pid = (val & GENMASK(47, 0));
+		if ((boardinfo->pid & GENMASK_ULL(63, 48)) ||
+		    I3C_PID_RND_LOWER_32BITS(boardinfo->pid))
+			return -EINVAL;
+
+		/*
+		 * According to the specification, SETDASA is not supported for DIMM slaves
+		 * during device discovery. Therefore, AMD BIOS will populate same initial
+		 * dynamic address as the static address.
+		 */
+		boardinfo->init_dyn_addr = boardinfo->static_addr;
+		list_add_tail(&boardinfo->node, &master->boardinfo.i3c);
+	}
+
+	return 0;
+}
+
 static int of_populate_i3c_bus(struct i3c_master_controller *master)
 {
 	struct device *dev = &master->dev;
@@ -2771,6 +2845,12 @@ int i3c_master_register(struct i3c_master_controller *master,
 	master->dev.coherent_dma_mask = parent->coherent_dma_mask;
 	master->dev.dma_parms = parent->dma_parms;
 
+	if (has_acpi_companion(master->dev.parent)) {
+		ret = i3c_acpi_configure_master(master);
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = of_populate_i3c_bus(master);
 	if (ret)
 		goto err_put_dev;
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index fd58a95ae1c3..8d4583bc2113 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -1602,6 +1602,11 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
 	master->maxdevs = ret >> 16;
 	master->free_pos = GENMASK(master->maxdevs - 1, 0);
 
+	ACPI_COMPANION_SET(&master->base.dev, ACPI_COMPANION(&pdev->dev));
+	master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
+	if (!master->base.ahandle)
+		dev_err(&pdev->dev, "Failed to get acpi device handle\n");
+
 	INIT_WORK(&master->hj_work, dw_i3c_hj_work);
 	ret = i3c_master_register(&master->base, &pdev->dev,
 				  &dw_mipi_i3c_ops, false);
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index 2a1ed05d5782..367faf7c4bf3 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -523,6 +523,7 @@ struct i3c_master_controller {
 	} boardinfo;
 	struct i3c_bus bus;
 	struct workqueue_struct *wq;
+	acpi_handle ahandle;
 };
 
 /**
-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device
  2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
                   ` (2 preceding siblings ...)
  2024-10-17 15:03 ` [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem Shyam Sundar S K
@ 2024-10-17 15:03 ` Shyam Sundar S K
  2024-10-20 11:25   ` kernel test robot
  2024-10-17 15:03 ` [PATCH 5/6] i3c: master: Add support for SETAASA CCC Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 6/6] i3c: dw: Add quirk to address OD/PP timing issue on AMD platform Shyam Sundar S K
  5 siblings, 1 reply; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

Implement the i3c_master_add_spd_dev() function in the I3C master to
handle SPD (Serial Presence Detect) device creation and map the board
information into the I3C device structure.

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
 drivers/i3c/master.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 20b83ca52d31..4f149519170e 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1657,6 +1657,45 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
 	}
 }
 
+static int i3c_master_add_spd_dev(struct i3c_master_controller *master,
+				  struct i3c_dev_boardinfo *boardinfo)
+{
+	struct i3c_dev_desc *i3cdev;
+	int ret;
+
+	list_for_each_entry(boardinfo, &master->boardinfo.i3c, node) {
+		struct i3c_device_info info = {
+			.static_addr = boardinfo->static_addr,
+		};
+
+		ret = i3c_bus_get_addr_slot_status(&master->bus, boardinfo->static_addr);
+		if (ret != I3C_ADDR_SLOT_FREE)
+			return -EBUSY;
+
+		i3cdev = i3c_master_alloc_i3c_dev(master, &info);
+		if (IS_ERR(i3cdev))
+			return -ENOMEM;
+
+		i3cdev->boardinfo = boardinfo;
+		ret = i3c_master_attach_i3c_dev(master, i3cdev);
+		if (ret)
+			goto err_free_dev;
+
+		i3cdev->info.pid = i3cdev->boardinfo->pid;
+		i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
+
+		i3c_bus_normaluse_lock(&master->bus);
+		i3c_master_register_new_i3c_devs(master);
+		i3c_bus_normaluse_unlock(&master->bus);
+	}
+
+	return 0;
+
+err_free_dev:
+	i3c_master_free_i3c_dev(i3cdev);
+	return ret;
+}
+
 /**
  * i3c_master_do_daa() - do a DAA (Dynamic Address Assignment)
  * @master: master doing the DAA
@@ -1868,6 +1907,8 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
 		goto err_bus_cleanup;
 	}
 
+	i3c_master_add_spd_dev(master, i3cboardinfo);
+
 	if (master->ops->set_speed) {
 		ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
 		if (ret)
-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/6] i3c: master: Add support for SETAASA CCC
  2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
                   ` (3 preceding siblings ...)
  2024-10-17 15:03 ` [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device Shyam Sundar S K
@ 2024-10-17 15:03 ` Shyam Sundar S K
  2024-10-17 15:03 ` [PATCH 6/6] i3c: dw: Add quirk to address OD/PP timing issue on AMD platform Shyam Sundar S K
  5 siblings, 0 replies; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

I3C devices like DIMMs over SPD use SETAASA for bus discovery instead of
SETDASA. Add a new routine for I3C host controller drivers to use. If the
I3C slave on the bus is an SPD device, skip the regular DAA process.

According to the SPD spec[1], use SETAASA for bus discovery, and avoid
sending RSTDAA and DISEC, as they are considered illegal. Skip this entire
process if the slave is SPD-compliant, as indicated by the "jdec_spd" flag
from the BIOS.

[1] https://www.jedec.org/system/files/docs/JESD300-5B.01.pdf
(section 2.4 and 2.6.3)

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
 drivers/i3c/master.c               | 32 +++++++++++++++++++++++++++++-
 drivers/i3c/master/dw-i3c-master.c |  1 +
 include/linux/i3c/ccc.h            |  1 +
 include/linux/i3c/master.h         |  1 +
 4 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 4f149519170e..0fe3e315d6cb 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -1657,6 +1657,21 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master)
 	}
 }
 
+static int i3c_master_setaasa_locked(struct i3c_master_controller *master)
+{
+	struct i3c_ccc_cmd_dest dest;
+	struct i3c_ccc_cmd cmd;
+	int ret;
+
+	i3c_ccc_cmd_dest_init(&dest, I3C_BROADCAST_ADDR, 0);
+	i3c_ccc_cmd_init(&cmd, false, I3C_CCC_SETAASA, &dest, 1);
+
+	ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
+	i3c_ccc_cmd_dest_cleanup(&dest);
+
+	return ret;
+}
+
 static int i3c_master_add_spd_dev(struct i3c_master_controller *master,
 				  struct i3c_dev_boardinfo *boardinfo)
 {
@@ -1684,6 +1699,10 @@ static int i3c_master_add_spd_dev(struct i3c_master_controller *master,
 		i3cdev->info.pid = i3cdev->boardinfo->pid;
 		i3cdev->info.dyn_addr = i3cdev->boardinfo->init_dyn_addr;
 
+		ret = i3c_master_setaasa_locked(master);
+		if (ret)
+			goto err_free_dev;
+
 		i3c_bus_normaluse_lock(&master->bus);
 		i3c_master_register_new_i3c_devs(master);
 		i3c_bus_normaluse_unlock(&master->bus);
@@ -1907,7 +1926,14 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)
 		goto err_bus_cleanup;
 	}
 
-	i3c_master_add_spd_dev(master, i3cboardinfo);
+	/*
+	 * If the I3C slave on the bus is SPD device, then do not follow the regular
+	 * DAA process. Also, as per SPD spec SETAASA is required for the bus discovery
+	 * and sending RSTDAA and DISEC is considered as illegal. So skip the entire process
+	 * if the jdec_spd flag has been identified from the BIOS.
+	 */
+	if (master->jdec_spd)
+		return i3c_master_add_spd_dev(master, i3cboardinfo);
 
 	if (master->ops->set_speed) {
 		ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
@@ -2310,6 +2336,10 @@ static int i3c_acpi_configure_master(struct i3c_master_controller *master)
 		return -ENODEV;
 	}
 
+	status = acpi_evaluate_object(master->ahandle, "_STR", NULL, NULL);
+	if (ACPI_SUCCESS(status))
+		master->jdec_spd = true;
+
 	num_dev = device_get_child_node_count(dev);
 	if (!num_dev) {
 		dev_err(&master->dev, "Error: no child node present\n");
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 8d4583bc2113..8f452976dd7c 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -282,6 +282,7 @@ static bool dw_i3c_master_supports_ccc_cmd(struct i3c_master_controller *m,
 	case I3C_CCC_GETSTATUS:
 	case I3C_CCC_GETMXDS:
 	case I3C_CCC_GETHDRCAP:
+	case I3C_CCC_SETAASA:
 		return true;
 	default:
 		return false;
diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h
index ad59a4ae60d1..a145d766ab6f 100644
--- a/include/linux/i3c/ccc.h
+++ b/include/linux/i3c/ccc.h
@@ -32,6 +32,7 @@
 #define I3C_CCC_DEFSLVS			I3C_CCC_ID(0x8, true)
 #define I3C_CCC_ENTTM			I3C_CCC_ID(0xb, true)
 #define I3C_CCC_ENTHDR(x)		I3C_CCC_ID(0x20 + (x), true)
+#define I3C_CCC_SETAASA			I3C_CCC_ID(0x29, true)
 
 /* Unicast-only commands */
 #define I3C_CCC_SETDASA			I3C_CCC_ID(0x7, false)
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index 367faf7c4bf3..cd8390d8b469 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -516,6 +516,7 @@ struct i3c_master_controller {
 	const struct i3c_master_controller_ops *ops;
 	unsigned int secondary : 1;
 	unsigned int init_done : 1;
+	unsigned int jdec_spd : 1;
 	unsigned int hotjoin: 1;
 	struct {
 		struct list_head i3c;
-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/6] i3c: dw: Add quirk to address OD/PP timing issue on AMD platform
  2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
                   ` (4 preceding siblings ...)
  2024-10-17 15:03 ` [PATCH 5/6] i3c: master: Add support for SETAASA CCC Shyam Sundar S K
@ 2024-10-17 15:03 ` Shyam Sundar S K
  5 siblings, 0 replies; 10+ messages in thread
From: Shyam Sundar S K @ 2024-10-17 15:03 UTC (permalink / raw)
  To: Alexandre Belloni, Jarkko Nikula
  Cc: Sanket.Goswami, linux-i3c, linux-kernel, Shyam Sundar S K

The AMD Legacy I3C is having a problem with its IP, specifically with the
push-pull and open-drain pull-up registers. These registers need to be
manually programmed for every CCC submission to align with the duty cycle.
Therefore, add a quirk to address this issue.

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
---
 drivers/i3c/master/dw-i3c-master.c | 29 ++++++++++++++++++++++++++++-
 drivers/i3c/master/dw-i3c-master.h |  1 +
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index 8f452976dd7c..8500b0d0dcf3 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -220,6 +220,14 @@
 
 #define XFER_TIMEOUT (msecs_to_jiffies(1000))
 #define RPM_AUTOSUSPEND_TIMEOUT 1000 /* ms */
+
+/* Timing values to configure 12.5MHz frequency */
+#define AMD_I3C_OD_TIMING          0x4C007C
+#define AMD_I3C_PP_TIMING          0x8001A
+
+/* List of quirks */
+#define AMD_I3C_OD_PP_TIMING		BIT(1)
+
 struct dw_i3c_cmd {
 	u32 cmd_lo;
 	u32 cmd_hi;
@@ -795,6 +803,12 @@ static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc)
 	return ret;
 }
 
+static void amd_configure_od_pp_quirk(struct dw_i3c_master *master)
+{
+	master->i3c_od_timing = AMD_I3C_OD_TIMING;
+	master->i3c_pp_timing = AMD_I3C_PP_TIMING;
+}
+
 static int dw_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
 				      struct i3c_ccc_cmd *ccc)
 {
@@ -804,6 +818,13 @@ static int dw_i3c_master_send_ccc_cmd(struct i3c_master_controller *m,
 	if (ccc->id == I3C_CCC_ENTDAA)
 		return -EINVAL;
 
+	/* AMD platform specific OD and PP timings */
+	if (master->quirks & AMD_I3C_OD_PP_TIMING) {
+		amd_configure_od_pp_quirk(master);
+		writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING);
+		writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING);
+	}
+
 	ret = pm_runtime_resume_and_get(master->dev);
 	if (ret < 0) {
 		dev_err(master->dev,
@@ -1608,6 +1629,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
 	if (!master->base.ahandle)
 		dev_err(&pdev->dev, "Failed to get acpi device handle\n");
 
+	master->quirks = (unsigned long)device_get_match_data(&pdev->dev);
+
 	INIT_WORK(&master->hj_work, dw_i3c_hj_work);
 	ret = i3c_master_register(&master->base, &pdev->dev,
 				  &dw_mipi_i3c_ops, false);
@@ -1681,6 +1704,10 @@ static void dw_i3c_master_restore_addrs(struct dw_i3c_master *master)
 
 static void dw_i3c_master_restore_timing_regs(struct dw_i3c_master *master)
 {
+	/* AMD platform specific OD and PP timings */
+	if (master->quirks & AMD_I3C_OD_PP_TIMING)
+		amd_configure_od_pp_quirk(master);
+
 	writel(master->i3c_pp_timing, master->regs + SCL_I3C_PP_TIMING);
 	writel(master->bus_free_timing, master->regs + BUS_FREE_TIMING);
 	writel(master->i3c_od_timing, master->regs + SCL_I3C_OD_TIMING);
@@ -1755,7 +1782,7 @@ static const struct of_device_id dw_i3c_master_of_match[] = {
 MODULE_DEVICE_TABLE(of, dw_i3c_master_of_match);
 
 static const struct acpi_device_id amd_i3c_device_match[] = {
-	{ "AMDI0015" },
+	{ "AMDI0015", AMD_I3C_OD_PP_TIMING },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, amd_i3c_device_match);
diff --git a/drivers/i3c/master/dw-i3c-master.h b/drivers/i3c/master/dw-i3c-master.h
index 219ff815d3a7..c5cb695c16ab 100644
--- a/drivers/i3c/master/dw-i3c-master.h
+++ b/drivers/i3c/master/dw-i3c-master.h
@@ -50,6 +50,7 @@ struct dw_i3c_master {
 	u32 bus_free_timing;
 	u32 i2c_fm_timing;
 	u32 i2c_fmp_timing;
+	u32 quirks;
 	/*
 	 * Per-device hardware data, used to manage the device address table
 	 * (DAT)
-- 
2.34.1


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem
  2024-10-17 15:03 ` [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem Shyam Sundar S K
@ 2024-10-20  7:46   ` kernel test robot
  2024-10-20  8:17   ` kernel test robot
  1 sibling, 0 replies; 10+ messages in thread
From: kernel test robot @ 2024-10-20  7:46 UTC (permalink / raw)
  To: Shyam Sundar S K, Alexandre Belloni, Jarkko Nikula
  Cc: oe-kbuild-all, Sanket.Goswami, linux-i3c, linux-kernel,
	Shyam Sundar S K

Hi Shyam,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.12-rc3 next-20241018]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shyam-Sundar-S-K/i3c-dw-Add-support-for-AMDI0015-ACPI-ID/20241017-230810
base:   linus/master
patch link:    https://lore.kernel.org/r/20241017150330.3035568-4-Shyam-sundar.S-k%40amd.com
patch subject: [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem
config: arc-randconfig-001-20241020 (https://download.01.org/0day-ci/archive/20241020/202410201515.SaOuSc9G-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241020/202410201515.SaOuSc9G-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410201515.SaOuSc9G-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/i3c/master/dw-i3c-master.c: In function 'dw_i3c_common_probe':
>> drivers/i3c/master/dw-i3c-master.c:1606:32: error: implicit declaration of function 'acpi_device_handle'; did you mean 'acpi_fwnode_handle'? [-Werror=implicit-function-declaration]
    1606 |         master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
         |                                ^~~~~~~~~~~~~~~~~~
         |                                acpi_fwnode_handle
>> drivers/i3c/master/dw-i3c-master.c:1606:30: warning: assignment to 'acpi_handle' {aka 'void *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1606 |         master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
         |                              ^
   cc1: some warnings being treated as errors


vim +1606 drivers/i3c/master/dw-i3c-master.c

  1545	
  1546	int dw_i3c_common_probe(struct dw_i3c_master *master,
  1547				struct platform_device *pdev)
  1548	{
  1549		int ret, irq;
  1550	
  1551		if (!master->platform_ops)
  1552			master->platform_ops = &dw_i3c_platform_ops_default;
  1553	
  1554		master->dev = &pdev->dev;
  1555	
  1556		master->regs = devm_platform_ioremap_resource(pdev, 0);
  1557		if (IS_ERR(master->regs))
  1558			return PTR_ERR(master->regs);
  1559	
  1560		master->core_clk = devm_clk_get_enabled(&pdev->dev, NULL);
  1561		if (IS_ERR(master->core_clk))
  1562			return PTR_ERR(master->core_clk);
  1563	
  1564		master->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
  1565		if (IS_ERR(master->pclk))
  1566			return PTR_ERR(master->pclk);
  1567	
  1568		master->core_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
  1569									    "core_rst");
  1570		if (IS_ERR(master->core_rst))
  1571			return PTR_ERR(master->core_rst);
  1572	
  1573		reset_control_deassert(master->core_rst);
  1574	
  1575		spin_lock_init(&master->xferqueue.lock);
  1576		INIT_LIST_HEAD(&master->xferqueue.list);
  1577	
  1578		writel(INTR_ALL, master->regs + INTR_STATUS);
  1579		irq = platform_get_irq(pdev, 0);
  1580		ret = devm_request_irq(&pdev->dev, irq,
  1581				       dw_i3c_master_irq_handler, IRQF_SHARED,
  1582				       dev_name(&pdev->dev), master);
  1583		if (ret)
  1584			goto err_assert_rst;
  1585	
  1586		platform_set_drvdata(pdev, master);
  1587	
  1588		pm_runtime_set_autosuspend_delay(&pdev->dev, RPM_AUTOSUSPEND_TIMEOUT);
  1589		pm_runtime_use_autosuspend(&pdev->dev);
  1590		pm_runtime_set_active(&pdev->dev);
  1591		pm_runtime_enable(&pdev->dev);
  1592	
  1593		/* Information regarding the FIFOs/QUEUEs depth */
  1594		ret = readl(master->regs + QUEUE_STATUS_LEVEL);
  1595		master->caps.cmdfifodepth = QUEUE_STATUS_LEVEL_CMD(ret);
  1596	
  1597		ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL);
  1598		master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret);
  1599	
  1600		ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
  1601		master->datstartaddr = ret;
  1602		master->maxdevs = ret >> 16;
  1603		master->free_pos = GENMASK(master->maxdevs - 1, 0);
  1604	
  1605		ACPI_COMPANION_SET(&master->base.dev, ACPI_COMPANION(&pdev->dev));
> 1606		master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
  1607		if (!master->base.ahandle)
  1608			dev_err(&pdev->dev, "Failed to get acpi device handle\n");
  1609	
  1610		INIT_WORK(&master->hj_work, dw_i3c_hj_work);
  1611		ret = i3c_master_register(&master->base, &pdev->dev,
  1612					  &dw_mipi_i3c_ops, false);
  1613		if (ret)
  1614			goto err_disable_pm;
  1615	
  1616		return 0;
  1617	
  1618	err_disable_pm:
  1619		pm_runtime_disable(&pdev->dev);
  1620		pm_runtime_set_suspended(&pdev->dev);
  1621		pm_runtime_dont_use_autosuspend(&pdev->dev);
  1622	
  1623	err_assert_rst:
  1624		reset_control_assert(master->core_rst);
  1625	
  1626		return ret;
  1627	}
  1628	EXPORT_SYMBOL_GPL(dw_i3c_common_probe);
  1629	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem
  2024-10-17 15:03 ` [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem Shyam Sundar S K
  2024-10-20  7:46   ` kernel test robot
@ 2024-10-20  8:17   ` kernel test robot
  1 sibling, 0 replies; 10+ messages in thread
From: kernel test robot @ 2024-10-20  8:17 UTC (permalink / raw)
  To: Shyam Sundar S K, Alexandre Belloni, Jarkko Nikula
  Cc: oe-kbuild-all, Sanket.Goswami, linux-i3c, linux-kernel,
	Shyam Sundar S K

Hi Shyam,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.12-rc3 next-20241018]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shyam-Sundar-S-K/i3c-dw-Add-support-for-AMDI0015-ACPI-ID/20241017-230810
base:   linus/master
patch link:    https://lore.kernel.org/r/20241017150330.3035568-4-Shyam-sundar.S-k%40amd.com
patch subject: [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem
config: openrisc-allyesconfig (https://download.01.org/0day-ci/archive/20241020/202410201553.RtPfO9pR-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241020/202410201553.RtPfO9pR-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410201553.RtPfO9pR-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/i3c/master/dw-i3c-master.c: In function 'dw_i3c_common_probe':
   drivers/i3c/master/dw-i3c-master.c:1606:32: error: implicit declaration of function 'acpi_device_handle'; did you mean 'acpi_fwnode_handle'? [-Wimplicit-function-declaration]
    1606 |         master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
         |                                ^~~~~~~~~~~~~~~~~~
         |                                acpi_fwnode_handle
>> drivers/i3c/master/dw-i3c-master.c:1606:30: error: assignment to 'acpi_handle' {aka 'void *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
    1606 |         master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
         |                              ^

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for GET_FREE_REGION
   Depends on [n]: SPARSEMEM [=n]
   Selected by [y]:
   - RESOURCE_KUNIT_TEST [=y] && RUNTIME_TESTING_MENU [=y] && KUNIT [=y]


vim +1606 drivers/i3c/master/dw-i3c-master.c

  1545	
  1546	int dw_i3c_common_probe(struct dw_i3c_master *master,
  1547				struct platform_device *pdev)
  1548	{
  1549		int ret, irq;
  1550	
  1551		if (!master->platform_ops)
  1552			master->platform_ops = &dw_i3c_platform_ops_default;
  1553	
  1554		master->dev = &pdev->dev;
  1555	
  1556		master->regs = devm_platform_ioremap_resource(pdev, 0);
  1557		if (IS_ERR(master->regs))
  1558			return PTR_ERR(master->regs);
  1559	
  1560		master->core_clk = devm_clk_get_enabled(&pdev->dev, NULL);
  1561		if (IS_ERR(master->core_clk))
  1562			return PTR_ERR(master->core_clk);
  1563	
  1564		master->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
  1565		if (IS_ERR(master->pclk))
  1566			return PTR_ERR(master->pclk);
  1567	
  1568		master->core_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
  1569									    "core_rst");
  1570		if (IS_ERR(master->core_rst))
  1571			return PTR_ERR(master->core_rst);
  1572	
  1573		reset_control_deassert(master->core_rst);
  1574	
  1575		spin_lock_init(&master->xferqueue.lock);
  1576		INIT_LIST_HEAD(&master->xferqueue.list);
  1577	
  1578		writel(INTR_ALL, master->regs + INTR_STATUS);
  1579		irq = platform_get_irq(pdev, 0);
  1580		ret = devm_request_irq(&pdev->dev, irq,
  1581				       dw_i3c_master_irq_handler, IRQF_SHARED,
  1582				       dev_name(&pdev->dev), master);
  1583		if (ret)
  1584			goto err_assert_rst;
  1585	
  1586		platform_set_drvdata(pdev, master);
  1587	
  1588		pm_runtime_set_autosuspend_delay(&pdev->dev, RPM_AUTOSUSPEND_TIMEOUT);
  1589		pm_runtime_use_autosuspend(&pdev->dev);
  1590		pm_runtime_set_active(&pdev->dev);
  1591		pm_runtime_enable(&pdev->dev);
  1592	
  1593		/* Information regarding the FIFOs/QUEUEs depth */
  1594		ret = readl(master->regs + QUEUE_STATUS_LEVEL);
  1595		master->caps.cmdfifodepth = QUEUE_STATUS_LEVEL_CMD(ret);
  1596	
  1597		ret = readl(master->regs + DATA_BUFFER_STATUS_LEVEL);
  1598		master->caps.datafifodepth = DATA_BUFFER_STATUS_LEVEL_TX(ret);
  1599	
  1600		ret = readl(master->regs + DEVICE_ADDR_TABLE_POINTER);
  1601		master->datstartaddr = ret;
  1602		master->maxdevs = ret >> 16;
  1603		master->free_pos = GENMASK(master->maxdevs - 1, 0);
  1604	
  1605		ACPI_COMPANION_SET(&master->base.dev, ACPI_COMPANION(&pdev->dev));
> 1606		master->base.ahandle = acpi_device_handle(ACPI_COMPANION(&pdev->dev));
  1607		if (!master->base.ahandle)
  1608			dev_err(&pdev->dev, "Failed to get acpi device handle\n");
  1609	
  1610		INIT_WORK(&master->hj_work, dw_i3c_hj_work);
  1611		ret = i3c_master_register(&master->base, &pdev->dev,
  1612					  &dw_mipi_i3c_ops, false);
  1613		if (ret)
  1614			goto err_disable_pm;
  1615	
  1616		return 0;
  1617	
  1618	err_disable_pm:
  1619		pm_runtime_disable(&pdev->dev);
  1620		pm_runtime_set_suspended(&pdev->dev);
  1621		pm_runtime_dont_use_autosuspend(&pdev->dev);
  1622	
  1623	err_assert_rst:
  1624		reset_control_assert(master->core_rst);
  1625	
  1626		return ret;
  1627	}
  1628	EXPORT_SYMBOL_GPL(dw_i3c_common_probe);
  1629	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device
  2024-10-17 15:03 ` [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device Shyam Sundar S K
@ 2024-10-20 11:25   ` kernel test robot
  0 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2024-10-20 11:25 UTC (permalink / raw)
  To: Shyam Sundar S K, Alexandre Belloni, Jarkko Nikula
  Cc: oe-kbuild-all, Sanket.Goswami, linux-i3c, linux-kernel,
	Shyam Sundar S K

Hi Shyam,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.12-rc3 next-20241018]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Shyam-Sundar-S-K/i3c-dw-Add-support-for-AMDI0015-ACPI-ID/20241017-230810
base:   linus/master
patch link:    https://lore.kernel.org/r/20241017150330.3035568-5-Shyam-sundar.S-k%40amd.com
patch subject: [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device
config: arm-randconfig-r073-20241020 (https://download.01.org/0day-ci/archive/20241020/202410201938.oiMeI2Pu-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project bfe84f7085d82d06d61c632a7bad1e692fd159e4)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241020/202410201938.oiMeI2Pu-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410201938.oiMeI2Pu-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/i3c/master.c:21:
   In file included from drivers/i3c/internals.h:11:
   In file included from include/linux/i3c/master.h:14:
   In file included from include/linux/i2c.h:19:
   In file included from include/linux/regulator/consumer.h:35:
   In file included from include/linux/suspend.h:5:
   In file included from include/linux/swap.h:9:
   In file included from include/linux/memcontrol.h:21:
   In file included from include/linux/mm.h:2213:
   include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     518 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> drivers/i3c/master.c:1910:33: warning: variable 'i3cboardinfo' is uninitialized when used here [-Wuninitialized]
    1910 |         i3c_master_add_spd_dev(master, i3cboardinfo);
         |                                        ^~~~~~~~~~~~
   drivers/i3c/master.c:1856:40: note: initialize the variable 'i3cboardinfo' to silence this warning
    1856 |         struct i3c_dev_boardinfo *i3cboardinfo;
         |                                               ^
         |                                                = NULL
   drivers/i3c/master.c:2324:12: error: call to undeclared function 'acpi_evaluate_integer'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
    2324 |                 status = acpi_evaluate_integer(adev->handle, "_ADR", NULL, &val);
         |                          ^
   drivers/i3c/master.c:2324:12: note: did you mean 'acpi_evaluate_object'?
   include/acpi/acpixf.h:550:8: note: 'acpi_evaluate_object' declared here
     550 |                             acpi_evaluate_object(acpi_handle object,
         |                             ^
   include/acpi/platform/aclinux.h:93:21: note: expanded from macro 'ACPI_EXTERNAL_RETURN_STATUS'
      93 |         static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);}
         |                            ^
   drivers/i3c/master.c:2324:38: error: incomplete definition of type 'struct acpi_device'
    2324 |                 status = acpi_evaluate_integer(adev->handle, "_ADR", NULL, &val);
         |                                                ~~~~^
   include/linux/acpi.h:801:8: note: forward declaration of 'struct acpi_device'
     801 | struct acpi_device;
         |        ^
   drivers/i3c/master.c:2352:27: warning: shift count is negative [-Wshift-count-negative]
    2352 |                 boardinfo->pid = (val & GENMASK(47, 0));
         |                                         ^~~~~~~~~~~~~~
   include/linux/bits.h:35:31: note: expanded from macro 'GENMASK'
      35 |         (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
         |                                      ^~~~~~~~~~~~~~~
   include/uapi/linux/bits.h:9:19: note: expanded from macro '__GENMASK'
       9 |          (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
         |                   ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   3 warnings and 2 errors generated.


vim +/i3cboardinfo +1910 drivers/i3c/master.c

  1819	
  1820	/**
  1821	 * i3c_master_bus_init() - initialize an I3C bus
  1822	 * @master: main master initializing the bus
  1823	 *
  1824	 * This function is following all initialisation steps described in the I3C
  1825	 * specification:
  1826	 *
  1827	 * 1. Attach I2C devs to the master so that the master can fill its internal
  1828	 *    device table appropriately
  1829	 *
  1830	 * 2. Call &i3c_master_controller_ops->bus_init() method to initialize
  1831	 *    the master controller. That's usually where the bus mode is selected
  1832	 *    (pure bus or mixed fast/slow bus)
  1833	 *
  1834	 * 3. Instruct all devices on the bus to drop their dynamic address. This is
  1835	 *    particularly important when the bus was previously configured by someone
  1836	 *    else (for example the bootloader)
  1837	 *
  1838	 * 4. Disable all slave events.
  1839	 *
  1840	 * 5. Reserve address slots for I3C devices with init_dyn_addr. And if devices
  1841	 *    also have static_addr, try to pre-assign dynamic addresses requested by
  1842	 *    the FW with SETDASA and attach corresponding statically defined I3C
  1843	 *    devices to the master.
  1844	 *
  1845	 * 6. Do a DAA (Dynamic Address Assignment) to assign dynamic addresses to all
  1846	 *    remaining I3C devices
  1847	 *
  1848	 * Once this is done, all I3C and I2C devices should be usable.
  1849	 *
  1850	 * Return: a 0 in case of success, an negative error code otherwise.
  1851	 */
  1852	static int i3c_master_bus_init(struct i3c_master_controller *master)
  1853	{
  1854		enum i3c_addr_slot_status status;
  1855		struct i2c_dev_boardinfo *i2cboardinfo;
  1856		struct i3c_dev_boardinfo *i3cboardinfo;
  1857		struct i2c_dev_desc *i2cdev;
  1858		int ret;
  1859	
  1860		/*
  1861		 * First attach all devices with static definitions provided by the
  1862		 * FW.
  1863		 */
  1864		list_for_each_entry(i2cboardinfo, &master->boardinfo.i2c, node) {
  1865			status = i3c_bus_get_addr_slot_status(&master->bus,
  1866							      i2cboardinfo->base.addr);
  1867			if (status != I3C_ADDR_SLOT_FREE) {
  1868				ret = -EBUSY;
  1869				goto err_detach_devs;
  1870			}
  1871	
  1872			i3c_bus_set_addr_slot_status(&master->bus,
  1873						     i2cboardinfo->base.addr,
  1874						     I3C_ADDR_SLOT_I2C_DEV);
  1875	
  1876			i2cdev = i3c_master_alloc_i2c_dev(master,
  1877							  i2cboardinfo->base.addr,
  1878							  i2cboardinfo->lvr);
  1879			if (IS_ERR(i2cdev)) {
  1880				ret = PTR_ERR(i2cdev);
  1881				goto err_detach_devs;
  1882			}
  1883	
  1884			ret = i3c_master_attach_i2c_dev(master, i2cdev);
  1885			if (ret) {
  1886				i3c_master_free_i2c_dev(i2cdev);
  1887				goto err_detach_devs;
  1888			}
  1889		}
  1890	
  1891		/*
  1892		 * Now execute the controller specific ->bus_init() routine, which
  1893		 * might configure its internal logic to match the bus limitations.
  1894		 */
  1895		ret = master->ops->bus_init(master);
  1896		if (ret)
  1897			goto err_detach_devs;
  1898	
  1899		/*
  1900		 * The master device should have been instantiated in ->bus_init(),
  1901		 * complain if this was not the case.
  1902		 */
  1903		if (!master->this) {
  1904			dev_err(&master->dev,
  1905				"master_set_info() was not called in ->bus_init()\n");
  1906			ret = -EINVAL;
  1907			goto err_bus_cleanup;
  1908		}
  1909	
> 1910		i3c_master_add_spd_dev(master, i3cboardinfo);
  1911	
  1912		if (master->ops->set_speed) {
  1913			ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
  1914			if (ret)
  1915				goto err_bus_cleanup;
  1916		}
  1917	
  1918		/*
  1919		 * Reset all dynamic address that may have been assigned before
  1920		 * (assigned by the bootloader for example).
  1921		 */
  1922		ret = i3c_master_rstdaa_locked(master, I3C_BROADCAST_ADDR);
  1923		if (ret && ret != I3C_ERROR_M2)
  1924			goto err_bus_cleanup;
  1925	
  1926		if (master->ops->set_speed) {
  1927			master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED);
  1928			if (ret)
  1929				goto err_bus_cleanup;
  1930		}
  1931	
  1932		/* Disable all slave events before starting DAA. */
  1933		ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
  1934					      I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
  1935					      I3C_CCC_EVENT_HJ);
  1936		if (ret && ret != I3C_ERROR_M2)
  1937			goto err_bus_cleanup;
  1938	
  1939		/*
  1940		 * Reserve init_dyn_addr first, and then try to pre-assign dynamic
  1941		 * address and retrieve device information if needed.
  1942		 * In case pre-assign dynamic address fails, setting dynamic address to
  1943		 * the requested init_dyn_addr is retried after DAA is done in
  1944		 * i3c_master_add_i3c_dev_locked().
  1945		 */
  1946		list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) {
  1947	
  1948			/*
  1949			 * We don't reserve a dynamic address for devices that
  1950			 * don't explicitly request one.
  1951			 */
  1952			if (!i3cboardinfo->init_dyn_addr)
  1953				continue;
  1954	
  1955			ret = i3c_bus_get_addr_slot_status(&master->bus,
  1956							   i3cboardinfo->init_dyn_addr);
  1957			if (ret != I3C_ADDR_SLOT_FREE) {
  1958				ret = -EBUSY;
  1959				goto err_rstdaa;
  1960			}
  1961	
  1962			i3c_bus_set_addr_slot_status(&master->bus,
  1963						     i3cboardinfo->init_dyn_addr,
  1964						     I3C_ADDR_SLOT_I3C_DEV);
  1965	
  1966			/*
  1967			 * Only try to create/attach devices that have a static
  1968			 * address. Other devices will be created/attached when
  1969			 * DAA happens, and the requested dynamic address will
  1970			 * be set using SETNEWDA once those devices become
  1971			 * addressable.
  1972			 */
  1973	
  1974			if (i3cboardinfo->static_addr)
  1975				i3c_master_early_i3c_dev_add(master, i3cboardinfo);
  1976		}
  1977	
  1978		ret = i3c_master_do_daa(master);
  1979		if (ret)
  1980			goto err_rstdaa;
  1981	
  1982		return 0;
  1983	
  1984	err_rstdaa:
  1985		i3c_master_rstdaa_locked(master, I3C_BROADCAST_ADDR);
  1986	
  1987	err_bus_cleanup:
  1988		if (master->ops->bus_cleanup)
  1989			master->ops->bus_cleanup(master);
  1990	
  1991	err_detach_devs:
  1992		i3c_master_detach_free_devs(master);
  1993	
  1994		return ret;
  1995	}
  1996	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-10-20 11:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-17 15:03 [PATCH 0/6] Introduce initial support for the AMD I3C (non-HCI) to DW driver Shyam Sundar S K
2024-10-17 15:03 ` [PATCH 1/6] i3c: dw: Add support for AMDI0015 ACPI ID Shyam Sundar S K
2024-10-17 15:03 ` [PATCH 2/6] i3c: dw: Use IRQF_SHARED flag for dw-i3c-master Shyam Sundar S K
2024-10-17 15:03 ` [PATCH 3/6] i3c: master: Add ACPI support to i3c subsystem Shyam Sundar S K
2024-10-20  7:46   ` kernel test robot
2024-10-20  8:17   ` kernel test robot
2024-10-17 15:03 ` [PATCH 4/6] i3c: master: Add a routine to include the I3C SPD device Shyam Sundar S K
2024-10-20 11:25   ` kernel test robot
2024-10-17 15:03 ` [PATCH 5/6] i3c: master: Add support for SETAASA CCC Shyam Sundar S K
2024-10-17 15:03 ` [PATCH 6/6] i3c: dw: Add quirk to address OD/PP timing issue on AMD platform Shyam Sundar S K

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox