90 lines
2.5 KiB
Diff
90 lines
2.5 KiB
Diff
|
|
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
|
||
|
|
|