From: Yang Xiwen <forbidden...@outlook.com>

The first supported SoC is Hi3798MV200.

Signed-off-by: Yang Xiwen <forbidden...@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@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 <forbidden...@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 <forbidden...@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 <forbidden...@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 <forbidden...@outlook.com>

Reply via email to