From 0851611d47f99f5bbba29d3cb39e109a4ecdcb0e Mon Sep 17 00:00:00 2001 From: wangjue Date: Fri, 11 Oct 2024 12:48:24 +0800 Subject: [PATCH] Add I3C GPIO switch in dw-i3c-master driver Signed-off-by: wangjue --- 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 #include #include +#include /* * 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