[PATCH RFC] pinctrl: add support for HiSilicon HiSTB SoCs
Yang Xiwen via B4 Relay
devnull+forbidden405.outlook.com at kernel.org
Mon Feb 12 17:30:15 CET 2024
From: Yang Xiwen <forbidden405 at outlook.com>
The first supported SoC is Hi3798MV200.
Signed-off-by: Yang Xiwen <forbidden405 at outlook.com>
---
This patchset adds support for HiSTB ioconfig module. The module is used
to set pins config(e.g. pull-up, pull-down, drive-strength etc..) and
pinmux.
The first supported chip is Hi3798MV200. Adding support for Hi3798CV200
should be also easy.
Below is an example of the dts node:
```dts
ioconfig: pinctrl at 8a21000 {
compatible = "hisilicon,hi3798mv200-ioconfig";
reg = <0x8a21000 0x180>;
#pinctrl-cells = <1>;
emmc_default: emmc-default-state {
cdata-pins {
// CDATA0-7
pins = "W20", "V20", "U20", "V19", "Y21", "W21", "V21", "U21";
bias-pullup;
slew-rate = <1>;
drive-strength = <8>;
function = "emmc_cdata";
};
cclk-pin {
pins = "T18";
bias-pullup;
slew-rate = <1>;
drive-strength = <8>;
function = "emmc_cclk";
};
ccmd-pin {
pins = "T20";
bias-pullup;
slew-rate = <1>;
drive-strength = <6>;
function = "emmc_ccmd";
};
reset-pin {
pins = "R20";
bias-disable;
slew-rate = <1>;
drive-strength = <1>;
function = "emmc_rst";
};
datastrobe-pin {
pins = "R21";
bias-pullup;
slew-rate;
drive-strength = <1>;
function = "emmc_datastrobe";
};
};
};
```
---
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/hisilicon/Kconfig | 21 ++
drivers/pinctrl/hisilicon/Makefile | 6 +
drivers/pinctrl/hisilicon/pinctrl-hi3798mv2x.c | 319 +++++++++++++++++++++++++
drivers/pinctrl/hisilicon/pinctrl-histb.c | 276 +++++++++++++++++++++
drivers/pinctrl/hisilicon/pinctrl-histb.h | 132 ++++++++++
7 files changed, 756 insertions(+)
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index a1d53cfbdb..d600a30492 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -346,6 +346,7 @@ endif
source "drivers/pinctrl/broadcom/Kconfig"
source "drivers/pinctrl/exynos/Kconfig"
+source "drivers/pinctrl/hisilicon/Kconfig"
source "drivers/pinctrl/intel/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/meson/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 0e929d8ca0..79fb800faf 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -36,3 +36,4 @@ obj-$(CONFIG_$(SPL_)PINCTRL_STMFX) += pinctrl-stmfx.o
obj-y += broadcom/
obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
obj-$(CONFIG_PINCTRL_STARFIVE) += starfive/
+obj-$(CONFIG_PINCTRL_HISILICON) += hisilicon/
diff --git a/drivers/pinctrl/hisilicon/Kconfig b/drivers/pinctrl/hisilicon/Kconfig
new file mode 100644
index 0000000000..33c3048940
--- /dev/null
+++ b/drivers/pinctrl/hisilicon/Kconfig
@@ -0,0 +1,21 @@
+config PINCTRL_HISILICON
+ bool
+
+config PINCTRL_HISTB
+ bool "HiSilicon HiSTB pinctrl framework"
+ depends on PINCTRL
+ select PINCTRL_HISILICON
+ imply PINCONF
+ help
+ Support HiSTB SoCs IOCONFIG module
+
+menu "HiSTB pinctrl drivers"
+ depends on PINCTRL_HISTB
+
+config PINCTRL_HI3798MV2X
+ bool "HiSilicon Hi3798MV2X pinctrl driver"
+ depends on ARCH_HI3798MV2X
+ help
+ Support IOCONFIG on Hi3798MV2X SoCs
+
+endmenu
diff --git a/drivers/pinctrl/hisilicon/Makefile b/drivers/pinctrl/hisilicon/Makefile
new file mode 100644
index 0000000000..5afb64d4b6
--- /dev/null
+++ b/drivers/pinctrl/hisilicon/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright 2024 (r) Yang Xiwen <forbidden405 at foxmail.com>
+
+obj-$(CONFIG_PINCTRL_HISTB) += pinctrl-histb.o
+obj-$(CONFIG_PINCTRL_HI3798MV2X) += pinctrl-hi3798mv2x.o
diff --git a/drivers/pinctrl/hisilicon/pinctrl-hi3798mv2x.c b/drivers/pinctrl/hisilicon/pinctrl-hi3798mv2x.c
new file mode 100644
index 0000000000..1e0a89675a
--- /dev/null
+++ b/drivers/pinctrl/hisilicon/pinctrl-hi3798mv2x.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * IOCONFIG driver for Hi3798MV2x SoCs
+ *
+ * Copyright 2024 (r) Yang Xiwen <forbidden405 at outlook.com>
+ */
+
+#include <dm/device.h>
+
+#include "pinctrl-histb.h"
+
+// The sequence is important!
+enum hi3798mv2x_ioconfig_pins {
+ HI3798MV2X_Y19,
+ HI3798MV2X_W19,
+ HI3798MV2X_AA20,
+ HI3798MV2X_Y20,
+ HI3798MV2X_V19,
+ HI3798MV2X_Y21,
+ HI3798MV2X_W20,
+ HI3798MV2X_W21,
+ HI3798MV2X_V20,
+ HI3798MV2X_V21,
+ HI3798MV2X_U20,
+ HI3798MV2X_U21,
+ HI3798MV2X_T18,
+ HI3798MV2X_T19,
+ HI3798MV2X_T20,
+ HI3798MV2X_R20,
+ HI3798MV2X_R21,
+ HI3798MV2X_P20,
+ HI3798MV2X_R19,
+ HI3798MV2X_K18,
+ HI3798MV2X_J17,
+ HI3798MV2X_J18,
+ HI3798MV2X_H17,
+ HI3798MV2X_H18,
+ HI3798MV2X_K20,
+ HI3798MV2X_K19,
+ HI3798MV2X_J20,
+ HI3798MV2X_J19,
+ HI3798MV2X_H21,
+ HI3798MV2X_H20,
+ HI3798MV2X_H19,
+ HI3798MV2X_G20,
+ HI3798MV2X_G19,
+ HI3798MV2X_F21,
+ HI3798MV2X_F20,
+ HI3798MV2X_F19,
+ HI3798MV2X_E20,
+ HI3798MV2X_E19,
+ HI3798MV2X_D21,
+ HI3798MV2X_E18,
+ HI3798MV2X_C20,
+ HI3798MV2X_D19,
+ HI3798MV2X_B21,
+ HI3798MV2X_B18,
+ HI3798MV2X_C17,
+ HI3798MV2X_B17,
+ HI3798MV2X_A17,
+ HI3798MV2X_C16,
+ HI3798MV2X_B16,
+ HI3798MV2X_B4,
+ HI3798MV2X_C4,
+ HI3798MV2X_A3,
+ HI3798MV2X_B3,
+ HI3798MV2X_A2,
+ HI3798MV2X_B2,
+ HI3798MV2X_A6,
+ HI3798MV2X_C6,
+ HI3798MV2X_C5,
+ HI3798MV2X_C3,
+ HI3798MV2X_D4,
+ HI3798MV2X_D3,
+ HI3798MV2X_B1,
+ HI3798MV2X_C2,
+ HI3798MV2X_C1,
+ HI3798MV2X_A5,
+ HI3798MV2X_D5,
+};
+
+/* incomplete (yet) */
+static const struct histb_pin_function_desc hi3798mv2x_pin_funcs[] = {
+ HISTB_PIN_FUNC(0, "emmc_cdata", ((struct histb_pin_func_setup_entry[]){
+ { HI3798MV2X_V19, 0x2 }, { HI3798MV2X_Y21, 0x2 }, { HI3798MV2X_W20, 0x2 },
+ { HI3798MV2X_W21, 0x2 }, { HI3798MV2X_V20, 0x2 }, { HI3798MV2X_V21, 0x2 },
+ { HI3798MV2X_U20, 0x2 }, { HI3798MV2X_U21, 0x2 }, })),
+ HISTB_PIN_FUNC(1, "emmc_cclk",
+ ((struct histb_pin_func_setup_entry[]){ { HI3798MV2X_T18, 0x2 } })),
+ HISTB_PIN_FUNC(2, "emmc_ccmd",
+ ((struct histb_pin_func_setup_entry[]){ { HI3798MV2X_T20, 0x2 } })),
+ HISTB_PIN_FUNC(3, "emmc_rst",
+ ((struct histb_pin_func_setup_entry[]){ { HI3798MV2X_R20, 0x2 } })),
+ HISTB_PIN_FUNC(4, "emmc_datastrobe",
+ ((struct histb_pin_func_setup_entry[]){ { HI3798MV2X_R21, 0x2 } })),
+};
+
+/* Frequentely used drive strength table */
+#define DRIVE_STRENGTH_TABLE_SAMPLE_A ((const u8[]){ 4, 3, 2, 1, 0 })
+#define DRIVE_STRENGTH_TABLE_SAMPLE_B ((const u8[]){ 18, 17, 16, 15, 13, 12, 11, 10, 9, 8, 7, 6, 4, 3, 2, 1, 0 })
+
+static const struct histb_pin_desc hi3798mv2x_pins[] = {
+ HISTB_PIN(HI3798MV2X_Y19, "Y19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO0_0", 0x0 }, { "NF_RDY", 0x1 }, { } }),
+ HISTB_PIN_FLAG_NOPD),
+ HISTB_PIN(HI3798MV2X_W19, "W19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO0_1", 0x0 }, { "NF_CSN", 0x1 }, { } }),
+ HISTB_PIN_FLAG_NOPD),
+ HISTB_PIN(HI3798MV2X_AA20, "AA20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO0_2", 0x0 }, { "NF_DQSN", 0x1 }, { "BOOT_SEL2", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_Y20, "Y20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[]){ { "NF_DQS", 0x1 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_V19, "V19", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO0_4", 0x0 }, { "NF_DQ7", 0x1 }, { "EMMC_CDATA3", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_Y21, "Y21", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO0_5", 0x0 }, { "NF_DQ6", 0x1 }, { "EMMC_CDATA4", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_W20, "W20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO0_6", 0x0 }, { "NF_DQ5", 0x1 }, { "EMMC_CDATA0", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_W21, "W21", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO0_7", 0x0 }, { "NF_DQ4", 0x1 }, { "EMMC_CDATA5", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_V20, "V20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_0", 0x0 }, { "NF_DQ3", 0x1 }, { "EMMC_CDATA1", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_V21, "V21", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_1", 0x0 }, { "NF_DQ2", 0x1 }, { "EMMC_CDATA6", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_U20, "U20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_2", 0x0 }, { "NF_DQ1", 0x1 }, { "EMMC_CDATA2", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_U21, "U21", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_3", 0x0 }, { "NF_DQ0", 0x1 }, { "EMMC_CDATA7", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_T18, "T18", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_4", 0x0 }, { "NF_WEN", 0x1 }, { "EMMC_CCLK_OUT", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_T19, "T19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_5", 0x0 }, { "NF_ALE", 0x1 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_T20, "T20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_6", 0x0 }, { "NF_CLE", 0x1 }, { "EMMC_CCMD", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_R20, "R20", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO1_7", 0x0 }, { "NF_REC", 0x1 }, { "EMMC_RST", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_R21, "R21", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO2_0", 0x0 }, { "NF_REN", 0x1 }, { "EMMC_DATA_STROBE", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_P20, "P20", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[])
+ { { "PMC_CORE0", 0x0 }, { "I2C0_SDA", 0x1 }, { "GPIO2_1", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_R19, "R19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[])
+ { { "PMC_GPU0", 0x0 }, { "I2C0_SCL", 0x1 }, { "GPIO2_2", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_K18, "K18", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]) { { "GPIO2_3", 0x0 }, { "SATA0_PWREN", 0x1 },
+ { "UART3_CTSN", 0x2 }, { "TSI0_D7", 0x3 }, { "TSI3_CLK", 0x4 }, { "SIM1_DATA", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_J17, "J17", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[])
+ { { "GPIO2_4", 0x0 }, { "SATA0_LED_N", 0x1 }, { "UART3_RTSN", 0x2 }, { "TSI1_SYNC", 0x3 },
+ { "TSI1_D1", 0x4 }, { "TSI0D6", 0x5 }, { "TSI3_VALID", 0x6 }, { "SIM1DET", 0x7 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_J18, "J18", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO2_5", 0x0 }, { "UART3_RXD", 0x1 },
+ { "TSI1_D0", 0x2 }, { "TSIO_D5", 0x3 }, { "TSI3_D0", 0x4 }, { "SIM1_RST", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_H17, "H17", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO2_6", 0x0 }, { "UART3_TXD", 0x1 },
+ { "TSI1_CLK", 0x2 }, { "TSIO_D4", 0x3 }, { "TSI2_VALID", 0x4 }, { "SIM1_CLK", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_H18, "H18", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO2_7", 0x0 }, { "I2C2_SDA", 0x1 },
+ { "TSI1_VALID", 0x2 }, { "TSIO_D3", 0x3 }, { "TSI2_D0", 0x4 }, { "SIM1_PWREN", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_K20, "K20", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "JTAG_TRSTN", 0x0 }, { "I2C2_SCL", 0x1 },
+ { "SPI0_SD0", 0x2 }, { "SIM0_DATA", 0x3 }, { "GPIO3_0", 0x4 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_K19, "K19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "JTAG_TDI", 0x0 }, { "SPIO_CSN", 0x1 },
+ { "SIM0_DET", 0x2 }, { "GPIO3_1", 0x3 }, { "UART2_CTSN", 0x4 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_J20, "J20", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "JTAG_TMS", 0x0 }, { "I2S_RX_BCLK", 0x1 },
+ { "SPI0_SCLK", 0x2 }, { "SIM0_RST", 0x3 }, { "GPIO3_2", 0x4 }, { "UART2_TXD", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_J19, "J19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "JTAG_TCK", 0x0 }, { "I2S_RX_WS", 0x1 },
+ { "SPI0_SDI", 0x2 }, { "SIM0_CLK", 0x3 }, { "GPIO3_3", 0x4 }, { "UART2_RXD", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_H21, "H21", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "JTAG_TDO", 0x0 }, { "I2S_RX_MCLK", 0x1 },
+ { "I2S_DOUT3", 0x2 }, { "SIM0_PWREN", 0x3 }, { "GPIO3_4", 0x4 }, { "UART2_RTSN", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_H20, "H20", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO3_5", 0x0 }, { "I2S_MCLK", 0x1 },
+ { "I2S_DOUT2", 0x2 }, { "SF_WPN_IO2", 0x3 }, { "TSO0_SYNC", 0x4 }, { } }), HISTB_PIN_FLAG_NOPD),
+ HISTB_PIN(HI3798MV2X_H19, "H19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO3_6", 0x0 }, { "I2S_WS", 0x1 },
+ { "I2S_DOUT1", 0x2 }, { "TSI1_SYNC", 0x3 }, { "TSI1_D1", 0x4 }, { "SF_SDI_IO1", 0x5 },
+ { "TSO0_VALID", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_G20, "G20", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO3_7", 0x0 }, { "I2S_DOUT0", 0x1 },
+ { "TSI1_D0", 0x3 }, { "SF_CSN", 0x5 }, { "TSO0_CLK", 0x6 }, { } }), HISTB_PIN_FLAG_NOPD),
+ HISTB_PIN(HI3798MV2X_G19, "G19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_0", 0x0 }, { "I2S_BCLK", 0x1 },
+ { "I2S_WS", 0x2 }, { "TSI1_CLK", 0x3 }, { "SF_HOLDN_IO3", 0x5 }, { "TSO0_D0", 0x6 }, { } }),
+ HISTB_PIN_FLAG_NOPD),
+ HISTB_PIN(HI3798MV2X_F21, "F21", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_1", 0x0 }, { "I2S_DIN", 0x1 },
+ { "I2S_BCLK", 0x2 }, { "TSI1_VALID", 0x3 }, { "SF_CLK", 0x5 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_F20, "F20", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_2", 0x0 }, { "SDIO1_CWPR", 0x1 },
+ { "I2S_MCLK", 0x2 }, { "SF_SDO_IO0", 0x4 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_F19, "F19", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_3", 0x0 }, { "SDIO1_CARD_POWER_EN", 0x1 },
+ { "I2C1_SCL", 0x3 }, { "I2S_RX_BCLK", 0x4 }, { "TSI0_D2", 0x5 }, { "TSI2_CLK", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_E20, "E20", ((const u8[]){ 18, 16, 14, 12, 5, 4, 2, 1, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_4", 0x0 }, { "SDIO1_CDATA1", 0x1 },
+ { "I2S_RX_WS", 0x4 }, { "TSI0_D1", 0x5 }, { "I2C1_SDA", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_E19, "E19", ((const u8[]){ 18, 16, 14, 12, 5, 4, 2, 1, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_5", 0x0 }, { "SDIO1_CDATA0", 0x1 },
+ { "TSI0_D1", 0x2 }, { "TSI0_SYNC", 0x3 }, { "I2S_RX_MCLK", 0x4 }, { "TSI0_DO", 0x5 },
+ { "I2C1_SCL", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_D21, "D21", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_6", 0x0 }, { "SDIO1_CCLK_OUT", 0x1 },
+ { "TSI0_DO", 0x3 }, { "I2S_MCLK", 0x4 }, { "TSI0_CLK", 0x5 }, { "TSI1_VALID", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_E18, "E18", ((const u8[]){ 18, 16, 14, 12, 5, 4, 2, 1, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO4_7", 0x0 }, { "SDIO1_CCMD", 0x1 },
+ { "TSI0_CLK", 0x3 }, { "I2S_WS", 0x4 }, { "TSI0_VALID", 0x5 }, { "TSI1_D0", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_C20, "C20", ((const u8[]){ 18, 16, 14, 12, 5, 4, 2, 1, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO6_0", 0x0 }, { "SDIO1_CDATA3", 0x1 },
+ { "TSI1_CLK", 0x2 }, { "TSI0_VALID", 0x3 }, { "I2S_DOUT0", 0x4 }, { "I2C2_SCL", 0x5 },
+ { "TSI0_VALID", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_D19, "D19", ((const u8[]){ 18, 16, 14, 12, 5, 4, 2, 1, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO6_1", 0x0 }, { "SDIO1_CDATA2", 0x1 },
+ { "I2C2_SCL", 0x3 }, { "I2S_BCLK", 0x4 }, { "I2C2_SDA", 0x5 }, { "TSI0_D0", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_B21, "B21", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO6_2", 0x0 }, { "SDIO1_CARD_DETECT", 0x1 },
+ { "I2C2_SDA", 0x3 }, { "I2S_DIN", 0x4 }, { "TSI0_CLK", 0x6 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_B18, "B18", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "JTAG_SEL", 0x0 }, { "GPIO6_3", 0x1 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_C17, "C17", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO6_4", 0x0 }, { "SPDIF_OUT", 0x1 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_B17, "B17", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "HDMITX_HOTPLUG", 0x1 }, { "GPIO6_5", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_A17, "A17", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "HDMITX_SDA", 0x1 }, { "GPIO6_6", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_C16, "C16", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "HDMITX_SCL", 0x1 }, { "GPIO6_7", 0x2 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_B16, "B16", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "HDMITX_CEC", 0x1 }, { "GPIO7_0", 0x2 }, { } }),
+ HISTB_PIN_FLAG_NOPU | HISTB_PIN_FLAG_NOPD | HISTB_PIN_FLAG_NOSR),
+ HISTB_PIN(HI3798MV2X_B4, "B4", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_4", 0x0 }, { "RGMII_RXCK", 0x1 },
+ { "RMII_TXD1", 0x2 }, { "SDIOO_CDATA1", 0x3 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_C4, "C4", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_5", 0x0 }, { "RGMII_RXDV", 0x1 },
+ { "RMII_TXD0", 0x2 }, { "SDIO0_CDATA0", 0x3 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_A3, "A3", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_6", 0x0 }, { "RGMII_RXD0", 0x1 },
+ { "RMII_TXEN", 0x2 }, { "SDIO0_CCLK_OUT", 0x3 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_B3, "B3", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_7", 0x0 }, { "RGMII_RXD1", 0x1 },
+ { "RMII_RXDV", 0x2 }, { "SDIO0_CCMD", 0x3 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_A2, "A2", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO8_0", 0x0 }, { "RGMII_RXD2", 0x1 },
+ { "RMII_RXD0", 0x2 }, { "SDIO0_CDATA3", 0x3 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_B2, "B2", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO8_1", 0x0 }, { "RGMII_RXD3", 0x1 },
+ { "RMII_RXD1", 0x2 }, { "SDIOO_CDATA2", 0x3 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_A6, "A6", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_1", 0x0 }, { "RGMII_RST", 0x1 },
+ { "UART3_TXD", 0x2 }, { "FE_LED_ACT", 0x3 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_C6, "C6", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_2", 0x0 }, { "RGMII_MDIO", 0x1 },
+ { "UART3_RXD", 0x2 }, { "FE_LED_BASE", 0x3 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_C5, "C5", DRIVE_STRENGTH_TABLE_SAMPLE_A,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO7_3", 0x0 }, { "RGMII_MDCK", 0x1 },
+ { "RMII_RST", 0x2 }, { "SDIO0_CARD_DETECT", 0x3 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_C3, "C3", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO8_2", 0x0 }, { "RGMII_TXEN", 0x1 },
+ { "BOOT_SEL0", 0x2 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_D4, "D4", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO8_3", 0x0 }, { "RGMII_TXCK", 0x1 },
+ { "UART3_CTSN", 0x2 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_D3, "D3", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO8_4", 0x0 }, { "RGMII_TXD3", 0x1 },
+ { "UART3_RTSN", 0x2 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_B1, "B1", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[]){ { "GPIO8_5", 0x0 }, { "RGMII_TXD2", 0x1 },
+ { "RMII_MDCK", 0x2 }, { "BOOT_SEL1", 0x3 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_C2, "C2", ((const u8[]){ 18, 16, 14, 12, 10, 8, 6, 4, 0 }),
+ ((const struct histb_pin_mux_desc[]){ { "RGMII_TXD1", 0x1 }, { "RMII_MDI0", 0x2 },
+ { "SDIO0_CWPR", 0x3 }, { "GPIO8_6", 0x4 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_C1, "C1", DRIVE_STRENGTH_TABLE_SAMPLE_B,
+ ((const struct histb_pin_mux_desc[]){ { "RGMII_TXDO", 0x1 }, { "RMII_REFCLK", 0x2 },
+ { "SDIO0_CARD_POWER_EN", 0x3 }, { "GPIO8_7", 0x4 }, { } }), HISTB_PIN_FLAG_HAS_SCHMITT),
+ HISTB_PIN(HI3798MV2X_A5, "A5", ((const u8 *)NULL),
+ ((const struct histb_pin_mux_desc[]){ { "GPIO9_0", 0x0 }, { "CLKOUT_25M", 0x1 }, { } }), 0),
+ HISTB_PIN(HI3798MV2X_D5, "D5", ((const u8 *)NULL),
+ ((const struct histb_pin_mux_desc[]){ { "PMC_CPU0", 0x0 }, { "GPIO9_1", 0x1 }, { } }),
+ HISTB_PIN_FLAG_NOPU | HISTB_PIN_FLAG_NOPD | HISTB_PIN_FLAG_NOSR),
+};
+
+static struct histb_pinctrl_priv hi3798mv2x_pinctrl_priv = {
+ .pins = hi3798mv2x_pins,
+ .funcs = hi3798mv2x_pin_funcs,
+ .pin_nums = ARRAY_SIZE(hi3798mv2x_pins),
+ .func_nums = ARRAY_SIZE(hi3798mv2x_pin_funcs),
+};
+
+static const struct udevice_id hi3798mv2x_pinctrl_match[] = {
+ { .compatible = "hisilicon,hi3798mv200-ioconfig", .data = (ulong)&hi3798mv2x_pinctrl_priv },
+ { },
+};
+
+U_BOOT_DRIVER(hi3798mv2x_pinctrl) = {
+ .name = "hi3798mv2x_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = hi3798mv2x_pinctrl_match,
+ .of_to_plat = histb_pinctrl_of_to_plat,
+ .ops = &histb_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/hisilicon/pinctrl-histb.c b/drivers/pinctrl/hisilicon/pinctrl-histb.c
new file mode 100644
index 0000000000..d0521c3459
--- /dev/null
+++ b/drivers/pinctrl/hisilicon/pinctrl-histb.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * IOCONFIG pinctrl driver for HiSTB SoCs
+ *
+ * Copyright 2024 (r) Yang Xiwen <forbidden405 at outlook.com>
+ */
+
+#include <asm/io.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/pinctrl.h>
+#include <dm/read.h>
+#include <linux/bitfield.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "pinctrl-histb.h"
+
+static int histb_pinctrl_get_pins_count(struct udevice *dev)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->pin_nums;
+}
+
+static const char *histb_pinctrl_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->pins[selector].name;
+}
+
+static int histb_pinctrl_get_functions_count(struct udevice *dev)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->func_nums;
+}
+
+static const char *histb_pinctrl_get_function_name(struct udevice *dev, unsigned int selector)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->funcs[selector].name;
+}
+
+static int histb_pinctrl_pinmux_set(struct udevice *dev, unsigned int pin_selector,
+ unsigned int func_selector)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct histb_pin_function_desc *func = &priv->funcs[func_selector];
+ const struct histb_pin_func_setup_entry *func_setup_tbl = func->cfg_tbl;
+ int i;
+ u32 reg;
+ void __iomem *pin_reg = (u32 *)priv->base + priv->pins[pin_selector].number;
+ bool found = false;
+
+ for (i = 0; i < func->pins_num; i++) {
+ if (func_setup_tbl[i].pin_selector == pin_selector) {
+ reg = readl(pin_reg);
+ reg &= ~HISTB_PIN_FUNC_MASK;
+ reg |= func_setup_tbl[i].mask;
+ writel(reg, pin_reg);
+
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ dev_err(dev, "Unable to set pin %d to the given function %d\n",
+ pin_selector, func_selector);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct pinconf_param histb_pinctrl_pinconf_params[] = {
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+ { "bias-pulldown", PIN_CONFIG_BIAS_PULL_DOWN, 0 },
+ { "bias-pullup", PIN_CONFIG_BIAS_PULL_UP, 0 },
+ { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
+ { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 1 },
+ { "slew-rate", PIN_CONFIG_SLEW_RATE, 1 },
+};
+
+enum histb_pinctrl_bias_status {
+ BIAS_PULL_DOWN,
+ BIAS_PULL_UP,
+ BIAS_DISABLE,
+};
+
+static int histb_pinctrl_set_bias(struct udevice *dev, unsigned int selector,
+ enum histb_pinctrl_bias_status status)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+ void __iomem *pin_reg = (u32 *)priv->base + priv->pins[selector].number;
+ u32 reg = readl(pin_reg);
+
+ reg &= ~(HISTB_PIN_PULLDOWN | HISTB_PIN_PULLUP);
+
+ switch (status) {
+ case BIAS_DISABLE:
+ break;
+ case BIAS_PULL_DOWN:
+ reg |= HISTB_PIN_PULLDOWN;
+ break;
+ case BIAS_PULL_UP:
+ reg |= HISTB_PIN_PULLUP;
+ break;
+ }
+
+ writel(reg, pin_reg);
+
+ return 0;
+}
+
+static int histb_pinctrl_set_slew_rate(struct udevice *dev, unsigned int pin_selector,
+ unsigned int argument)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+ void __iomem *pin_reg = (u32 *)priv->base + priv->pins[pin_selector].number;
+ u32 reg = readl(pin_reg);
+
+ if (likely(argument == 1)) {
+ reg |= HISTB_PIN_SLEWRATE;
+ } else if (argument == 0) {
+ reg &= ~HISTB_PIN_SLEWRATE;
+ } else {
+ dev_err(dev, "slew rate argument can be only 0 or 1!\n");
+ return -EINVAL;
+ }
+
+ writel(reg, pin_reg);
+
+ return 0;
+}
+
+static int histb_pinctrl_set_schmitt(struct udevice *dev, unsigned int pin_selector,
+ unsigned int argument)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+ void __iomem *pin_reg = (u32 *)priv->base + priv->pins[pin_selector].number;
+ u32 reg = readl(pin_reg);
+
+ if (likely(argument == 0)) {
+ reg &= ~HISTB_PIN_SCHMITT;
+ } else if (argument == 1) {
+ reg |= HISTB_PIN_SCHMITT;
+ } else {
+ dev_err(dev, "schmitt argument can be only 0 or 1!\n");
+ return -EINVAL;
+ }
+
+ writel(reg, pin_reg);
+
+ return 0;
+}
+
+static int histb_pinctrl_set_drive_strength(struct udevice *dev, unsigned int pin_selector,
+ unsigned int argument)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+ const u8 *drv_tbl = priv->pins[pin_selector].drv_tbl;
+ void __iomem *pin_reg = (u32 *)priv->base + priv->pins[pin_selector].number;
+ u32 reg = readl(pin_reg);
+ int i = -1;
+
+ if (unlikely(argument == 0)) {
+ dev_err(dev, "the minimal drive strength is 1mA!\n");
+ return -EINVAL;
+ }
+
+ if (unlikely(!drv_tbl)) {
+ dev_err(dev, "pin %u does not support setting drive strength!\n", pin_selector);
+ return -ENOENT;
+ }
+
+ // calculate the largest drive-strength that does not exceeds the given value
+ // if the lowest value is still too large, use that anyway
+ // TODO: use bsearch()?
+ while (drv_tbl[++i] > argument)
+ ;
+
+ if (!drv_tbl[i])
+ i--;
+
+ reg &= ~HISTB_PIN_DRV_MASK;
+ reg |= FIELD_PREP(HISTB_PIN_DRV_MASK, i);
+
+ debug("%s: setting drive strength of pin %s to %d\n", __func__, priv->pins[pin_selector].name, drv_tbl[i]);
+ writel(reg, pin_reg);
+
+ return 0;
+}
+
+static int histb_pinctrl_pinconf_set(struct udevice *dev, unsigned int pin_selector,
+ unsigned int param, unsigned int argument)
+{
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ return histb_pinctrl_set_bias(dev, pin_selector, BIAS_DISABLE);
+ case PIN_CONFIG_BIAS_PULL_UP:
+ return histb_pinctrl_set_bias(dev, pin_selector, BIAS_PULL_UP);
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ return histb_pinctrl_set_bias(dev, pin_selector, BIAS_PULL_DOWN);
+ case PIN_CONFIG_SLEW_RATE:
+ return histb_pinctrl_set_slew_rate(dev, pin_selector, argument);
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ return histb_pinctrl_set_schmitt(dev, pin_selector, argument);
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ return histb_pinctrl_set_drive_strength(dev, pin_selector, argument);
+ }
+
+ dev_err(dev, "can't handle given config %d\n", param);
+ return -EINVAL;
+}
+
+static int histb_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector,
+ char *buf, int size)
+{
+ struct histb_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct histb_pin_mux_desc *desc = priv->pins[selector].func_tbl;
+ u32 reg = readl((u32 *)priv->base + priv->pins[selector].number);
+ bool found = false;
+ int current;
+
+ current = FIELD_GET(HISTB_PIN_FUNC_MASK, reg);
+
+ while (desc->name) {
+ if (desc->bits == current) {
+ strlcpy(buf, desc->name, size);
+ found = true;
+ break;
+ }
+ desc++;
+ }
+
+ if (!found) {
+ dev_warn(dev, "unknown pinmux selected\n");
+ strcpy(buf, "UNKNOWN!");
+ }
+
+ return 0;
+}
+
+const struct pinctrl_ops histb_pinctrl_ops = {
+ .get_pins_count = histb_pinctrl_get_pins_count,
+ .get_pin_name = histb_pinctrl_get_pin_name,
+ .get_functions_count = histb_pinctrl_get_functions_count,
+ .get_function_name = histb_pinctrl_get_function_name,
+ .pinmux_set = histb_pinctrl_pinmux_set,
+ .pinconf_num_params = ARRAY_SIZE(histb_pinctrl_pinconf_params),
+ .pinconf_params = histb_pinctrl_pinconf_params,
+ .pinconf_set = histb_pinctrl_pinconf_set,
+ .set_state = pinctrl_generic_set_state,
+ .get_pin_muxing = histb_pinctrl_get_pin_muxing,
+};
+
+int histb_pinctrl_of_to_plat(struct udevice *dev)
+{
+ struct histb_pinctrl_priv *priv = (void *)dev_get_driver_data(dev);
+
+ priv->base = dev_remap_addr(dev);
+ if (!priv->base) {
+ dev_err(dev, "failed to remap addr\n");
+ return -EINVAL;
+ }
+
+ dev_set_priv(dev, priv);
+
+ return 0;
+}
diff --git a/drivers/pinctrl/hisilicon/pinctrl-histb.h b/drivers/pinctrl/hisilicon/pinctrl-histb.h
new file mode 100644
index 0000000000..6169534139
--- /dev/null
+++ b/drivers/pinctrl/hisilicon/pinctrl-histb.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+
+/* per-register bit definition */
+#define HISTB_PIN_SCHMITT BIT(14)
+#define HISTB_PIN_PULLDOWN BIT(13)
+#define HISTB_PIN_PULLUP BIT(12)
+#define HISTB_PIN_SLEWRATE BIT(8)
+#define HISTB_PIN_DRV_MASK GENMASK(7, 4)
+#define HISTB_PIN_FUNC_MASK GENMASK(2, 0)
+
+/**
+ * @histb_pin_desc flags
+ *
+ * @HISTB_PIN_FLAG_NOPU: This pin does not support "bias-pullup"
+ * @HISTB_PIN_FLAG_NOPD: This pin does not support "bias-pulldown"
+ * @HISTB_PIN_FLAG_NOSR: This pin does not support "slew-rate"
+ * @HISTB_PIN_FLAG_HAS_SCHMITT: This pin supports setting schmitt
+ */
+#define HISTB_PIN_FLAG_NOPU BIT(0)
+#define HISTB_PIN_FLAG_NOPD BIT(1)
+#define HISTB_PIN_FLAG_NOSR BIT(2)
+#define HISTB_PIN_FLAG_HAS_SCHMITT BIT(3)
+
+/**
+ * histb_pin_mux_desc - a descriptor for one function of a pin.
+ *
+ * @name: the name of the function, in capital
+ * @bits: the bits pattern for this function
+ */
+struct histb_pin_mux_desc {
+ const char *name;
+ u32 bits;
+};
+
+/**
+ * histb_pin_desc - a descriptor for a pin
+ *
+ * @number: ID for this pin, also used as offset into device address space
+ * @name: pin name, e.g. "F17", refer to the datasheet for detail
+ * @drv_tbl: (Optional) drive strength table, end with 0. The index is used as bits pattern. fill
+ * NULL if setting drive strength is not supported.
+ * @func_tbl: pinmux function table, end with { }.
+ * @flags: pin flags (use HISTB_PIN_FLAG_* constants)
+ */
+struct histb_pin_desc {
+ unsigned int number;
+ const char *name;
+ const u8 *drv_tbl;
+ const struct histb_pin_mux_desc *func_tbl;
+ int flags;
+};
+
+/**
+ * HISTB_PIN() - a helper for initializing struct histb_pin_desc
+ */
+#define HISTB_PIN(_index, _name, _drv_tbl, _func_tbl, _flag) { \
+ .number = _index, \
+ .name = _name, \
+ .drv_tbl = _drv_tbl, \
+ .func_tbl = _func_tbl, \
+ .flags = _flag, \
+}
+
+/**
+ * histb_pin_func_setup_entry - an entry for setting up a function for a pin
+ *
+ * @pin_selector: pin ID
+ * @mask: function bit pattern
+ */
+struct histb_pin_func_setup_entry {
+ unsigned int pin_selector;
+ u8 mask;
+};
+
+/**
+ * histb_pin_function_desc - a descriptor for a function
+ *
+ * @func_selector: function selector
+ * @name: function name
+ * @pins_num: the number of pins engaged in this function
+ * @cfg_tbl: config table
+ */
+struct histb_pin_function_desc {
+ unsigned int func_selector;
+ const char *name;
+ unsigned int pins_num;
+ const struct histb_pin_func_setup_entry *cfg_tbl;
+};
+
+/**
+ * HISTB_PIN_FUNC - a helper macro to setup a function
+ */
+#define HISTB_PIN_FUNC(_id, _name, _cfg) { \
+ .func_selector = _id, \
+ .name = _name, \
+ .pins_num = ARRAY_SIZE(_cfg), \
+ .cfg_tbl = _cfg, \
+}
+
+/**
+ * histb_pinctrl_priv - private data for the driver
+ *
+ * @base: device base address
+ * @pins: descriptor array for all pins
+ * @funcs: descriptor array for all functions
+ * @pin_nums: array size of .pins
+ * @func_nums: array size of .funcs
+ */
+struct histb_pinctrl_priv {
+ void __iomem *base;
+ const struct histb_pin_desc *pins;
+ const struct histb_pin_function_desc *funcs;
+ unsigned int pin_nums;
+ unsigned int func_nums;
+};
+
+/**
+ * histb_pinctrl_of_to_plat - convert device tree node to private data
+ *
+ * use this function as .of_to_plat field in the driver
+ */
+int histb_pinctrl_of_to_plat(struct udevice *dev);
+
+/**
+ * histb_pinctrl_ops - HiSTB pinctrl ops
+ *
+ * use this struct as .ops field in the driver
+ */
+extern const struct pinctrl_ops histb_pinctrl_ops;
---
base-commit: 050a9b981d6a835133521b599be3ae189ce70f41
change-id: 20240204-pinctrl-3a126ad9286e
Best regards,
--
Yang Xiwen <forbidden405 at outlook.com>
More information about the U-Boot
mailing list