[PATCH v5 13/33] pinctrl: Add support for Kendryte K210 FPIOA

Rick Chen rickchen36 at gmail.com
Wed Mar 4 07:47:43 CET 2020


Hi Sean

> The Fully-Programmable Input/Output Array (FPIOA) device controls pin
> multiplexing on the K210. The FPIOA can remap any supported function to any
> multifunctional IO pin. It can also perform basic GPIO functions, such as
> reading the current value of a pin.
>
> Signed-off-by: Sean Anderson <seanga2 at gmail.com>
> ---
>
> Changes in v5:
> - New
>
>  MAINTAINERS                                   |   2 +
>  .../pinctrl/kendryte,k210-fpioa.txt           | 116 +++
>  drivers/pinctrl/Kconfig                       |   1 +
>  drivers/pinctrl/Makefile                      |   1 +
>  drivers/pinctrl/kendryte/Kconfig              |   7 +
>  drivers/pinctrl/kendryte/Makefile             |   1 +
>  drivers/pinctrl/kendryte/pinctrl.c            | 663 ++++++++++++++++++
>  drivers/pinctrl/kendryte/pinctrl.h            | 325 +++++++++
>  include/dt-bindings/pinctrl/k210-pinctrl.h    |  12 +
>  9 files changed, 1128 insertions(+)
>  create mode 100644 doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
>  create mode 100644 drivers/pinctrl/kendryte/Kconfig
>  create mode 100644 drivers/pinctrl/kendryte/Makefile
>  create mode 100644 drivers/pinctrl/kendryte/pinctrl.c
>  create mode 100644 drivers/pinctrl/kendryte/pinctrl.h
>  create mode 100644 include/dt-bindings/pinctrl/k210-pinctrl.h
>

Please checkpatch and fix

total: 3 errors, 13 warnings, 5 checks, 1147 lines checked

Thanks
Rick


> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8e9e0569ba..8725bcf9af 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -809,7 +809,9 @@ RISC-V KENDRYTE
>  M:     Sean Anderson <seanga2 at gmail.com>
>  S:     Maintained
>  F:     doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt
> +F:     doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
>  F:     drivers/clk/kendryte/
> +F:     drivers/pinctrl/kendryte/
>  F:     include/kendryte/
>
>  RNG
> diff --git a/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt b/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
> new file mode 100644
> index 0000000000..299ce65304
> --- /dev/null
> +++ b/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt
> @@ -0,0 +1,116 @@
> +Kendryte K210 FPIOA
> +
> +This binding describes the Fully-Programmable Input/Output Array found on
> +Kendryte K210 SoCs. Any of the 256 functions can be mapped to any of the 48
> +pins.
> +
> +Required properties:
> +- compatible: should be "kendryte,k210-fpioa"
> +- reg: address and length of the FPIOA registers
> +- kendryte,sysctl: phandle to the "sysctl" register map node
> +- kendryte,power-offset: offset in the register map of the power bank control
> +  register (in bytes)
> +
> +Configuration nodes
> +
> +Pin configuration nodes are documented in pinctrl-bindings.txt
> +
> +Valid values for pins, groups, and function names:
> +
> +pins:
> +       "IO_X", where X is a number from 0 to 47.
> +
> +groups:
> +       A0, A1, A2, B0, B1, B2, C0, C1
> +
> +functions:
> +       JTAG_TCLK, JTAG_TDI, JTAG_TMS, JTAG_TDO, SPI0_D0, SPI0_D1, SPI0_D2,
> +       SPI0_D3, SPI0_D4, SPI0_D5, SPI0_D6, SPI0_D7, SPI0_SS0, SPI0_SS1,
> +       SPI0_SS2, SPI0_SS3, SPI0_ARB, SPI0_SCLK, UARTHS_RX, UARTHS_TX, RESV6,
> +       RESV7, CLK_SPI1, CLK_I2C1, GPIOHS0, GPIOHS1, GPIOHS2, GPIOHS3, GPIOHS4,
> +       GPIOHS5, GPIOHS6, GPIOHS7, GPIOHS8, GPIOHS9, GPIOHS10, GPIOHS11,
> +       GPIOHS12, GPIOHS13, GPIOHS14, GPIOHS15, GPIOHS16, GPIOHS17, GPIOHS18,
> +       GPIOHS19, GPIOHS20, GPIOHS21, GPIOHS22, GPIOHS23, GPIOHS24, GPIOHS25,
> +       GPIOHS26, GPIOHS27, GPIOHS28, GPIOHS29, GPIOHS30, GPIOHS31, GPIO0,
> +       GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, UART1_RX, UART1_TX,
> +       UART2_RX, UART2_TX, UART3_RX, UART3_TX, SPI1_D0, SPI1_D1, SPI1_D2,
> +       SPI1_D3, SPI1_D4, SPI1_D5, SPI1_D6, SPI1_D7, SPI1_SS0, SPI1_SS1,
> +       SPI1_SS2, SPI1_SS3, SPI1_ARB, SPI1_SCLK, SPI2_D0, SPI2_SS, SPI2_SCLK,
> +       I2S0_MCLK, I2S0_SCLK, I2S0_WS, I2S0_IN_D0, I2S0_IN_D1, I2S0_IN_D2,
> +       I2S0_IN_D3, I2S0_OUT_D0, I2S0_OUT_D1, I2S0_OUT_D2, I2S0_OUT_D3,
> +       I2S1_MCLK, I2S1_SCLK, I2S1_WS, I2S1_IN_D0, I2S1_IN_D1, I2S1_IN_D2,
> +       I2S1_IN_D3, I2S1_OUT_D0, I2S1_OUT_D1, I2S1_OUT_D2, I2S1_OUT_D3,
> +       I2S2_MCLK, I2S2_SCLK, I2S2_WS, I2S2_IN_D0, I2S2_IN_D1, I2S2_IN_D2,
> +       I2S2_IN_D3, I2S2_OUT_D0, I2S2_OUT_D1, I2S2_OUT_D2, I2S2_OUT_D3, RESV0,
> +       RESV1, RESV2, RESV3, RESV4, RESV5, I2C0_SCLK, I2C0_SDA, I2C1_SCLK,
> +       I2C1_SDA, I2C2_SCLK, I2C2_SDA, DVP_XCLK, DVP_RST, DVP_PWDN, DVP_VSYNC,
> +       DVP_HREF, DVP_PCLK, DVP_D0, DVP_D1, DVP_D2, DVP_D3, DVP_D4, DVP_D5,
> +       DVP_D6, DVP_D7, SCCB_SCLK, SCCB_SDA, UART1_CTS, UART1_DSR, UART1_DCD,
> +       UART1_RI, UART1_SIR_IN, UART1_DTR, UART1_RTS, UART1_OUT2, UART1_OUT1,
> +       UART1_SIR_OUT, UART1_BAUD, UART1_RE, UART1_DE, UART1_RS485_EN,
> +       UART2_CTS, UART2_DSR, UART2_DCD, UART2_RI, UART2_SIR_IN, UART2_DTR,
> +       UART2_RTS, UART2_OUT2, UART2_OUT1, UART2_SIR_OUT, UART2_BAUD, UART2_RE,
> +       UART2_DE, UART2_RS485_EN, UART3_CTS, UART3_DSR, UART3_DCD, UART3_RI,
> +       UART3_SIR_IN, UART3_DTR, UART3_RTS, UART3_OUT2, UART3_OUT1,
> +       UART3_SIR_OUT, UART3_BAUD, UART3_RE, UART3_DE, UART3_RS485_EN,
> +       TIMER0_TOGGLE1, TIMER0_TOGGLE2, TIMER0_TOGGLE3, TIMER0_TOGGLE4,
> +       TIMER1_TOGGLE1, TIMER1_TOGGLE2, TIMER1_TOGGLE3, TIMER1_TOGGLE4,
> +       TIMER2_TOGGLE1, TIMER2_TOGGLE2, TIMER2_TOGGLE3, TIMER2_TOGGLE4,
> +       CLK_SPI2, CLK_I2C2, INTERNAL0, INTERNAL1, INTERNAL2, INTERNAL3,
> +       INTERNAL4, INTERNAL5, INTERNAL6, INTERNAL7, INTERNAL8, INTERNAL9,
> +       INTERNAL10, INTERNAL11, INTERNAL12, INTERNAL13, INTERNAL14, INTERNAL15,
> +       INTERNAL16, INTERNAL17, CONSTANT, INTERNAL18, DEBUG0, DEBUG1, DEBUG2,
> +       DEBUG3, DEBUG4, DEBUG5, DEBUG6, DEBUG7, DEBUG8, DEBUG9, DEBUG10,
> +       DEBUG11, DEBUG12, DEBUG13, DEBUG14, DEBUG15, DEBUG16, DEBUG17, DEBUG18,
> +       DEBUG19, DEBUG20, DEBUG21, DEBUG22, DEBUG23, DEBUG24, DEBUG25, DEBUG26,
> +       DEBUG27, DEBUG28, DEBUG29, DEBUG30, DEBUG31
> +
> +Valid properties include:
> +       bias-disable, bias-pull-down, bias-pull-up, drive-strength,
> +       drive-strength-ua, input-enable, input-disable, input-schmitt-enable,
> +       input-schmitt-disable, power-source, output-low, output-high,
> +       output-enable, output-disable, slew-rate
> +
> +Notes on specific properties include:
> +- bias-pull-up, -down, and -pin-default: The pull strength cannot be configured.
> +- drive-strength: There are 8 drive strength settings between 11 and 50 mA
> +- power-source: Controls the output voltage of a bank of pins. Either
> +  K210_PC_POWER_1V8 or K210_PC_POWER_3V3 may be specified. This property cannot
> +  be specified for individual pins.
> +- slew-rate: Specifying this property reduces the slew rate
> +
> +Example:
> +fpioa: pinmux at 502B0000 {
> +       compatible = "kendryte,k210-fpioa";
> +       reg = <0x502B0000 0x100>;
> +       kendryte,sysctl = <&sysctl>;
> +       kendryte,power-offset = <K210_SYSCTL_POWER_SEL>;
> +
> +       fpioa_jtag: jtag {
> +               voltage {
> +                       group = "A0";
> +                       power-source = <K210_PC_POWER_3V3>;
> +               };
> +               tck {
> +                       function = "JTAG_TCLK";
> +                       pins = "IO_0";
> +               };
> +               tdi {
> +                       function = "JTAG_TDI";
> +                       pins = "IO_1";
> +               };
> +               tms {
> +                       function = "JTAG_TMS";
> +                       pins = "IO_2";
> +               };
> +               tdo {
> +                       function = "JTAG_TDO";
> +                       pins = "IO_3";
> +               };
> +       };
> +
> +       fpioa_isp: isp {
> +               function = "GPIOHS0";
> +               pins = "IO_16";
> +       };
> +};
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 83e39b9de3..9ec56c7735 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -289,6 +289,7 @@ endif
>  source "drivers/pinctrl/broadcom/Kconfig"
>  source "drivers/pinctrl/exynos/Kconfig"
>  source "drivers/pinctrl/intel/Kconfig"
> +source "drivers/pinctrl/kendryte/Kconfig"
>  source "drivers/pinctrl/mediatek/Kconfig"
>  source "drivers/pinctrl/meson/Kconfig"
>  source "drivers/pinctrl/mscc/Kconfig"
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index 4f662c4f6d..1fe66fed3c 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
>  obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
>  obj-$(CONFIG_PINCTRL_PIC32)    += pinctrl_pic32.o
>  obj-$(CONFIG_PINCTRL_EXYNOS)   += exynos/
> +obj-$(CONFIG_PINCTRL_K210)     += kendryte/
>  obj-$(CONFIG_PINCTRL_MESON)    += meson/
>  obj-$(CONFIG_PINCTRL_MTK)      += mediatek/
>  obj-$(CONFIG_PINCTRL_MSCC)     += mscc/
> diff --git a/drivers/pinctrl/kendryte/Kconfig b/drivers/pinctrl/kendryte/Kconfig
> new file mode 100644
> index 0000000000..6fc10e9516
> --- /dev/null
> +++ b/drivers/pinctrl/kendryte/Kconfig
> @@ -0,0 +1,7 @@
> +config PINCTRL_K210
> +       bool "Kendryte K210 Fully-Programmable Input/Output Array driver"
> +       depends on DM && PINCTRL_GENERIC
> +       help
> +         Support pin multiplexing on the K210. The "FPIOA" can remap any
> +         supported function to any multifunctional IO pin. It can also perform
> +         basic GPIO functions, such as reading the current value of a pin.
> diff --git a/drivers/pinctrl/kendryte/Makefile b/drivers/pinctrl/kendryte/Makefile
> new file mode 100644
> index 0000000000..1c10d7a929
> --- /dev/null
> +++ b/drivers/pinctrl/kendryte/Makefile
> @@ -0,0 +1 @@
> +obj-y += pinctrl.o
> diff --git a/drivers/pinctrl/kendryte/pinctrl.c b/drivers/pinctrl/kendryte/pinctrl.c
> new file mode 100644
> index 0000000000..3f7de0e706
> --- /dev/null
> +++ b/drivers/pinctrl/kendryte/pinctrl.c
> @@ -0,0 +1,663 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2020 Sean Anderson <seanga2 at gmail.com>
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dm/pinctrl.h>
> +#include <dt-bindings/pinctrl/k210-pinctrl.h>
> +#include <mapmem.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <linux/err.h>
> +#include "pinctrl.h"
> +
> +struct k210_pc_priv {
> +       struct clk clk;
> +       struct k210_fpioa __iomem *fpioa; /* FPIOA register */
> +       struct regmap *sysctl; /* Sysctl regmap */
> +       u32 power_offset; /* Power bank register offset */
> +};
> +
> +#define PIN(i) [i] = "IO_" #i
> +static const char k210_pc_pin_names[][6] = {
> +       PIN(0),
> +       PIN(1),
> +       PIN(2),
> +       PIN(3),
> +       PIN(4),
> +       PIN(5),
> +       PIN(6),
> +       PIN(7),
> +       PIN(8),
> +       PIN(9),
> +       PIN(10),
> +       PIN(11),
> +       PIN(12),
> +       PIN(13),
> +       PIN(14),
> +       PIN(15),
> +       PIN(16),
> +       PIN(17),
> +       PIN(18),
> +       PIN(19),
> +       PIN(20),
> +       PIN(21),
> +       PIN(22),
> +       PIN(23),
> +       PIN(24),
> +       PIN(25),
> +       PIN(26),
> +       PIN(27),
> +       PIN(28),
> +       PIN(29),
> +       PIN(30),
> +       PIN(31),
> +       PIN(32),
> +       PIN(33),
> +       PIN(34),
> +       PIN(35),
> +       PIN(36),
> +       PIN(37),
> +       PIN(38),
> +       PIN(39),
> +       PIN(40),
> +       PIN(41),
> +       PIN(42),
> +       PIN(43),
> +       PIN(44),
> +       PIN(45),
> +       PIN(46),
> +       PIN(47),
> +};
> +#undef PIN
> +
> +static int k210_pc_get_pins_count(struct udevice *dev)
> +{
> +       return ARRAY_SIZE(k210_pc_pin_names);
> +};
> +
> +static const char *k210_pc_get_pin_name(struct udevice *dev, unsigned selector)
> +{
> +       return k210_pc_pin_names[selector];
> +}
> +
> +/* These are just power domains */
> +static const char k210_pc_group_names[][3] = {
> +       [0] = "A0",
> +       [1] = "A1",
> +       [2] = "A2",
> +       [3] = "B0",
> +       [4] = "B1",
> +       [5] = "B2",
> +       [6] = "C0",
> +       [7] = "C1",
> +};
> +
> +static int k210_pc_get_groups_count(struct udevice *dev)
> +{
> +       return ARRAY_SIZE(k210_pc_group_names);
> +}
> +
> +static const char *k210_pc_get_group_name(struct udevice *dev,
> +                                         unsigned selector)
> +{
> +       return k210_pc_group_names[selector];
> +}
> +
> +enum k210_pc_mode_id {
> +       K210_PC_DEFAULT_DISABLED,
> +       K210_PC_DEFAULT_IN,
> +       K210_PC_DEFAULT_IN_TIE,
> +       K210_PC_DEFAULT_OUT,
> +       K210_PC_DEFAULT_I2C,
> +       K210_PC_DEFAULT_SPI,
> +       K210_PC_DEFAULT_GPIO,
> +       K210_PC_DEFAULT_INT13,
> +};
> +
> +#define DEFAULT(mode) [K210_PC_DEFAULT_##mode] = K210_PC_MODE_##mode
> +static const u32 k210_pc_mode_id_to_mode[] = {
> +       [K210_PC_DEFAULT_DISABLED] = 0,
> +       DEFAULT(IN),
> +       [K210_PC_DEFAULT_IN_TIE] = K210_PC_MODE_IN,
> +       DEFAULT(OUT),
> +       DEFAULT(I2C),
> +       DEFAULT(SPI),
> +       DEFAULT(GPIO),
> +       [K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
> +};
> +#undef DEFAULT
> +
> +/* This saves around 2K vs having a pointer+mode */
> +struct k210_pcf_info {
> +       char name[15];
> +       u8 mode_id;
> +};
> +
> +#define FUNC(id, mode) [K210_PCF_##id] = { \
> +       .name = #id, \
> +       .mode_id = K210_PC_DEFAULT_##mode \
> +}
> +static const struct k210_pcf_info k210_pcf_infos[] = {
> +       FUNC(JTAG_TCLK,      IN),
> +       FUNC(JTAG_TDI,       IN),
> +       FUNC(JTAG_TMS,       IN),
> +       FUNC(JTAG_TDO,       OUT),
> +       FUNC(SPI0_D0,        SPI),
> +       FUNC(SPI0_D1,        SPI),
> +       FUNC(SPI0_D2,        SPI),
> +       FUNC(SPI0_D3,        SPI),
> +       FUNC(SPI0_D4,        SPI),
> +       FUNC(SPI0_D5,        SPI),
> +       FUNC(SPI0_D6,        SPI),
> +       FUNC(SPI0_D7,        SPI),
> +       FUNC(SPI0_SS0,       OUT),
> +       FUNC(SPI0_SS1,       OUT),
> +       FUNC(SPI0_SS2,       OUT),
> +       FUNC(SPI0_SS3,       OUT),
> +       FUNC(SPI0_ARB,       IN_TIE),
> +       FUNC(SPI0_SCLK,      OUT),
> +       FUNC(UARTHS_RX,      IN),
> +       FUNC(UARTHS_TX,      OUT),
> +       FUNC(RESV6,          IN),
> +       FUNC(RESV7,          IN),
> +       FUNC(CLK_SPI1,       OUT),
> +       FUNC(CLK_I2C1,       OUT),
> +       FUNC(GPIOHS0,        GPIO),
> +       FUNC(GPIOHS1,        GPIO),
> +       FUNC(GPIOHS2,        GPIO),
> +       FUNC(GPIOHS3,        GPIO),
> +       FUNC(GPIOHS4,        GPIO),
> +       FUNC(GPIOHS5,        GPIO),
> +       FUNC(GPIOHS6,        GPIO),
> +       FUNC(GPIOHS7,        GPIO),
> +       FUNC(GPIOHS8,        GPIO),
> +       FUNC(GPIOHS9,        GPIO),
> +       FUNC(GPIOHS10,       GPIO),
> +       FUNC(GPIOHS11,       GPIO),
> +       FUNC(GPIOHS12,       GPIO),
> +       FUNC(GPIOHS13,       GPIO),
> +       FUNC(GPIOHS14,       GPIO),
> +       FUNC(GPIOHS15,       GPIO),
> +       FUNC(GPIOHS16,       GPIO),
> +       FUNC(GPIOHS17,       GPIO),
> +       FUNC(GPIOHS18,       GPIO),
> +       FUNC(GPIOHS19,       GPIO),
> +       FUNC(GPIOHS20,       GPIO),
> +       FUNC(GPIOHS21,       GPIO),
> +       FUNC(GPIOHS22,       GPIO),
> +       FUNC(GPIOHS23,       GPIO),
> +       FUNC(GPIOHS24,       GPIO),
> +       FUNC(GPIOHS25,       GPIO),
> +       FUNC(GPIOHS26,       GPIO),
> +       FUNC(GPIOHS27,       GPIO),
> +       FUNC(GPIOHS28,       GPIO),
> +       FUNC(GPIOHS29,       GPIO),
> +       FUNC(GPIOHS30,       GPIO),
> +       FUNC(GPIOHS31,       GPIO),
> +       FUNC(GPIO0,          GPIO),
> +       FUNC(GPIO1,          GPIO),
> +       FUNC(GPIO2,          GPIO),
> +       FUNC(GPIO3,          GPIO),
> +       FUNC(GPIO4,          GPIO),
> +       FUNC(GPIO5,          GPIO),
> +       FUNC(GPIO6,          GPIO),
> +       FUNC(GPIO7,          GPIO),
> +       FUNC(UART1_RX,       IN),
> +       FUNC(UART1_TX,       OUT),
> +       FUNC(UART2_RX,       IN),
> +       FUNC(UART2_TX,       OUT),
> +       FUNC(UART3_RX,       IN),
> +       FUNC(UART3_TX,       OUT),
> +       FUNC(SPI1_D0,        SPI),
> +       FUNC(SPI1_D1,        SPI),
> +       FUNC(SPI1_D2,        SPI),
> +       FUNC(SPI1_D3,        SPI),
> +       FUNC(SPI1_D4,        SPI),
> +       FUNC(SPI1_D5,        SPI),
> +       FUNC(SPI1_D6,        SPI),
> +       FUNC(SPI1_D7,        SPI),
> +       FUNC(SPI1_SS0,       OUT),
> +       FUNC(SPI1_SS1,       OUT),
> +       FUNC(SPI1_SS2,       OUT),
> +       FUNC(SPI1_SS3,       OUT),
> +       FUNC(SPI1_ARB,       IN_TIE),
> +       FUNC(SPI1_SCLK,      OUT),
> +       FUNC(SPI2_D0,        SPI),
> +       FUNC(SPI2_SS,        IN),
> +       FUNC(SPI2_SCLK,      IN),
> +       FUNC(I2S0_MCLK,      OUT),
> +       FUNC(I2S0_SCLK,      OUT),
> +       FUNC(I2S0_WS,        OUT),
> +       FUNC(I2S0_IN_D0,     IN),
> +       FUNC(I2S0_IN_D1,     IN),
> +       FUNC(I2S0_IN_D2,     IN),
> +       FUNC(I2S0_IN_D3,     IN),
> +       FUNC(I2S0_OUT_D0,    OUT),
> +       FUNC(I2S0_OUT_D1,    OUT),
> +       FUNC(I2S0_OUT_D2,    OUT),
> +       FUNC(I2S0_OUT_D3,    OUT),
> +       FUNC(I2S1_MCLK,      OUT),
> +       FUNC(I2S1_SCLK,      OUT),
> +       FUNC(I2S1_WS,        OUT),
> +       FUNC(I2S1_IN_D0,     IN),
> +       FUNC(I2S1_IN_D1,     IN),
> +       FUNC(I2S1_IN_D2,     IN),
> +       FUNC(I2S1_IN_D3,     IN),
> +       FUNC(I2S1_OUT_D0,    OUT),
> +       FUNC(I2S1_OUT_D1,    OUT),
> +       FUNC(I2S1_OUT_D2,    OUT),
> +       FUNC(I2S1_OUT_D3,    OUT),
> +       FUNC(I2S2_MCLK,      OUT),
> +       FUNC(I2S2_SCLK,      OUT),
> +       FUNC(I2S2_WS,        OUT),
> +       FUNC(I2S2_IN_D0,     IN),
> +       FUNC(I2S2_IN_D1,     IN),
> +       FUNC(I2S2_IN_D2,     IN),
> +       FUNC(I2S2_IN_D3,     IN),
> +       FUNC(I2S2_OUT_D0,    OUT),
> +       FUNC(I2S2_OUT_D1,    OUT),
> +       FUNC(I2S2_OUT_D2,    OUT),
> +       FUNC(I2S2_OUT_D3,    OUT),
> +       FUNC(RESV0,          DISABLED),
> +       FUNC(RESV1,          DISABLED),
> +       FUNC(RESV2,          DISABLED),
> +       FUNC(RESV3,          DISABLED),
> +       FUNC(RESV4,          DISABLED),
> +       FUNC(RESV5,          DISABLED),
> +       FUNC(I2C0_SCLK,      I2C),
> +       FUNC(I2C0_SDA,       I2C),
> +       FUNC(I2C1_SCLK,      I2C),
> +       FUNC(I2C1_SDA,       I2C),
> +       FUNC(I2C2_SCLK,      I2C),
> +       FUNC(I2C2_SDA,       I2C),
> +       FUNC(DVP_XCLK,       OUT),
> +       FUNC(DVP_RST,        OUT),
> +       FUNC(DVP_PWDN,       OUT),
> +       FUNC(DVP_VSYNC,      IN),
> +       FUNC(DVP_HREF,       IN),
> +       FUNC(DVP_PCLK,       IN),
> +       FUNC(DVP_D0,         IN),
> +       FUNC(DVP_D1,         IN),
> +       FUNC(DVP_D2,         IN),
> +       FUNC(DVP_D3,         IN),
> +       FUNC(DVP_D4,         IN),
> +       FUNC(DVP_D5,         IN),
> +       FUNC(DVP_D6,         IN),
> +       FUNC(DVP_D7,         IN),
> +       FUNC(SCCB_SCLK,      I2C),
> +       FUNC(SCCB_SDA,       I2C),
> +       FUNC(UART1_CTS,      IN),
> +       FUNC(UART1_DSR,      IN),
> +       FUNC(UART1_DCD,      IN),
> +       FUNC(UART1_RI,       IN),
> +       FUNC(UART1_SIR_IN,   IN),
> +       FUNC(UART1_DTR,      OUT),
> +       FUNC(UART1_RTS,      OUT),
> +       FUNC(UART1_OUT2,     OUT),
> +       FUNC(UART1_OUT1,     OUT),
> +       FUNC(UART1_SIR_OUT,  OUT),
> +       FUNC(UART1_BAUD,     OUT),
> +       FUNC(UART1_RE,       OUT),
> +       FUNC(UART1_DE,       OUT),
> +       FUNC(UART1_RS485_EN, OUT),
> +       FUNC(UART2_CTS,      IN),
> +       FUNC(UART2_DSR,      IN),
> +       FUNC(UART2_DCD,      IN),
> +       FUNC(UART2_RI,       IN),
> +       FUNC(UART2_SIR_IN,   IN),
> +       FUNC(UART2_DTR,      OUT),
> +       FUNC(UART2_RTS,      OUT),
> +       FUNC(UART2_OUT2,     OUT),
> +       FUNC(UART2_OUT1,     OUT),
> +       FUNC(UART2_SIR_OUT,  OUT),
> +       FUNC(UART2_BAUD,     OUT),
> +       FUNC(UART2_RE,       OUT),
> +       FUNC(UART2_DE,       OUT),
> +       FUNC(UART2_RS485_EN, OUT),
> +       FUNC(UART3_CTS,      IN),
> +       FUNC(UART3_DSR,      IN),
> +       FUNC(UART3_DCD,      IN),
> +       FUNC(UART3_RI,       IN),
> +       FUNC(UART3_SIR_IN,   IN),
> +       FUNC(UART3_DTR,      OUT),
> +       FUNC(UART3_RTS,      OUT),
> +       FUNC(UART3_OUT2,     OUT),
> +       FUNC(UART3_OUT1,     OUT),
> +       FUNC(UART3_SIR_OUT,  OUT),
> +       FUNC(UART3_BAUD,     OUT),
> +       FUNC(UART3_RE,       OUT),
> +       FUNC(UART3_DE,       OUT),
> +       FUNC(UART3_RS485_EN, OUT),
> +       FUNC(TIMER0_TOGGLE1, OUT),
> +       FUNC(TIMER0_TOGGLE2, OUT),
> +       FUNC(TIMER0_TOGGLE3, OUT),
> +       FUNC(TIMER0_TOGGLE4, OUT),
> +       FUNC(TIMER1_TOGGLE1, OUT),
> +       FUNC(TIMER1_TOGGLE2, OUT),
> +       FUNC(TIMER1_TOGGLE3, OUT),
> +       FUNC(TIMER1_TOGGLE4, OUT),
> +       FUNC(TIMER2_TOGGLE1, OUT),
> +       FUNC(TIMER2_TOGGLE2, OUT),
> +       FUNC(TIMER2_TOGGLE3, OUT),
> +       FUNC(TIMER2_TOGGLE4, OUT),
> +       FUNC(CLK_SPI2,       OUT),
> +       FUNC(CLK_I2C2,       OUT),
> +       FUNC(INTERNAL0,      OUT),
> +       FUNC(INTERNAL1,      OUT),
> +       FUNC(INTERNAL2,      OUT),
> +       FUNC(INTERNAL3,      OUT),
> +       FUNC(INTERNAL4,      OUT),
> +       FUNC(INTERNAL5,      OUT),
> +       FUNC(INTERNAL6,      OUT),
> +       FUNC(INTERNAL7,      OUT),
> +       FUNC(INTERNAL8,      OUT),
> +       FUNC(INTERNAL9,      IN),
> +       FUNC(INTERNAL10,     IN),
> +       FUNC(INTERNAL11,     IN),
> +       FUNC(INTERNAL12,     IN),
> +       FUNC(INTERNAL13,     INT13),
> +       FUNC(INTERNAL14,     I2C),
> +       FUNC(INTERNAL15,     IN),
> +       FUNC(INTERNAL16,     IN),
> +       FUNC(INTERNAL17,     IN),
> +       FUNC(CONSTANT,       DISABLED),
> +       FUNC(INTERNAL18,     IN),
> +       FUNC(DEBUG0,         OUT),
> +       FUNC(DEBUG1,         OUT),
> +       FUNC(DEBUG2,         OUT),
> +       FUNC(DEBUG3,         OUT),
> +       FUNC(DEBUG4,         OUT),
> +       FUNC(DEBUG5,         OUT),
> +       FUNC(DEBUG6,         OUT),
> +       FUNC(DEBUG7,         OUT),
> +       FUNC(DEBUG8,         OUT),
> +       FUNC(DEBUG9,         OUT),
> +       FUNC(DEBUG10,        OUT),
> +       FUNC(DEBUG11,        OUT),
> +       FUNC(DEBUG12,        OUT),
> +       FUNC(DEBUG13,        OUT),
> +       FUNC(DEBUG14,        OUT),
> +       FUNC(DEBUG15,        OUT),
> +       FUNC(DEBUG16,        OUT),
> +       FUNC(DEBUG17,        OUT),
> +       FUNC(DEBUG18,        OUT),
> +       FUNC(DEBUG19,        OUT),
> +       FUNC(DEBUG20,        OUT),
> +       FUNC(DEBUG21,        OUT),
> +       FUNC(DEBUG22,        OUT),
> +       FUNC(DEBUG23,        OUT),
> +       FUNC(DEBUG24,        OUT),
> +       FUNC(DEBUG25,        OUT),
> +       FUNC(DEBUG26,        OUT),
> +       FUNC(DEBUG27,        OUT),
> +       FUNC(DEBUG28,        OUT),
> +       FUNC(DEBUG29,        OUT),
> +       FUNC(DEBUG30,        OUT),
> +       FUNC(DEBUG31,        OUT),
> +};
> +#undef FUNC
> +
> +int k210_pc_get_functions_count(struct udevice *dev)
> +{
> +       return ARRAY_SIZE(k210_pcf_infos);
> +}
> +
> +static const char *k210_pc_get_function_name(struct udevice *dev,
> +                                            unsigned selector)
> +{
> +       return k210_pcf_infos[selector].name;
> +}
> +
> +static int k210_pc_pinmux_set(struct udevice *dev, unsigned pin_selector,
> +                             unsigned func_selector)
> +{
> +       struct k210_pc_priv *priv = dev_get_priv(dev);
> +       const struct k210_pcf_info *info = &k210_pcf_infos[func_selector];
> +       u32 mode = k210_pc_mode_id_to_mode[info->mode_id];
> +       u32 val = func_selector | mode;
> +
> +       log_debug("setting pin %s to %s with mode %.8x\n",
> +                 k210_pc_pin_names[pin_selector], info->name, mode);
> +       writel(val, &priv->fpioa->pins[pin_selector]);
> +       return 0;
> +}
> +
> +/* Max drive strength in uA */
> +static const int k210_pc_drive_strength[] = {
> +       [0] = 11200,
> +       [1] = 16800,
> +       [2] = 22300,
> +       [3] = 27800,
> +       [4] = 33300,
> +       [5] = 38700,
> +       [6] = 44100,
> +       [7] = 49500,
> +};
> +
> +static int k210_pc_get_drive(unsigned max_strength_ua)
> +{
> +       int i;
> +
> +       for (i = K210_PC_DRIVE_MAX; i; i--)
> +               if (k210_pc_drive_strength[i] < max_strength_ua)
> +                       return i;
> +
> +       return -EINVAL;
> +}
> +
> +static int k210_pc_pinconf_set(struct udevice *dev, unsigned pin_selector,
> +                              unsigned param, unsigned argument)
> +{
> +       struct k210_pc_priv *priv = dev_get_priv(dev);
> +       u32 val = readl(&priv->fpioa->pins[pin_selector]);
> +
> +       switch (param) {
> +       case PIN_CONFIG_BIAS_DISABLE:
> +               val &= ~K210_PC_BIAS_MASK;
> +               break;
> +       case PIN_CONFIG_BIAS_PULL_DOWN:
> +               if (argument)
> +                       val |= K210_PC_PD;
> +               else
> +                       return -EINVAL;
> +               break;
> +       case PIN_CONFIG_BIAS_PULL_UP:
> +               if (argument)
> +                       val |= K210_PC_PD;
> +               else
> +                       return -EINVAL;
> +               break;
> +       case PIN_CONFIG_DRIVE_STRENGTH:
> +               argument *= 1000;
> +       case PIN_CONFIG_DRIVE_STRENGTH_UA: {
> +               int drive = k210_pc_get_drive(argument);
> +
> +               if (IS_ERR_VALUE(drive))
> +                       return drive;
> +               val &= ~K210_PC_DRIVE_MASK;
> +               val |= FIELD_PREP(K210_PC_DRIVE_MASK, drive);
> +               break;
> +       }
> +       case PIN_CONFIG_INPUT_ENABLE:
> +               if (argument)
> +                       val |= K210_PC_IE;
> +               else
> +                       val &= ~K210_PC_IE;
> +               break;
> +       case PIN_CONFIG_INPUT_SCHMITT:
> +               argument = 1;
> +       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
> +               if (argument)
> +                       val |= K210_PC_ST;
> +               else
> +                       val &= ~K210_PC_ST;
> +               break;
> +       case PIN_CONFIG_OUTPUT:
> +               k210_pc_pinmux_set(dev, pin_selector, K210_PCF_CONSTANT);
> +               val = readl(&priv->fpioa->pins[pin_selector]);
> +               val |= K210_PC_MODE_OUT;
> +
> +               if (!argument)
> +                       val |= K210_PC_DO_INV;
> +               break;
> +       case PIN_CONFIG_OUTPUT_ENABLE:
> +               if (argument)
> +                       val |= K210_PC_OE;
> +               else
> +                       val &= ~K210_PC_OE;
> +               break;
> +       case PIN_CONFIG_SLEW_RATE:
> +               if (argument)
> +                       val |= K210_PC_SL;
> +               else
> +                       val &= ~K210_PC_SL;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       writel(val, &priv->fpioa->pins[pin_selector]);
> +       return 0;
> +}
> +
> +static int k210_pc_pinconf_group_set(struct udevice *dev,
> +                                    unsigned group_selector, unsigned param,
> +                                    unsigned argument)
> +{
> +       struct k210_pc_priv *priv = dev_get_priv(dev);
> +
> +       if (param == PIN_CONFIG_POWER_SOURCE) {
> +               u32 bit = BIT(group_selector);
> +
> +               regmap_update_bits(priv->sysctl, priv->power_offset, bit,
> +                                  argument ? bit : 0);
> +       } else {
> +               int i, ret;
> +
> +               for (i = 0; i < 6; i++) {
> +                       ret = k210_pc_pinconf_set(dev, group_selector * 6 + i,
> +                                                 param, argument);
> +                       if (ret)
> +                               return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int k210_pc_get_pin_muxing(struct udevice *dev, unsigned int selector,
> +                                 char *buf, int size)
> +{
> +       struct k210_pc_priv *priv = dev_get_priv(dev);
> +       u32 val = readl(&priv->fpioa->pins[selector]);
> +       const struct k210_pcf_info *info = &k210_pcf_infos[val & K210_PCF_MASK];
> +
> +       strncpy(buf, info->name, min((size_t)size, sizeof(info->name)));
> +       return 0;
> +}
> +
> +static const struct pinconf_param k210_pc_pinconf_params[] = {
> +       { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
> +       { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
> +       { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
> +       { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, U32_MAX },
> +       { "drive-strength-ua", PIN_CONFIG_DRIVE_STRENGTH_UA, U32_MAX },
> +       { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
> +       { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
> +       { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
> +       { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
> +       { "power-source", PIN_CONFIG_POWER_SOURCE, K210_PC_POWER_1V8 },
> +       { "output-low", PIN_CONFIG_OUTPUT, 0 },
> +       { "output-high", PIN_CONFIG_OUTPUT, 1 },
> +       { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
> +       { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
> +       { "slew-rate", PIN_CONFIG_SLEW_RATE, 1 },
> +};
> +
> +static const struct pinctrl_ops k210_pc_pinctrl_ops = {
> +       .get_pins_count = k210_pc_get_pins_count,
> +       .get_pin_name = k210_pc_get_pin_name,
> +       .get_groups_count = k210_pc_get_groups_count,
> +       .get_group_name = k210_pc_get_group_name,
> +       .get_functions_count = k210_pc_get_functions_count,
> +       .get_function_name = k210_pc_get_function_name,
> +       .pinmux_set = k210_pc_pinmux_set,
> +       .pinconf_num_params = ARRAY_SIZE(k210_pc_pinconf_params),
> +       .pinconf_params = k210_pc_pinconf_params,
> +       .pinconf_set = k210_pc_pinconf_set,
> +       .pinconf_group_set = k210_pc_pinconf_group_set,
> +       .set_state = pinctrl_generic_set_state,
> +       .get_pin_muxing = k210_pc_get_pin_muxing,
> +};
> +
> +static int k210_pc_probe(struct udevice *dev)
> +{
> +       int ret, i, j;
> +       struct k210_pc_priv *priv = dev_get_priv(dev);
> +
> +       priv->fpioa = dev_read_addr_ptr(dev);
> +       if (!priv->fpioa)
> +               return -EINVAL;
> +
> +       ret = clk_get_by_index(dev, 0, &priv->clk);
> +       if (ret)
> +               return ret;
> +
> +       ret = clk_enable(&priv->clk);
> +       if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
> +               goto err;
> +
> +       priv->sysctl = syscon_regmap_lookup_by_phandle(dev, "kendryte,sysctl");
> +       if (IS_ERR(priv->sysctl)) {
> +               ret = -ENODEV;
> +               goto err;
> +       }
> +
> +       ret = dev_read_u32(dev, "kendryte,power-offset", &priv->power_offset);
> +       if (ret)
> +               goto err;
> +
> +       log_debug("fpioa = %p sysctl = %p power offset = %x\n", priv->fpioa,
> +                 (void *)priv->sysctl->ranges[0].start, priv->power_offset);
> +
> +       /* Disable all pins */
> +       for (i = 6; i < ARRAY_SIZE(k210_pc_pin_names); i++)
> +               k210_pc_pinmux_set(dev, i, K210_PCF_CONSTANT);
> +
> +       /* Init input ties */
> +       for (i = 0; i < ARRAY_SIZE(priv->fpioa->tie_en); i++) {
> +               u32 val = 0;
> +
> +               for (j = 0; j < 32; j++)
> +                       if (k210_pcf_infos[i * 32 + j].mode_id ==
> +                           K210_PC_DEFAULT_IN_TIE)
> +                               val |= BIT(j);
> +               writel(val, &priv->fpioa->tie_en[i]);
> +               writel(val, &priv->fpioa->tie_val[i]);
> +       }
> +
> +       return 0;
> +
> +err:
> +       clk_free(&priv->clk);
> +       return ret;
> +}
> +
> +static const struct udevice_id k210_pc_ids[] = {
> +       { .compatible = "kendryte,k210-fpioa" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(pinctrl_k210) = {
> +       .name = "pinctrl_k210",
> +       .id = UCLASS_PINCTRL,
> +       .of_match = k210_pc_ids,
> +       .probe = k210_pc_probe,
> +       .priv_auto_alloc_size = sizeof(struct k210_pc_priv),
> +       .ops = &k210_pc_pinctrl_ops,
> +};
> diff --git a/drivers/pinctrl/kendryte/pinctrl.h b/drivers/pinctrl/kendryte/pinctrl.h
> new file mode 100644
> index 0000000000..de434700c3
> --- /dev/null
> +++ b/drivers/pinctrl/kendryte/pinctrl.h
> @@ -0,0 +1,325 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2020 Sean Anderson <seanga2 at gmail.com>
> + */
> +
> +#ifndef K210_PINCTRL_H
> +#define K210_PINCTRL_H
> +
> +#include <linux/bitfield.h>
> +
> +/*
> + * Full list of PinCtrl Functions from
> + * kendryte-standalone-sdk/lib/drivers/include/fpioa.h
> + */
> +#define K210_PCF_SHIFT 0
> +#define K210_PCF_MASK GENMASK(7, 0)
> +#define K210_PCF_JTAG_TCLK      0   /* JTAG Test Clock */
> +#define K210_PCF_JTAG_TDI       1   /* JTAG Test Data In */
> +#define K210_PCF_JTAG_TMS       2   /* JTAG Test Mode Select */
> +#define K210_PCF_JTAG_TDO       3   /* JTAG Test Data Out */
> +#define K210_PCF_SPI0_D0        4   /* SPI0 Data 0 */
> +#define K210_PCF_SPI0_D1        5   /* SPI0 Data 1 */
> +#define K210_PCF_SPI0_D2        6   /* SPI0 Data 2 */
> +#define K210_PCF_SPI0_D3        7   /* SPI0 Data 3 */
> +#define K210_PCF_SPI0_D4        8   /* SPI0 Data 4 */
> +#define K210_PCF_SPI0_D5        9   /* SPI0 Data 5 */
> +#define K210_PCF_SPI0_D6        10  /* SPI0 Data 6 */
> +#define K210_PCF_SPI0_D7        11  /* SPI0 Data 7 */
> +#define K210_PCF_SPI0_SS0       12  /* SPI0 Chip Select 0 */
> +#define K210_PCF_SPI0_SS1       13  /* SPI0 Chip Select 1 */
> +#define K210_PCF_SPI0_SS2       14  /* SPI0 Chip Select 2 */
> +#define K210_PCF_SPI0_SS3       15  /* SPI0 Chip Select 3 */
> +#define K210_PCF_SPI0_ARB       16  /* SPI0 Arbitration */
> +#define K210_PCF_SPI0_SCLK      17  /* SPI0 Serial Clock */
> +#define K210_PCF_UARTHS_RX      18  /* UART High speed Receiver */
> +#define K210_PCF_UARTHS_TX      19  /* UART High speed Transmitter */
> +#define K210_PCF_RESV6          20  /* Reserved function */
> +#define K210_PCF_RESV7          21  /* Reserved function */
> +#define K210_PCF_CLK_SPI1       22  /* Clock SPI1 */
> +#define K210_PCF_CLK_I2C1       23  /* Clock I2C1 */
> +#define K210_PCF_GPIOHS0        24  /* GPIO High speed 0 */
> +#define K210_PCF_GPIOHS1        25  /* GPIO High speed 1 */
> +#define K210_PCF_GPIOHS2        26  /* GPIO High speed 2 */
> +#define K210_PCF_GPIOHS3        27  /* GPIO High speed 3 */
> +#define K210_PCF_GPIOHS4        28  /* GPIO High speed 4 */
> +#define K210_PCF_GPIOHS5        29  /* GPIO High speed 5 */
> +#define K210_PCF_GPIOHS6        30  /* GPIO High speed 6 */
> +#define K210_PCF_GPIOHS7        31  /* GPIO High speed 7 */
> +#define K210_PCF_GPIOHS8        32  /* GPIO High speed 8 */
> +#define K210_PCF_GPIOHS9        33  /* GPIO High speed 9 */
> +#define K210_PCF_GPIOHS10       34  /* GPIO High speed 10 */
> +#define K210_PCF_GPIOHS11       35  /* GPIO High speed 11 */
> +#define K210_PCF_GPIOHS12       36  /* GPIO High speed 12 */
> +#define K210_PCF_GPIOHS13       37  /* GPIO High speed 13 */
> +#define K210_PCF_GPIOHS14       38  /* GPIO High speed 14 */
> +#define K210_PCF_GPIOHS15       39  /* GPIO High speed 15 */
> +#define K210_PCF_GPIOHS16       40  /* GPIO High speed 16 */
> +#define K210_PCF_GPIOHS17       41  /* GPIO High speed 17 */
> +#define K210_PCF_GPIOHS18       42  /* GPIO High speed 18 */
> +#define K210_PCF_GPIOHS19       43  /* GPIO High speed 19 */
> +#define K210_PCF_GPIOHS20       44  /* GPIO High speed 20 */
> +#define K210_PCF_GPIOHS21       45  /* GPIO High speed 21 */
> +#define K210_PCF_GPIOHS22       46  /* GPIO High speed 22 */
> +#define K210_PCF_GPIOHS23       47  /* GPIO High speed 23 */
> +#define K210_PCF_GPIOHS24       48  /* GPIO High speed 24 */
> +#define K210_PCF_GPIOHS25       49  /* GPIO High speed 25 */
> +#define K210_PCF_GPIOHS26       50  /* GPIO High speed 26 */
> +#define K210_PCF_GPIOHS27       51  /* GPIO High speed 27 */
> +#define K210_PCF_GPIOHS28       52  /* GPIO High speed 28 */
> +#define K210_PCF_GPIOHS29       53  /* GPIO High speed 29 */
> +#define K210_PCF_GPIOHS30       54  /* GPIO High speed 30 */
> +#define K210_PCF_GPIOHS31       55  /* GPIO High speed 31 */
> +#define K210_PCF_GPIO0          56  /* GPIO pin 0 */
> +#define K210_PCF_GPIO1          57  /* GPIO pin 1 */
> +#define K210_PCF_GPIO2          58  /* GPIO pin 2 */
> +#define K210_PCF_GPIO3          59  /* GPIO pin 3 */
> +#define K210_PCF_GPIO4          60  /* GPIO pin 4 */
> +#define K210_PCF_GPIO5          61  /* GPIO pin 5 */
> +#define K210_PCF_GPIO6          62  /* GPIO pin 6 */
> +#define K210_PCF_GPIO7          63  /* GPIO pin 7 */
> +#define K210_PCF_UART1_RX       64  /* UART1 Receiver */
> +#define K210_PCF_UART1_TX       65  /* UART1 Transmitter */
> +#define K210_PCF_UART2_RX       66  /* UART2 Receiver */
> +#define K210_PCF_UART2_TX       67  /* UART2 Transmitter */
> +#define K210_PCF_UART3_RX       68  /* UART3 Receiver */
> +#define K210_PCF_UART3_TX       69  /* UART3 Transmitter */
> +#define K210_PCF_SPI1_D0        70  /* SPI1 Data 0 */
> +#define K210_PCF_SPI1_D1        71  /* SPI1 Data 1 */
> +#define K210_PCF_SPI1_D2        72  /* SPI1 Data 2 */
> +#define K210_PCF_SPI1_D3        73  /* SPI1 Data 3 */
> +#define K210_PCF_SPI1_D4        74  /* SPI1 Data 4 */
> +#define K210_PCF_SPI1_D5        75  /* SPI1 Data 5 */
> +#define K210_PCF_SPI1_D6        76  /* SPI1 Data 6 */
> +#define K210_PCF_SPI1_D7        77  /* SPI1 Data 7 */
> +#define K210_PCF_SPI1_SS0       78  /* SPI1 Chip Select 0 */
> +#define K210_PCF_SPI1_SS1       79  /* SPI1 Chip Select 1 */
> +#define K210_PCF_SPI1_SS2       80  /* SPI1 Chip Select 2 */
> +#define K210_PCF_SPI1_SS3       81  /* SPI1 Chip Select 3 */
> +#define K210_PCF_SPI1_ARB       82  /* SPI1 Arbitration */
> +#define K210_PCF_SPI1_SCLK      83  /* SPI1 Serial Clock */
> +#define K210_PCF_SPI2_D0        84  /* SPI2 Data 0 */
> +#define K210_PCF_SPI2_SS        85  /* SPI2 Select */
> +#define K210_PCF_SPI2_SCLK      86  /* SPI2 Serial Clock */
> +#define K210_PCF_I2S0_MCLK      87  /* I2S0 Master Clock */
> +#define K210_PCF_I2S0_SCLK      88  /* I2S0 Serial Clock(BCLK) */
> +#define K210_PCF_I2S0_WS        89  /* I2S0 Word Select(LRCLK) */
> +#define K210_PCF_I2S0_IN_D0     90  /* I2S0 Serial Data Input 0 */
> +#define K210_PCF_I2S0_IN_D1     91  /* I2S0 Serial Data Input 1 */
> +#define K210_PCF_I2S0_IN_D2     92  /* I2S0 Serial Data Input 2 */
> +#define K210_PCF_I2S0_IN_D3     93  /* I2S0 Serial Data Input 3 */
> +#define K210_PCF_I2S0_OUT_D0    94  /* I2S0 Serial Data Output 0 */
> +#define K210_PCF_I2S0_OUT_D1    95  /* I2S0 Serial Data Output 1 */
> +#define K210_PCF_I2S0_OUT_D2    96  /* I2S0 Serial Data Output 2 */
> +#define K210_PCF_I2S0_OUT_D3    97  /* I2S0 Serial Data Output 3 */
> +#define K210_PCF_I2S1_MCLK      98  /* I2S1 Master Clock */
> +#define K210_PCF_I2S1_SCLK      99  /* I2S1 Serial Clock(BCLK) */
> +#define K210_PCF_I2S1_WS        100 /* I2S1 Word Select(LRCLK) */
> +#define K210_PCF_I2S1_IN_D0     101 /* I2S1 Serial Data Input 0 */
> +#define K210_PCF_I2S1_IN_D1     102 /* I2S1 Serial Data Input 1 */
> +#define K210_PCF_I2S1_IN_D2     103 /* I2S1 Serial Data Input 2 */
> +#define K210_PCF_I2S1_IN_D3     104 /* I2S1 Serial Data Input 3 */
> +#define K210_PCF_I2S1_OUT_D0    105 /* I2S1 Serial Data Output 0 */
> +#define K210_PCF_I2S1_OUT_D1    106 /* I2S1 Serial Data Output 1 */
> +#define K210_PCF_I2S1_OUT_D2    107 /* I2S1 Serial Data Output 2 */
> +#define K210_PCF_I2S1_OUT_D3    108 /* I2S1 Serial Data Output 3 */
> +#define K210_PCF_I2S2_MCLK      109 /* I2S2 Master Clock */
> +#define K210_PCF_I2S2_SCLK      110 /* I2S2 Serial Clock(BCLK) */
> +#define K210_PCF_I2S2_WS        111 /* I2S2 Word Select(LRCLK) */
> +#define K210_PCF_I2S2_IN_D0     112 /* I2S2 Serial Data Input 0 */
> +#define K210_PCF_I2S2_IN_D1     113 /* I2S2 Serial Data Input 1 */
> +#define K210_PCF_I2S2_IN_D2     114 /* I2S2 Serial Data Input 2 */
> +#define K210_PCF_I2S2_IN_D3     115 /* I2S2 Serial Data Input 3 */
> +#define K210_PCF_I2S2_OUT_D0    116 /* I2S2 Serial Data Output 0 */
> +#define K210_PCF_I2S2_OUT_D1    117 /* I2S2 Serial Data Output 1 */
> +#define K210_PCF_I2S2_OUT_D2    118 /* I2S2 Serial Data Output 2 */
> +#define K210_PCF_I2S2_OUT_D3    119 /* I2S2 Serial Data Output 3 */
> +#define K210_PCF_RESV0          120 /* Reserved function */
> +#define K210_PCF_RESV1          121 /* Reserved function */
> +#define K210_PCF_RESV2          122 /* Reserved function */
> +#define K210_PCF_RESV3          123 /* Reserved function */
> +#define K210_PCF_RESV4          124 /* Reserved function */
> +#define K210_PCF_RESV5          125 /* Reserved function */
> +#define K210_PCF_I2C0_SCLK      126 /* I2C0 Serial Clock */
> +#define K210_PCF_I2C0_SDA       127 /* I2C0 Serial Data */
> +#define K210_PCF_I2C1_SCLK      128 /* I2C1 Serial Clock */
> +#define K210_PCF_I2C1_SDA       129 /* I2C1 Serial Data */
> +#define K210_PCF_I2C2_SCLK      130 /* I2C2 Serial Clock */
> +#define K210_PCF_I2C2_SDA       131 /* I2C2 Serial Data */
> +#define K210_PCF_DVP_XCLK       132 /* DVP System Clock */
> +#define K210_PCF_DVP_RST        133 /* DVP System Reset */
> +#define K210_PCF_DVP_PWDN       134 /* DVP Power Down Mode */
> +#define K210_PCF_DVP_VSYNC      135 /* DVP Vertical Sync */
> +#define K210_PCF_DVP_HREF       136 /* DVP Horizontal Reference output */
> +#define K210_PCF_DVP_PCLK       137 /* Pixel Clock */
> +#define K210_PCF_DVP_D0         138 /* Data Bit 0 */
> +#define K210_PCF_DVP_D1         139 /* Data Bit 1 */
> +#define K210_PCF_DVP_D2         140 /* Data Bit 2 */
> +#define K210_PCF_DVP_D3         141 /* Data Bit 3 */
> +#define K210_PCF_DVP_D4         142 /* Data Bit 4 */
> +#define K210_PCF_DVP_D5         143 /* Data Bit 5 */
> +#define K210_PCF_DVP_D6         144 /* Data Bit 6 */
> +#define K210_PCF_DVP_D7         145 /* Data Bit 7 */
> +#define K210_PCF_SCCB_SCLK      146 /* Serial Camera Control Bus Clock */
> +#define K210_PCF_SCCB_SDA       147 /* Serial Camera Control Bus Data */
> +#define K210_PCF_UART1_CTS      148 /* UART1 Clear To Send */
> +#define K210_PCF_UART1_DSR      149 /* UART1 Data Set Ready */
> +#define K210_PCF_UART1_DCD      150 /* UART1 Data Carrier Detect */
> +#define K210_PCF_UART1_RI       151 /* UART1 Ring Indicator */
> +#define K210_PCF_UART1_SIR_IN   152 /* UART1 Serial Infrared Input */
> +#define K210_PCF_UART1_DTR      153 /* UART1 Data Terminal Ready */
> +#define K210_PCF_UART1_RTS      154 /* UART1 Request To Send */
> +#define K210_PCF_UART1_OUT2     155 /* UART1 User-designated Output 2 */
> +#define K210_PCF_UART1_OUT1     156 /* UART1 User-designated Output 1 */
> +#define K210_PCF_UART1_SIR_OUT  157 /* UART1 Serial Infrared Output */
> +#define K210_PCF_UART1_BAUD     158 /* UART1 Transmit Clock Output */
> +#define K210_PCF_UART1_RE       159 /* UART1 Receiver Output Enable */
> +#define K210_PCF_UART1_DE       160 /* UART1 Driver Output Enable */
> +#define K210_PCF_UART1_RS485_EN 161 /* UART1 RS485 Enable */
> +#define K210_PCF_UART2_CTS      162 /* UART2 Clear To Send */
> +#define K210_PCF_UART2_DSR      163 /* UART2 Data Set Ready */
> +#define K210_PCF_UART2_DCD      164 /* UART2 Data Carrier Detect */
> +#define K210_PCF_UART2_RI       165 /* UART2 Ring Indicator */
> +#define K210_PCF_UART2_SIR_IN   166 /* UART2 Serial Infrared Input */
> +#define K210_PCF_UART2_DTR      167 /* UART2 Data Terminal Ready */
> +#define K210_PCF_UART2_RTS      168 /* UART2 Request To Send */
> +#define K210_PCF_UART2_OUT2     169 /* UART2 User-designated Output 2 */
> +#define K210_PCF_UART2_OUT1     170 /* UART2 User-designated Output 1 */
> +#define K210_PCF_UART2_SIR_OUT  171 /* UART2 Serial Infrared Output */
> +#define K210_PCF_UART2_BAUD     172 /* UART2 Transmit Clock Output */
> +#define K210_PCF_UART2_RE       173 /* UART2 Receiver Output Enable */
> +#define K210_PCF_UART2_DE       174 /* UART2 Driver Output Enable */
> +#define K210_PCF_UART2_RS485_EN 175 /* UART2 RS485 Enable */
> +#define K210_PCF_UART3_CTS      176 /* UART3 Clear To Send */
> +#define K210_PCF_UART3_DSR      177 /* UART3 Data Set Ready */
> +#define K210_PCF_UART3_DCD      178 /* UART3 Data Carrier Detect */
> +#define K210_PCF_UART3_RI       179 /* UART3 Ring Indicator */
> +#define K210_PCF_UART3_SIR_IN   180 /* UART3 Serial Infrared Input */
> +#define K210_PCF_UART3_DTR      181 /* UART3 Data Terminal Ready */
> +#define K210_PCF_UART3_RTS      182 /* UART3 Request To Send */
> +#define K210_PCF_UART3_OUT2     183 /* UART3 User-designated Output 2 */
> +#define K210_PCF_UART3_OUT1     184 /* UART3 User-designated Output 1 */
> +#define K210_PCF_UART3_SIR_OUT  185 /* UART3 Serial Infrared Output */
> +#define K210_PCF_UART3_BAUD     186 /* UART3 Transmit Clock Output */
> +#define K210_PCF_UART3_RE       187 /* UART3 Receiver Output Enable */
> +#define K210_PCF_UART3_DE       188 /* UART3 Driver Output Enable */
> +#define K210_PCF_UART3_RS485_EN 189 /* UART3 RS485 Enable */
> +#define K210_PCF_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */
> +#define K210_PCF_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */
> +#define K210_PCF_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */
> +#define K210_PCF_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */
> +#define K210_PCF_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */
> +#define K210_PCF_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */
> +#define K210_PCF_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */
> +#define K210_PCF_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */
> +#define K210_PCF_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */
> +#define K210_PCF_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */
> +#define K210_PCF_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */
> +#define K210_PCF_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */
> +#define K210_PCF_CLK_SPI2       202 /* Clock SPI2 */
> +#define K210_PCF_CLK_I2C2       203 /* Clock I2C2 */
> +#define K210_PCF_INTERNAL0      204 /* Internal function signal 0 */
> +#define K210_PCF_INTERNAL1      205 /* Internal function signal 1 */
> +#define K210_PCF_INTERNAL2      206 /* Internal function signal 2 */
> +#define K210_PCF_INTERNAL3      207 /* Internal function signal 3 */
> +#define K210_PCF_INTERNAL4      208 /* Internal function signal 4 */
> +#define K210_PCF_INTERNAL5      209 /* Internal function signal 5 */
> +#define K210_PCF_INTERNAL6      210 /* Internal function signal 6 */
> +#define K210_PCF_INTERNAL7      211 /* Internal function signal 7 */
> +#define K210_PCF_INTERNAL8      212 /* Internal function signal 8 */
> +#define K210_PCF_INTERNAL9      213 /* Internal function signal 9 */
> +#define K210_PCF_INTERNAL10     214 /* Internal function signal 10 */
> +#define K210_PCF_INTERNAL11     215 /* Internal function signal 11 */
> +#define K210_PCF_INTERNAL12     216 /* Internal function signal 12 */
> +#define K210_PCF_INTERNAL13     217 /* Internal function signal 13 */
> +#define K210_PCF_INTERNAL14     218 /* Internal function signal 14 */
> +#define K210_PCF_INTERNAL15     219 /* Internal function signal 15 */
> +#define K210_PCF_INTERNAL16     220 /* Internal function signal 16 */
> +#define K210_PCF_INTERNAL17     221 /* Internal function signal 17 */
> +#define K210_PCF_CONSTANT       222 /* Constant function */
> +#define K210_PCF_INTERNAL18     223 /* Internal function signal 18 */
> +#define K210_PCF_DEBUG0         224 /* Debug function 0 */
> +#define K210_PCF_DEBUG1         225 /* Debug function 1 */
> +#define K210_PCF_DEBUG2         226 /* Debug function 2 */
> +#define K210_PCF_DEBUG3         227 /* Debug function 3 */
> +#define K210_PCF_DEBUG4         228 /* Debug function 4 */
> +#define K210_PCF_DEBUG5         229 /* Debug function 5 */
> +#define K210_PCF_DEBUG6         230 /* Debug function 6 */
> +#define K210_PCF_DEBUG7         231 /* Debug function 7 */
> +#define K210_PCF_DEBUG8         232 /* Debug function 8 */
> +#define K210_PCF_DEBUG9         233 /* Debug function 9 */
> +#define K210_PCF_DEBUG10        234 /* Debug function 10 */
> +#define K210_PCF_DEBUG11        235 /* Debug function 11 */
> +#define K210_PCF_DEBUG12        236 /* Debug function 12 */
> +#define K210_PCF_DEBUG13        237 /* Debug function 13 */
> +#define K210_PCF_DEBUG14        238 /* Debug function 14 */
> +#define K210_PCF_DEBUG15        239 /* Debug function 15 */
> +#define K210_PCF_DEBUG16        240 /* Debug function 16 */
> +#define K210_PCF_DEBUG17        241 /* Debug function 17 */
> +#define K210_PCF_DEBUG18        242 /* Debug function 18 */
> +#define K210_PCF_DEBUG19        243 /* Debug function 19 */
> +#define K210_PCF_DEBUG20        244 /* Debug function 20 */
> +#define K210_PCF_DEBUG21        245 /* Debug function 21 */
> +#define K210_PCF_DEBUG22        246 /* Debug function 22 */
> +#define K210_PCF_DEBUG23        247 /* Debug function 23 */
> +#define K210_PCF_DEBUG24        248 /* Debug function 24 */
> +#define K210_PCF_DEBUG25        249 /* Debug function 25 */
> +#define K210_PCF_DEBUG26        250 /* Debug function 26 */
> +#define K210_PCF_DEBUG27        251 /* Debug function 27 */
> +#define K210_PCF_DEBUG28        252 /* Debug function 28 */
> +#define K210_PCF_DEBUG29        253 /* Debug function 29 */
> +#define K210_PCF_DEBUG30        254 /* Debug function 30 */
> +#define K210_PCF_DEBUG31        255 /* Debug function 31 */
> +
> +/*
> + * The K210 only implements 8 drive levels, even though there is register space
> + * for 16
> + */
> +#define K210_PC_DRIVE_SHIFT 8
> +#define K210_PC_DRIVE_MASK GENMASK(11, 8)
> +#define K210_PC_DRIVE_0 (0 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_1 (1 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_2 (2 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_3 (3 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_4 (4 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_5 (5 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_6 (6 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_7 (7 << K210_PC_DRIVE_SHIFT)
> +#define K210_PC_DRIVE_MAX 7
> +
> +#define K210_PC_MODE_MASK GENMASK(23, 12)
> +/*
> + * output enabled == PC_OE & (PC_OE_INV ^ FUNCTION_OE) where FUNCTION_OE is a
> + * physical signal from the function
> + */
> +#define K210_PC_OE       BIT(12) /* Output Enable */
> +#define K210_PC_OE_INV   BIT(13) /* INVert function-controlled Output Enable */
> +#define K210_PC_DO_OE    BIT(14) /* set Data Out to the Output Enable signal */
> +#define K210_PC_DO_INV   BIT(15) /* INVert final Data Output */
> +#define K210_PC_PU       BIT(16) /* Pull Up */
> +#define K210_PC_PD       BIT(17) /* Pull Down */
> +/* Strong pull up not implemented on K210 */
> +#define K210_PC_SL       BIT(19) /* reduce SLew rate to prevent overshoot */
> +/* Same semantics as OE above */
> +#define K210_PC_IE       BIT(20) /* Input Enable */
> +#define K210_PC_IE_INV   BIT(21) /* INVert function-controlled Input Enable */
> +#define K210_PC_DI_INV   BIT(22) /* INVert Data Input */
> +#define K210_PC_ST       BIT(23) /* Schmitt Trigger */
> +#define K210_PC_DI       BIT(31) /* raw Data Input */
> +#define K210_PC_BIAS_MASK (K210_PC_PU & K210_PC_PD)
> +
> +#define K210_PC_MODE_IN   (K210_PC_IE | K210_PC_ST)
> +#define K210_PC_MODE_OUT  (K210_PC_DRIVE_7 | K210_PC_OE)
> +#define K210_PC_MODE_I2C  (K210_PC_MODE_IN | K210_PC_IE_INV | K210_PC_SL | \
> +                          K210_PC_OE | K210_PC_OE_INV | K210_PC_PU)
> +#define K210_PC_MODE_SPI  (K210_PC_MODE_IN | K210_PC_IE_INV | \
> +                          K210_PC_MODE_OUT | K210_PC_OE_INV)
> +#define K210_PC_MODE_GPIO (K210_PC_MODE_IN | K210_PC_MODE_OUT)
> +
> +struct k210_fpioa {
> +       u32 pins[48];
> +       u32 tie_en[8];
> +       u32 tie_val[8];
> +};
> +
> +#endif /* K210_PINCTRL_H */
> diff --git a/include/dt-bindings/pinctrl/k210-pinctrl.h b/include/dt-bindings/pinctrl/k210-pinctrl.h
> new file mode 100644
> index 0000000000..6d44ea765b
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/k210-pinctrl.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2020 Sean Anderson <seanga2 at gmail.com>
> + */
> +
> +#ifndef DT_K210_PINCTRL_H
> +#define DT_K210_PINCTRL_H
> +
> +#define K210_PC_POWER_3V3 0
> +#define K210_PC_POWER_1V8 1
> +
> +#endif /* DT_K210_PINCTRL_H */
> --
> 2.25.0
>


More information about the U-Boot mailing list