Files
OpenBMC/meta-luxshare/meta-bhs/recipes-kernel/linux/linux-aspeed/0004-Add-I3C-GPIO-switch-in-dw-i3c-master-driver.patch
T

90 lines
2.5 KiB
Diff
Raw Normal View History

2026-04-23 17:07:55 +08:00
From 0851611d47f99f5bbba29d3cb39e109a4ecdcb0e Mon Sep 17 00:00:00 2001
From: wangjue <jue.wang2@luxshare-ict.com>
Date: Fri, 11 Oct 2024 12:48:24 +0800
Subject: [PATCH] Add I3C GPIO switch in dw-i3c-master driver
Signed-off-by: wangjue <jue.wang2@luxshare-ict.com>
---
drivers/i3c/master/dw-i3c-master.c | 34 ++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c
index c29c609510e7..6d1ba40eca0f 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -25,6 +25,7 @@
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>
+#include <linux/gpio.h>
/*
* Below bits are valid for I3Cx Global register (REG1) on AST2600 platform.
@@ -373,6 +374,9 @@
#define AST2600_I3C_IBI_MAX_PAYLOAD 255
+#define SEL_CPU0_I3C_DDR_GPIO 921
+#define SEL_CPU1_I3C_DDR_GPIO 922
+
struct dw_i3c_master_caps {
u8 cmdfifodepth;
u8 datafifodepth;
@@ -3110,6 +3114,33 @@ static int dw_i3c_debugfs_init(struct dw_i3c_master *master)
return 0;
}
+static void i3c_gpio_switch_bmc(struct dw_i3c_master *master)
+{
+ if (gpio_request(SEL_CPU0_I3C_DDR_GPIO, "dw-i3c-master")) {
+ dev_err(master->dev, "unable to allocate SEL_CPU0_I3C_DDR_GPIO\n");
+ return;
+ }
+
+ if (gpio_request(SEL_CPU1_I3C_DDR_GPIO, "dw-i3c-master")) {
+ dev_err(master->dev, "unable to allocate SEL_CPU0_I3C_DDR_GPIO\n");
+ return;
+ }
+ gpio_direction_output(SEL_CPU0_I3C_DDR_GPIO, 1);
+ gpio_direction_output(SEL_CPU1_I3C_DDR_GPIO, 1);
+
+ usleep_range(500, 1000);
+}
+
+static void i3c_gpio_switch_bios(struct dw_i3c_master *master)
+{
+ gpio_direction_output(SEL_CPU0_I3C_DDR_GPIO, 0);
+ gpio_direction_output(SEL_CPU1_I3C_DDR_GPIO, 0);
+ usleep_range(500, 1000);
+
+ gpio_free(SEL_CPU0_I3C_DDR_GPIO);
+ gpio_free(SEL_CPU1_I3C_DDR_GPIO);
+}
+
static int dw_i3c_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@@ -3149,6 +3180,7 @@ static int dw_i3c_probe(struct platform_device *pdev)
spin_lock_init(&master->ibi.master.lock);
platform_set_drvdata(pdev, master);
+ i3c_gpio_switch_bmc(master);
/* Information regarding the FIFOs/QUEUEs depth */
ret = readl(master->regs + QUEUE_STATUS_LEVEL);
@@ -3218,9 +3250,11 @@ static int dw_i3c_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "i3c bus %d registered, irq %d\n",
master->base.bus_id, irq);
+ i3c_gpio_switch_bios(master);
return 0;
err_assert_rst:
+ i3c_gpio_switch_bios(master);
reset_control_assert(master->core_rst);
err_disable_core_clk:
--
2.34.1