diff --git a/arch/risc-v/include/eic7700x/eic7700x_pinctrl.h b/arch/risc-v/include/eic7700x/eic7700x_pinctrl.h new file mode 100644 index 0000000000000..ee3e51c757c80 --- /dev/null +++ b/arch/risc-v/include/eic7700x/eic7700x_pinctrl.h @@ -0,0 +1,662 @@ +/**************************************************************************** + * arch/risc-v/include/eic7700x/eic7700x_pinctrl.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_EIC7700X_EIC7700X_PINCTRL_H +#define __ARCH_RISCV_INCLUDE_EIC7700X_EIC7700X_PINCTRL_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Every pad of the Chip Level Mode Mux, in register order. + * + * The pad registers are contiguous, so a pad id is simply the register + * index and the address falls out of it. The names are the manual's own, + * taken from the register detail description in TRM part 4 section 12.1.2.2 + * pages 371 to 410, which means a name describes the pad's default function + * rather than whatever it has been muxed to. EIC7700X_PAD_UART0_TX is the + * pad that comes up as UART0 TX, not a pad that is necessarily still UART. + * + * Eight registers the manual leaves as RESERVED are numbered in offset + * order. They are real registers with real reset values, so they are + * carried here rather than left as holes; the pad table records that their + * function select cannot be driven. + * + * Two balls in part 1 table 2-4 have no register in this range at all, + * GPIO5 and GPIO11, so they have no pad id. See the note on the reverse + * map in eic7700x_pinctrl.c. + */ + +#define EIC7700X_PAD_NPADS (166) +#define EIC7700X_PAD_OFFSET(id) (0x0080 + ((id) << 2)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum eic7700x_pad_e +{ + /* Chip mode, straps and the oscillator pads */ + + EIC7700X_PAD_CHIP_MODE = 0, /* 0x080 */ + EIC7700X_PAD_MODE_SET0 = 1, /* 0x084 */ + EIC7700X_PAD_MODE_SET1 = 2, /* 0x088 */ + EIC7700X_PAD_MODE_SET2 = 3, /* 0x08c */ + EIC7700X_PAD_MODE_SET3 = 4, /* 0x090 */ + EIC7700X_PAD_XIN = 5, /* 0x094 */ + EIC7700X_PAD_RESERVED0 = 6, /* 0x098 */ + EIC7700X_PAD_RST_OUT_N = 7, /* 0x09c */ + EIC7700X_PAD_KEY_RESET_N = 8, /* 0x0a0 */ + EIC7700X_PAD_RESERVED1 = 9, /* 0x0a4 */ + EIC7700X_PAD_RESERVED2 = 10, /* 0x0a8 */ + EIC7700X_PAD_RESERVED3 = 11, /* 0x0ac */ + EIC7700X_PAD_GPIO0 = 12, /* 0x0b0 */ + EIC7700X_PAD_POR_SEL = 13, /* 0x0b4 */ + + /* JTAG, SPI2 chip selects, PCIe control and HDMI */ + + EIC7700X_PAD_JTAG0_TCK = 14, /* 0x0b8 */ + EIC7700X_PAD_JTAG0_TMS = 15, /* 0x0bc */ + EIC7700X_PAD_JTAG0_TDI = 16, /* 0x0c0 */ + EIC7700X_PAD_JTAG0_TDO = 17, /* 0x0c4 */ + EIC7700X_PAD_JTAG0_TRST = 18, /* 0x0c8 */ + EIC7700X_PAD_SPI2_CS0_N = 19, /* 0x0cc */ + EIC7700X_PAD_JTAG1_TCK = 20, /* 0x0d0 */ + EIC7700X_PAD_JTAG1_TMS = 21, /* 0x0d4 */ + EIC7700X_PAD_JTAG1_TDI = 22, /* 0x0d8 */ + EIC7700X_PAD_JTAG1_TDO = 23, /* 0x0dc */ + EIC7700X_PAD_JTAG1_TRST = 24, /* 0x0e0 */ + EIC7700X_PAD_SPI2_CS1_N = 25, /* 0x0e4 */ + EIC7700X_PAD_PCIE_CLKREQ_N = 26, /* 0x0e8 */ + EIC7700X_PAD_PCIE_WAKE_N = 27, /* 0x0ec */ + EIC7700X_PAD_PCIE_PERST_N = 28, /* 0x0f0 */ + EIC7700X_PAD_HDMI_SCL = 29, /* 0x0f4 */ + EIC7700X_PAD_HDMI_SDA = 30, /* 0x0f8 */ + EIC7700X_PAD_HDMI_CEC = 31, /* 0x0fc */ + EIC7700X_PAD_JTAG2_TRST = 32, /* 0x100 */ + + /* Gigabit Ethernet, I2S, SPI1 and the dedicated GPIO pads */ + + EIC7700X_PAD_RGMII0_CLK_125 = 33, /* 0x104 */ + EIC7700X_PAD_RGMII0_TXEN = 34, /* 0x108 */ + EIC7700X_PAD_RGMII0_TXCLK = 35, /* 0x10c */ + EIC7700X_PAD_RGMII0_TXD0 = 36, /* 0x110 */ + EIC7700X_PAD_RGMII0_TXD1 = 37, /* 0x114 */ + EIC7700X_PAD_RGMII0_TXD2 = 38, /* 0x118 */ + EIC7700X_PAD_RGMII0_TXD3 = 39, /* 0x11c */ + EIC7700X_PAD_I2S0_BCLK = 40, /* 0x120 */ + EIC7700X_PAD_I2S0_WCLK = 41, /* 0x124 */ + EIC7700X_PAD_I2S0_SDI = 42, /* 0x128 */ + EIC7700X_PAD_I2S0_SDO = 43, /* 0x12c */ + EIC7700X_PAD_I2S_MCLK = 44, /* 0x130 */ + EIC7700X_PAD_RGMII0_RXCLK = 45, /* 0x134 */ + EIC7700X_PAD_RGMII0_RXDV = 46, /* 0x138 */ + EIC7700X_PAD_RGMII0_RXD0 = 47, /* 0x13c */ + EIC7700X_PAD_RGMII0_RXD1 = 48, /* 0x140 */ + EIC7700X_PAD_RGMII0_RXD2 = 49, /* 0x144 */ + EIC7700X_PAD_RGMII0_RXD3 = 50, /* 0x148 */ + EIC7700X_PAD_I2S2_BCLK = 51, /* 0x14c */ + EIC7700X_PAD_I2S2_WCLK = 52, /* 0x150 */ + EIC7700X_PAD_I2S2_SDI = 53, /* 0x154 */ + EIC7700X_PAD_I2S2_SDO = 54, /* 0x158 */ + EIC7700X_PAD_GPIO27 = 55, /* 0x15c */ + EIC7700X_PAD_GPIO28 = 56, /* 0x160 */ + EIC7700X_PAD_GPIO29 = 57, /* 0x164 */ + EIC7700X_PAD_RGMII0_MDC = 58, /* 0x168 */ + EIC7700X_PAD_RGMII0_MDIO = 59, /* 0x16c */ + EIC7700X_PAD_RGMII0_INTB = 60, /* 0x170 */ + EIC7700X_PAD_RGMII1_CLK_125 = 61, /* 0x174 */ + EIC7700X_PAD_RGMII1_TXEN = 62, /* 0x178 */ + EIC7700X_PAD_RGMII1_TXCLK = 63, /* 0x17c */ + EIC7700X_PAD_RGMII1_TXD0 = 64, /* 0x180 */ + EIC7700X_PAD_RGMII1_TXD1 = 65, /* 0x184 */ + EIC7700X_PAD_RGMII1_TXD2 = 66, /* 0x188 */ + EIC7700X_PAD_RGMII1_TXD3 = 67, /* 0x18c */ + EIC7700X_PAD_I2S1_BCLK = 68, /* 0x190 */ + EIC7700X_PAD_I2S1_WCLK = 69, /* 0x194 */ + EIC7700X_PAD_I2S1_SDI = 70, /* 0x198 */ + EIC7700X_PAD_I2S1_SDO = 71, /* 0x19c */ + EIC7700X_PAD_GPIO34 = 72, /* 0x1a0 */ + EIC7700X_PAD_RGMII1_RXCLK = 73, /* 0x1a4 */ + EIC7700X_PAD_RGMII1_RXDV = 74, /* 0x1a8 */ + EIC7700X_PAD_RGMII1_RXD0 = 75, /* 0x1ac */ + EIC7700X_PAD_RGMII1_RXD1 = 76, /* 0x1b0 */ + EIC7700X_PAD_RGMII1_RXD2 = 77, /* 0x1b4 */ + EIC7700X_PAD_RGMII1_RXD3 = 78, /* 0x1b8 */ + EIC7700X_PAD_SPI1_CS0_N = 79, /* 0x1bc */ + EIC7700X_PAD_SPI1_CLK = 80, /* 0x1c0 */ + EIC7700X_PAD_SPI1_D0 = 81, /* 0x1c4 */ + EIC7700X_PAD_SPI1_D1 = 82, /* 0x1c8 */ + EIC7700X_PAD_SPI1_D2 = 83, /* 0x1cc */ + EIC7700X_PAD_SPI1_D3 = 84, /* 0x1d0 */ + EIC7700X_PAD_SPI1_CS1_N = 85, /* 0x1d4 */ + EIC7700X_PAD_RGMII1_MDC = 86, /* 0x1d8 */ + EIC7700X_PAD_RGMII1_MDIO = 87, /* 0x1dc */ + EIC7700X_PAD_RGMII1_INTB = 88, /* 0x1e0 */ + + /* USB power, I2C 0-5, UART 0-2, JTAG2 and the fan */ + + EIC7700X_PAD_USB0_PWREN = 89, /* 0x1e4 */ + EIC7700X_PAD_USB1_PWREN = 90, /* 0x1e8 */ + EIC7700X_PAD_I2C0_SCL = 91, /* 0x1ec */ + EIC7700X_PAD_I2C0_SDA = 92, /* 0x1f0 */ + EIC7700X_PAD_I2C1_SCL = 93, /* 0x1f4 */ + EIC7700X_PAD_I2C1_SDA = 94, /* 0x1f8 */ + EIC7700X_PAD_I2C2_SCL = 95, /* 0x1fc */ + EIC7700X_PAD_I2C2_SDA = 96, /* 0x200 */ + EIC7700X_PAD_I2C3_SCL = 97, /* 0x204 */ + EIC7700X_PAD_I2C3_SDA = 98, /* 0x208 */ + EIC7700X_PAD_I2C4_SCL = 99, /* 0x20c */ + EIC7700X_PAD_I2C4_SDA = 100, /* 0x210 */ + EIC7700X_PAD_I2C5_SCL = 101, /* 0x214 */ + EIC7700X_PAD_I2C5_SDA = 102, /* 0x218 */ + EIC7700X_PAD_UART0_TX = 103, /* 0x21c */ + EIC7700X_PAD_UART0_RX = 104, /* 0x220 */ + EIC7700X_PAD_UART1_TX = 105, /* 0x224 */ + EIC7700X_PAD_UART1_RX = 106, /* 0x228 */ + EIC7700X_PAD_UART1_CTS = 107, /* 0x22c */ + EIC7700X_PAD_UART1_RTS = 108, /* 0x230 */ + EIC7700X_PAD_UART2_TX = 109, /* 0x234 */ + EIC7700X_PAD_UART2_RX = 110, /* 0x238 */ + EIC7700X_PAD_JTAG2_TCK = 111, /* 0x23c */ + EIC7700X_PAD_JTAG2_TMS = 112, /* 0x240 */ + EIC7700X_PAD_JTAG2_TDI = 113, /* 0x244 */ + EIC7700X_PAD_JTAG2_TDO = 114, /* 0x248 */ + EIC7700X_PAD_FAN_PWM = 115, /* 0x24c */ + EIC7700X_PAD_FAN_TACH = 116, /* 0x250 */ + + /* MIPI CSI camera sync and clock */ + + EIC7700X_PAD_MIPI_CSI0_XVS = 117, /* 0x254 */ + EIC7700X_PAD_MIPI_CSI0_XHS = 118, /* 0x258 */ + EIC7700X_PAD_MIPI_CSI0_MCLK = 119, /* 0x25c */ + EIC7700X_PAD_MIPI_CSI1_XVS = 120, /* 0x260 */ + EIC7700X_PAD_MIPI_CSI1_XHS = 121, /* 0x264 */ + EIC7700X_PAD_MIPI_CSI1_MCLK = 122, /* 0x268 */ + EIC7700X_PAD_MIPI_CSI2_XVS = 123, /* 0x26c */ + EIC7700X_PAD_MIPI_CSI2_XHS = 124, /* 0x270 */ + EIC7700X_PAD_MIPI_CSI2_MCLK = 125, /* 0x274 */ + EIC7700X_PAD_MIPI_CSI3_XVS = 126, /* 0x278 */ + EIC7700X_PAD_MIPI_CSI3_XHS = 127, /* 0x27c */ + EIC7700X_PAD_MIPI_CSI3_MCLK = 128, /* 0x280 */ + EIC7700X_PAD_MIPI_CSI4_XVS = 129, /* 0x284 */ + EIC7700X_PAD_MIPI_CSI4_XHS = 130, /* 0x288 */ + EIC7700X_PAD_MIPI_CSI4_MCLK = 131, /* 0x28c */ + EIC7700X_PAD_MIPI_CSI5_XVS = 132, /* 0x290 */ + EIC7700X_PAD_MIPI_CSI5_XHS = 133, /* 0x294 */ + EIC7700X_PAD_MIPI_CSI5_MCLK = 134, /* 0x298 */ + + /* SPI3, SPI0, I2C 10-11 and more dedicated GPIO */ + + EIC7700X_PAD_SPI3_CS_N = 135, /* 0x29c */ + EIC7700X_PAD_SPI3_CLK = 136, /* 0x2a0 */ + EIC7700X_PAD_SPI3_DI = 137, /* 0x2a4 */ + EIC7700X_PAD_SPI3_DO = 138, /* 0x2a8 */ + EIC7700X_PAD_GPIO92 = 139, /* 0x2ac */ + EIC7700X_PAD_GPIO93 = 140, /* 0x2b0 */ + EIC7700X_PAD_S_MODE = 141, /* 0x2b4 */ + EIC7700X_PAD_GPIO95 = 142, /* 0x2b8 */ + EIC7700X_PAD_SPI0_CS_N = 143, /* 0x2bc */ + EIC7700X_PAD_SPI0_CLK = 144, /* 0x2c0 */ + EIC7700X_PAD_SPI0_D0 = 145, /* 0x2c4 */ + EIC7700X_PAD_SPI0_D1 = 146, /* 0x2c8 */ + EIC7700X_PAD_SPI0_D2 = 147, /* 0x2cc */ + EIC7700X_PAD_SPI0_D3 = 148, /* 0x2d0 */ + EIC7700X_PAD_I2C10_SCL = 149, /* 0x2d4 */ + EIC7700X_PAD_I2C10_SDA = 150, /* 0x2d8 */ + EIC7700X_PAD_I2C11_SCL = 151, /* 0x2dc */ + EIC7700X_PAD_I2C11_SDA = 152, /* 0x2e0 */ + EIC7700X_PAD_GPIO106 = 153, /* 0x2e4 */ + + /* Boot select, reserved pads and the RGMII voltage mode */ + + EIC7700X_PAD_BOOT_SEL0 = 154, /* 0x2e8 */ + EIC7700X_PAD_BOOT_SEL1 = 155, /* 0x2ec */ + EIC7700X_PAD_BOOT_SEL2 = 156, /* 0x2f0 */ + EIC7700X_PAD_BOOT_SEL3 = 157, /* 0x2f4 */ + EIC7700X_PAD_GPIO111 = 158, /* 0x2f8 */ + EIC7700X_PAD_RESERVED4 = 159, /* 0x2fc */ + EIC7700X_PAD_RESERVED5 = 160, /* 0x300 */ + EIC7700X_PAD_RESERVED6 = 161, /* 0x304 */ + EIC7700X_PAD_RESERVED7 = 162, /* 0x308 */ + EIC7700X_PAD_LPDDR_REF_CLK = 163, /* 0x30c */ + EIC7700X_PAD_ADDR_RGMII0_SEL_MODE = 164, /* 0x310 */ + EIC7700X_PAD_ADDR_RGMII1_SEL_MODE = 165, /* 0x314 */ +}; + +/* What each pad's function select selects, from part 1 table 2-4. + * + * A pad only accepts the values named here; the write path refuses any + * other, even where the hardware would take it. The names are the + * manual's, so a constant reads as the signal that appears on the ball. + */ + +/* Straps, oscillator, JTAG0 and JTAG1, SPI2 selects, PCIe, HDMI */ + +#define EIC7700X_PAD_CHIP_MODE_FUNC_CHIP_MODE 0 + +#define EIC7700X_PAD_MODE_SET0_FUNC_SDIO0_DETECT 0 +#define EIC7700X_PAD_MODE_SET0_FUNC_GPIO13 2 + +#define EIC7700X_PAD_MODE_SET1_FUNC_SDIO0_WRITE_PROT 0 +#define EIC7700X_PAD_MODE_SET1_FUNC_GPIO14 2 + +#define EIC7700X_PAD_MODE_SET2_FUNC_SDIO1_DETECT 0 +#define EIC7700X_PAD_MODE_SET2_FUNC_GPIO15 2 + +#define EIC7700X_PAD_MODE_SET3_FUNC_SDIO1_WRITE_PROT 0 +#define EIC7700X_PAD_MODE_SET3_FUNC_GPIO16 2 + +#define EIC7700X_PAD_XIN_FUNC_XIN_24M 0 +#define EIC7700X_PAD_RESERVED0_FUNC_XOUT_24M 0 +#define EIC7700X_PAD_RST_OUT_N_FUNC_RST_OUT_N 0 +#define EIC7700X_PAD_KEY_RESET_N_FUNC_KEY_RESET_N 0 +#define EIC7700X_PAD_GPIO0_FUNC_GPIO0 0 +#define EIC7700X_PAD_POR_SEL_FUNC_POR_SEL 0 + +#define EIC7700X_PAD_JTAG0_TCK_FUNC_JTAG0_TCK 0 +#define EIC7700X_PAD_JTAG0_TCK_FUNC_SPI2_CLK 1 +#define EIC7700X_PAD_JTAG0_TCK_FUNC_GPIO1 2 + +#define EIC7700X_PAD_JTAG0_TMS_FUNC_JTAG0_TMS 0 +#define EIC7700X_PAD_JTAG0_TMS_FUNC_SPI2_D0 1 +#define EIC7700X_PAD_JTAG0_TMS_FUNC_GPIO2 2 + +#define EIC7700X_PAD_JTAG0_TDI_FUNC_JTAG0_TDI 0 +#define EIC7700X_PAD_JTAG0_TDI_FUNC_SPI2_D1 1 +#define EIC7700X_PAD_JTAG0_TDI_FUNC_GPIO3 2 + +#define EIC7700X_PAD_JTAG0_TDO_FUNC_JTAG0_TDO 0 +#define EIC7700X_PAD_JTAG0_TDO_FUNC_SPI2_D2 1 +#define EIC7700X_PAD_JTAG0_TDO_FUNC_GPIO4 2 + +#define EIC7700X_PAD_SPI2_CS0_N_FUNC_SPI2_CS0_N 0 +#define EIC7700X_PAD_SPI2_CS0_N_FUNC_GPIO6 2 + +#define EIC7700X_PAD_JTAG1_TCK_FUNC_JTAG1_TCK 0 +#define EIC7700X_PAD_JTAG1_TCK_FUNC_GPIO7 2 + +#define EIC7700X_PAD_JTAG1_TMS_FUNC_JTAG1_TMS 0 +#define EIC7700X_PAD_JTAG1_TMS_FUNC_GPIO8 2 + +#define EIC7700X_PAD_JTAG1_TDI_FUNC_JTAG1_TDI 0 +#define EIC7700X_PAD_JTAG1_TDI_FUNC_GPIO9 2 + +#define EIC7700X_PAD_JTAG1_TDO_FUNC_JTAG1_TDO 0 +#define EIC7700X_PAD_JTAG1_TDO_FUNC_GPIO10 2 + +#define EIC7700X_PAD_SPI2_CS1_N_FUNC_SPI2_CS1_N 0 +#define EIC7700X_PAD_SPI2_CS1_N_FUNC_GPIO12 2 + +#define EIC7700X_PAD_PCIE_CLKREQ_N_FUNC_PCIE_CLKREQ_N 0 +#define EIC7700X_PAD_PCIE_WAKE_N_FUNC_PCIE_WAKE_N 0 +#define EIC7700X_PAD_PCIE_PERST_N_FUNC_PCIE_PERST_N 0 +#define EIC7700X_PAD_HDMI_SCL_FUNC_HDMI_SCL 0 +#define EIC7700X_PAD_HDMI_SDA_FUNC_HDMI_SDA 0 +#define EIC7700X_PAD_HDMI_CEC_FUNC_HDMI_CEC 0 + +#define EIC7700X_PAD_JTAG2_TRST_FUNC_JTAG2_TRST 0 +#define EIC7700X_PAD_JTAG2_TRST_FUNC_GPIO17 2 + +/* Gigabit Ethernet, I2S, SPI1 and the dedicated GPIO pads */ + +#define EIC7700X_PAD_RGMII0_CLK_125_FUNC_RGMII0_CLK_125 0 +#define EIC7700X_PAD_RGMII0_TXEN_FUNC_RGMII0_TXEN 0 +#define EIC7700X_PAD_RGMII0_TXCLK_FUNC_RGMII0_TXCLK 0 +#define EIC7700X_PAD_RGMII0_TXD0_FUNC_RGMII0_TXD0 0 +#define EIC7700X_PAD_RGMII0_TXD1_FUNC_RGMII0_TXD1 0 +#define EIC7700X_PAD_RGMII0_TXD2_FUNC_RGMII0_TXD2 0 +#define EIC7700X_PAD_RGMII0_TXD3_FUNC_RGMII0_TXD3 0 + +#define EIC7700X_PAD_I2S0_BCLK_FUNC_I2S0_BCLK 0 +#define EIC7700X_PAD_I2S0_BCLK_FUNC_GPIO18 2 + +#define EIC7700X_PAD_I2S0_WCLK_FUNC_I2S0_WCLK 0 +#define EIC7700X_PAD_I2S0_WCLK_FUNC_GPIO19 2 + +#define EIC7700X_PAD_I2S0_SDI_FUNC_I2S0_SDI 0 +#define EIC7700X_PAD_I2S0_SDI_FUNC_GPIO20 2 + +#define EIC7700X_PAD_I2S0_SDO_FUNC_I2S0_SDO 0 +#define EIC7700X_PAD_I2S0_SDO_FUNC_GPIO21 2 + +#define EIC7700X_PAD_I2S_MCLK_FUNC_I2S_MCLK 0 +#define EIC7700X_PAD_I2S_MCLK_FUNC_GPIO22 2 + +#define EIC7700X_PAD_RGMII0_RXCLK_FUNC_RGMII0_RXCLK 0 +#define EIC7700X_PAD_RGMII0_RXDV_FUNC_RGMII0_RXDV 0 +#define EIC7700X_PAD_RGMII0_RXD0_FUNC_RGMII0_RXD0 0 +#define EIC7700X_PAD_RGMII0_RXD1_FUNC_RGMII0_RXD1 0 +#define EIC7700X_PAD_RGMII0_RXD2_FUNC_RGMII0_RXD2 0 +#define EIC7700X_PAD_RGMII0_RXD3_FUNC_RGMII0_RXD3 0 + +#define EIC7700X_PAD_I2S2_BCLK_FUNC_I2S2_BCLK 0 +#define EIC7700X_PAD_I2S2_BCLK_FUNC_GPIO23 2 + +#define EIC7700X_PAD_I2S2_WCLK_FUNC_I2S2_WCLK 0 +#define EIC7700X_PAD_I2S2_WCLK_FUNC_GPIO24 2 + +#define EIC7700X_PAD_I2S2_SDI_FUNC_I2S2_SDI 0 +#define EIC7700X_PAD_I2S2_SDI_FUNC_GPIO25 2 + +#define EIC7700X_PAD_I2S2_SDO_FUNC_I2S2_SDO 0 +#define EIC7700X_PAD_I2S2_SDO_FUNC_GPIO26 2 + +#define EIC7700X_PAD_GPIO27_FUNC_GPIO27 0 +#define EIC7700X_PAD_GPIO27_FUNC_SATA_ACT_LED 1 + +#define EIC7700X_PAD_GPIO28_FUNC_GPIO28 0 + +#define EIC7700X_PAD_GPIO29_FUNC_POR_TIME_SEL0 0 +#define EIC7700X_PAD_GPIO29_FUNC_EMMC_LED_CONTROL 1 +#define EIC7700X_PAD_GPIO29_FUNC_GPIO29 2 + +#define EIC7700X_PAD_RGMII0_MDC_FUNC_RGMII0_MDC 0 +#define EIC7700X_PAD_RGMII0_MDIO_FUNC_RGMII0_MDIO 0 +#define EIC7700X_PAD_RGMII0_INTB_FUNC_RGMII0_INTB 0 +#define EIC7700X_PAD_RGMII1_CLK_125_FUNC_RGMII1_CLK_125 0 +#define EIC7700X_PAD_RGMII1_TXEN_FUNC_RGMII1_TXEN 0 +#define EIC7700X_PAD_RGMII1_TXCLK_FUNC_RGMII1_TXCLK 0 +#define EIC7700X_PAD_RGMII1_TXD0_FUNC_RGMII1_TXD0 0 +#define EIC7700X_PAD_RGMII1_TXD1_FUNC_RGMII1_TXD1 0 +#define EIC7700X_PAD_RGMII1_TXD2_FUNC_RGMII1_TXD2 0 +#define EIC7700X_PAD_RGMII1_TXD3_FUNC_RGMII1_TXD3 0 + +#define EIC7700X_PAD_I2S1_BCLK_FUNC_I2S1_BCLK 0 +#define EIC7700X_PAD_I2S1_BCLK_FUNC_GPIO30 2 + +#define EIC7700X_PAD_I2S1_WCLK_FUNC_I2S1_WCLK 0 +#define EIC7700X_PAD_I2S1_WCLK_FUNC_GPIO31 2 + +#define EIC7700X_PAD_I2S1_SDI_FUNC_I2S1_SDI 0 +#define EIC7700X_PAD_I2S1_SDI_FUNC_GPIO32 2 + +#define EIC7700X_PAD_I2S1_SDO_FUNC_I2S1_SDO 0 +#define EIC7700X_PAD_I2S1_SDO_FUNC_GPIO33 2 + +#define EIC7700X_PAD_GPIO34_FUNC_POR_TIME_SEL1 0 +#define EIC7700X_PAD_GPIO34_FUNC_SD0_LED_CONTROL 1 +#define EIC7700X_PAD_GPIO34_FUNC_GPIO34 2 + +#define EIC7700X_PAD_RGMII1_RXCLK_FUNC_RGMII1_RXCLK 0 +#define EIC7700X_PAD_RGMII1_RXDV_FUNC_RGMII1_RXDV 0 +#define EIC7700X_PAD_RGMII1_RXD0_FUNC_RGMII1_RXD0 0 +#define EIC7700X_PAD_RGMII1_RXD1_FUNC_RGMII1_RXD1 0 +#define EIC7700X_PAD_RGMII1_RXD2_FUNC_RGMII1_RXD2 0 +#define EIC7700X_PAD_RGMII1_RXD3_FUNC_RGMII1_RXD3 0 + +#define EIC7700X_PAD_SPI1_CS0_N_FUNC_SPI1_CS0_N 0 +#define EIC7700X_PAD_SPI1_CS0_N_FUNC_GPIO35 2 + +#define EIC7700X_PAD_SPI1_CLK_FUNC_SPI1_CLK 0 +#define EIC7700X_PAD_SPI1_CLK_FUNC_GPIO36 2 + +#define EIC7700X_PAD_SPI1_D0_FUNC_SPI1_D0 0 +#define EIC7700X_PAD_SPI1_D0_FUNC_I2C9_SCL 1 +#define EIC7700X_PAD_SPI1_D0_FUNC_GPIO37 2 +#define EIC7700X_PAD_SPI1_D0_FUNC_UART4_TX 3 + +#define EIC7700X_PAD_SPI1_D1_FUNC_SPI1_D1 0 +#define EIC7700X_PAD_SPI1_D1_FUNC_I2C9_SDA 1 +#define EIC7700X_PAD_SPI1_D1_FUNC_GPIO38 2 +#define EIC7700X_PAD_SPI1_D1_FUNC_UART4_RX 3 + +#define EIC7700X_PAD_SPI1_D2_FUNC_SPI1_D2 0 +#define EIC7700X_PAD_SPI1_D2_FUNC_SD1_LED_CONTROL 1 +#define EIC7700X_PAD_SPI1_D2_FUNC_GPIO39 2 + +#define EIC7700X_PAD_SPI1_D3_FUNC_SPI1_D3 0 +#define EIC7700X_PAD_SPI1_D3_FUNC_PWM1 1 +#define EIC7700X_PAD_SPI1_D3_FUNC_GPIO40 2 + +#define EIC7700X_PAD_SPI1_CS1_N_FUNC_SPI1_CS1_N 0 +#define EIC7700X_PAD_SPI1_CS1_N_FUNC_PWM2 1 +#define EIC7700X_PAD_SPI1_CS1_N_FUNC_GPIO41 2 + +#define EIC7700X_PAD_RGMII1_MDC_FUNC_RGMII1_MDC 0 +#define EIC7700X_PAD_RGMII1_MDIO_FUNC_RGMII1_MDIO 0 +#define EIC7700X_PAD_RGMII1_INTB_FUNC_RGMII1_INTB 0 + +/* USB power, I2C 0 to 5, UART 0 to 2, JTAG2 and the fan */ + +#define EIC7700X_PAD_USB0_PWREN_FUNC_USB0_PWREN 0 +#define EIC7700X_PAD_USB0_PWREN_FUNC_GPIO42 2 + +#define EIC7700X_PAD_USB1_PWREN_FUNC_USB1_PWREN 0 +#define EIC7700X_PAD_USB1_PWREN_FUNC_GPIO43 2 + +#define EIC7700X_PAD_I2C0_SCL_FUNC_I2C0_SCL 0 +#define EIC7700X_PAD_I2C0_SCL_FUNC_GPIO44 2 + +#define EIC7700X_PAD_I2C0_SDA_FUNC_I2C0_SDA 0 +#define EIC7700X_PAD_I2C0_SDA_FUNC_GPIO45 2 + +#define EIC7700X_PAD_I2C1_SCL_FUNC_I2C1_SCL 0 +#define EIC7700X_PAD_I2C1_SCL_FUNC_GPIO46 2 + +#define EIC7700X_PAD_I2C1_SDA_FUNC_I2C1_SDA 0 +#define EIC7700X_PAD_I2C1_SDA_FUNC_GPIO47 2 + +#define EIC7700X_PAD_I2C2_SCL_FUNC_I2C2_SCL 0 +#define EIC7700X_PAD_I2C2_SCL_FUNC_GPIO48 2 + +#define EIC7700X_PAD_I2C2_SDA_FUNC_I2C2_SDA 0 +#define EIC7700X_PAD_I2C2_SDA_FUNC_GPIO49 2 + +#define EIC7700X_PAD_I2C3_SCL_FUNC_I2C3_SCL 0 +#define EIC7700X_PAD_I2C3_SCL_FUNC_GPIO50 2 + +#define EIC7700X_PAD_I2C3_SDA_FUNC_I2C3_SDA 0 +#define EIC7700X_PAD_I2C3_SDA_FUNC_GPIO51 2 + +#define EIC7700X_PAD_I2C4_SCL_FUNC_I2C4_SCL 0 +#define EIC7700X_PAD_I2C4_SCL_FUNC_GPIO52 2 + +#define EIC7700X_PAD_I2C4_SDA_FUNC_I2C4_SDA 0 +#define EIC7700X_PAD_I2C4_SDA_FUNC_GPIO53 2 + +#define EIC7700X_PAD_I2C5_SCL_FUNC_I2C5_SCL 0 +#define EIC7700X_PAD_I2C5_SCL_FUNC_GPIO54 2 + +#define EIC7700X_PAD_I2C5_SDA_FUNC_I2C5_SDA 0 +#define EIC7700X_PAD_I2C5_SDA_FUNC_GPIO55 2 + +#define EIC7700X_PAD_UART0_TX_FUNC_UART0_TX 0 +#define EIC7700X_PAD_UART0_TX_FUNC_GPIO56 2 + +#define EIC7700X_PAD_UART0_RX_FUNC_UART0_RX 0 +#define EIC7700X_PAD_UART0_RX_FUNC_GPIO57 2 + +#define EIC7700X_PAD_UART1_TX_FUNC_UART1_TX 0 +#define EIC7700X_PAD_UART1_TX_FUNC_GPIO58 2 + +#define EIC7700X_PAD_UART1_RX_FUNC_UART1_RX 0 +#define EIC7700X_PAD_UART1_RX_FUNC_GPIO59 2 + +#define EIC7700X_PAD_UART1_CTS_FUNC_UART1_CTS 0 +#define EIC7700X_PAD_UART1_CTS_FUNC_I2C6_SCL 1 +#define EIC7700X_PAD_UART1_CTS_FUNC_GPIO60 2 + +#define EIC7700X_PAD_UART1_RTS_FUNC_UART1_RTS 0 +#define EIC7700X_PAD_UART1_RTS_FUNC_I2C6_SDA 1 +#define EIC7700X_PAD_UART1_RTS_FUNC_GPIO61 2 + +#define EIC7700X_PAD_UART2_TX_FUNC_UART2_TX 0 +#define EIC7700X_PAD_UART2_TX_FUNC_I2C7_SCL 1 +#define EIC7700X_PAD_UART2_TX_FUNC_GPIO62 2 + +#define EIC7700X_PAD_UART2_RX_FUNC_UART2_RX 0 +#define EIC7700X_PAD_UART2_RX_FUNC_I2C7_SDA 1 +#define EIC7700X_PAD_UART2_RX_FUNC_GPIO63 2 + +#define EIC7700X_PAD_JTAG2_TCK_FUNC_JTAG2_TCK 0 +#define EIC7700X_PAD_JTAG2_TCK_FUNC_GPIO64 2 + +#define EIC7700X_PAD_JTAG2_TMS_FUNC_JTAG2_TMS 0 +#define EIC7700X_PAD_JTAG2_TMS_FUNC_GPIO65 2 + +#define EIC7700X_PAD_JTAG2_TDI_FUNC_JTAG2_TDI 0 +#define EIC7700X_PAD_JTAG2_TDI_FUNC_GPIO66 2 + +#define EIC7700X_PAD_JTAG2_TDO_FUNC_JTAG2_TDO 0 +#define EIC7700X_PAD_JTAG2_TDO_FUNC_GPIO67 2 + +#define EIC7700X_PAD_FAN_PWM_FUNC_FAN_PWM 0 +#define EIC7700X_PAD_FAN_PWM_FUNC_GPIO68 2 + +#define EIC7700X_PAD_FAN_TACH_FUNC_FAN_TACH 0 +#define EIC7700X_PAD_FAN_TACH_FUNC_GPIO69 2 + +/* MIPI CSI camera sync and clock */ + +#define EIC7700X_PAD_MIPI_CSI0_XVS_FUNC_MIPI_CSI0_XVS 0 +#define EIC7700X_PAD_MIPI_CSI0_XVS_FUNC_GPIO70 2 + +#define EIC7700X_PAD_MIPI_CSI0_XHS_FUNC_MIPI_CSI0_XHS 0 +#define EIC7700X_PAD_MIPI_CSI0_XHS_FUNC_GPIO71 2 + +#define EIC7700X_PAD_MIPI_CSI0_MCLK_FUNC_MIPI_CSI0_MCLK 0 +#define EIC7700X_PAD_MIPI_CSI0_MCLK_FUNC_GPIO72 2 + +#define EIC7700X_PAD_MIPI_CSI1_XVS_FUNC_MIPI_CSI1_XVS 0 +#define EIC7700X_PAD_MIPI_CSI1_XVS_FUNC_GPIO73 2 + +#define EIC7700X_PAD_MIPI_CSI1_XHS_FUNC_MIPI_CSI1_XHS 0 +#define EIC7700X_PAD_MIPI_CSI1_XHS_FUNC_GPIO74 2 + +#define EIC7700X_PAD_MIPI_CSI1_MCLK_FUNC_MIPI_CSI1_MCLK 0 +#define EIC7700X_PAD_MIPI_CSI1_MCLK_FUNC_GPIO75 2 + +#define EIC7700X_PAD_MIPI_CSI2_XVS_FUNC_MIPI_CSI2_XVS 0 +#define EIC7700X_PAD_MIPI_CSI2_XVS_FUNC_GPIO76 2 + +#define EIC7700X_PAD_MIPI_CSI2_XHS_FUNC_MIPI_CSI2_XHS 0 +#define EIC7700X_PAD_MIPI_CSI2_XHS_FUNC_GPIO77 2 + +#define EIC7700X_PAD_MIPI_CSI2_MCLK_FUNC_MIPI_CSI2_MCLK 0 +#define EIC7700X_PAD_MIPI_CSI2_MCLK_FUNC_GPIO78 2 + +#define EIC7700X_PAD_MIPI_CSI3_XVS_FUNC_MIPI_CSI3_XVS 0 +#define EIC7700X_PAD_MIPI_CSI3_XVS_FUNC_GPIO79 2 + +#define EIC7700X_PAD_MIPI_CSI3_XHS_FUNC_MIPI_CSI3_XHS 0 +#define EIC7700X_PAD_MIPI_CSI3_XHS_FUNC_GPIO80 2 + +#define EIC7700X_PAD_MIPI_CSI3_MCLK_FUNC_MIPI_CSI3_MCLK 0 +#define EIC7700X_PAD_MIPI_CSI3_MCLK_FUNC_GPIO81 2 + +#define EIC7700X_PAD_MIPI_CSI4_XVS_FUNC_MIPI_CSI4_XVS 0 +#define EIC7700X_PAD_MIPI_CSI4_XVS_FUNC_GPIO82 2 + +#define EIC7700X_PAD_MIPI_CSI4_XHS_FUNC_MIPI_CSI4_XHS 0 +#define EIC7700X_PAD_MIPI_CSI4_XHS_FUNC_GPIO83 2 + +#define EIC7700X_PAD_MIPI_CSI4_MCLK_FUNC_MIPI_CSI4_MCLK 0 +#define EIC7700X_PAD_MIPI_CSI4_MCLK_FUNC_GPIO84 2 + +#define EIC7700X_PAD_MIPI_CSI5_XVS_FUNC_MIPI_CSI5_XVS 0 +#define EIC7700X_PAD_MIPI_CSI5_XVS_FUNC_GPIO85 2 + +#define EIC7700X_PAD_MIPI_CSI5_XHS_FUNC_MIPI_CSI5_XHS 0 +#define EIC7700X_PAD_MIPI_CSI5_XHS_FUNC_GPIO86 2 + +#define EIC7700X_PAD_MIPI_CSI5_MCLK_FUNC_MIPI_CSI5_MCLK 0 +#define EIC7700X_PAD_MIPI_CSI5_MCLK_FUNC_GPIO87 2 + +/* SPI3, SPI0, I2C 10 and 11, boot select and the last GPIO */ + +#define EIC7700X_PAD_SPI3_CS_N_FUNC_SPI3_CS_N 0 +#define EIC7700X_PAD_SPI3_CS_N_FUNC_GPIO88 2 + +#define EIC7700X_PAD_SPI3_CLK_FUNC_SPI3_CLK 0 +#define EIC7700X_PAD_SPI3_CLK_FUNC_GPIO89 2 + +#define EIC7700X_PAD_SPI3_DI_FUNC_SPI3_DI 0 +#define EIC7700X_PAD_SPI3_DI_FUNC_GPIO90 2 + +#define EIC7700X_PAD_SPI3_DO_FUNC_SPI3_DO 0 +#define EIC7700X_PAD_SPI3_DO_FUNC_GPIO91 2 + +#define EIC7700X_PAD_GPIO92_FUNC_I2C8_SCL 0 +#define EIC7700X_PAD_GPIO92_FUNC_MIPI_CSI_XTRIG0 1 +#define EIC7700X_PAD_GPIO92_FUNC_GPIO92 2 +#define EIC7700X_PAD_GPIO92_FUNC_UART3_TX 3 + +#define EIC7700X_PAD_GPIO93_FUNC_I2C8_SDA 0 +#define EIC7700X_PAD_GPIO93_FUNC_MIPI_CSI_XTRIG1 1 +#define EIC7700X_PAD_GPIO93_FUNC_GPIO93 2 +#define EIC7700X_PAD_GPIO93_FUNC_UART3_RX 3 + +#define EIC7700X_PAD_S_MODE_FUNC_S_MODE 0 +#define EIC7700X_PAD_S_MODE_FUNC_GPIO94 2 + +#define EIC7700X_PAD_GPIO95_FUNC_LPDDR_REFCLK_SEL 0 +#define EIC7700X_PAD_GPIO95_FUNC_GPIO95 2 + +#define EIC7700X_PAD_SPI0_CS_N_FUNC_SPI0_CS_N 0 +#define EIC7700X_PAD_SPI0_CS_N_FUNC_GPIO96 2 + +#define EIC7700X_PAD_SPI0_CLK_FUNC_SPI0_CLK 0 +#define EIC7700X_PAD_SPI0_CLK_FUNC_GPIO97 2 + +#define EIC7700X_PAD_SPI0_D0_FUNC_SPI0_D0 0 +#define EIC7700X_PAD_SPI0_D0_FUNC_GPIO98 2 + +#define EIC7700X_PAD_SPI0_D1_FUNC_SPI0_D1 0 +#define EIC7700X_PAD_SPI0_D1_FUNC_GPIO99 2 + +#define EIC7700X_PAD_SPI0_D2_FUNC_SPI0_D2 0 +#define EIC7700X_PAD_SPI0_D2_FUNC_GPIO100 2 + +#define EIC7700X_PAD_SPI0_D3_FUNC_SPI0_D3 0 +#define EIC7700X_PAD_SPI0_D3_FUNC_GPIO101 2 + +#define EIC7700X_PAD_I2C10_SCL_FUNC_I2C10_SCL 0 +#define EIC7700X_PAD_I2C10_SCL_FUNC_GPIO102 2 + +#define EIC7700X_PAD_I2C10_SDA_FUNC_I2C10_SDA 0 +#define EIC7700X_PAD_I2C10_SDA_FUNC_GPIO103 2 + +#define EIC7700X_PAD_I2C11_SCL_FUNC_I2C11_SCL 0 +#define EIC7700X_PAD_I2C11_SCL_FUNC_GPIO104 2 + +#define EIC7700X_PAD_I2C11_SDA_FUNC_I2C11_SDA 0 +#define EIC7700X_PAD_I2C11_SDA_FUNC_GPIO105 2 + +#define EIC7700X_PAD_GPIO106_FUNC_GPIO106 0 + +#define EIC7700X_PAD_BOOT_SEL0_FUNC_BOOT_SEL0 0 +#define EIC7700X_PAD_BOOT_SEL0_FUNC_GPIO107 2 + +#define EIC7700X_PAD_BOOT_SEL1_FUNC_BOOT_SEL1 0 +#define EIC7700X_PAD_BOOT_SEL1_FUNC_GPIO108 2 + +#define EIC7700X_PAD_BOOT_SEL2_FUNC_BOOT_SEL2 0 +#define EIC7700X_PAD_BOOT_SEL2_FUNC_GPIO109 2 + +#define EIC7700X_PAD_BOOT_SEL3_FUNC_BOOT_SEL3 0 +#define EIC7700X_PAD_BOOT_SEL3_FUNC_GPIO110 2 + +#define EIC7700X_PAD_GPIO111_FUNC_GPIO111 0 +#define EIC7700X_PAD_LPDDR_REF_CLK_FUNC_LPDDR_REF_CLK 0 + +#endif /* __ARCH_RISCV_INCLUDE_EIC7700X_EIC7700X_PINCTRL_H */ diff --git a/arch/risc-v/src/eic7700x/Kconfig b/arch/risc-v/src/eic7700x/Kconfig index 31cbbc73b206e..c32839a8da3d8 100644 --- a/arch/risc-v/src/eic7700x/Kconfig +++ b/arch/risc-v/src/eic7700x/Kconfig @@ -47,4 +47,21 @@ config EIC7700X_CPU_FREQ_MHZ cores at 1400, so the default changes nothing and merely says so in the log. -endif \ No newline at end of file +endif + +config EIC7700X_PINCTRL + bool "CLMM pad multiplexing" + default y + select PINCTRL + ---help--- + Describe the pads of the Chip Level Mode Mux (CLMM) to the NuttX + pinctrl framework. Initialisation writes nothing to the hardware: + a pad only moves when a driver asks it to. + + Every pad on the SoC shares its ball with something else, so the + UARTs beyond the console, the GPIO block and the peripheral buses + all need a pad configured here before they reach a pin. + + The board reports the pad count and how many differ from their + reset defaults once, at startup. With DEBUG_PINCTRL_INFO the + driver also logs each pad as it is configured. diff --git a/arch/risc-v/src/eic7700x/Make.defs b/arch/risc-v/src/eic7700x/Make.defs index 28614bcb7902f..a07a7c3d24b69 100644 --- a/arch/risc-v/src/eic7700x/Make.defs +++ b/arch/risc-v/src/eic7700x/Make.defs @@ -39,3 +39,7 @@ endif ifeq ($(CONFIG_EIC7700X_CPUCLK),y) CHIP_CSRCS += eic7700x_cpuclk.c endif + +ifeq ($(CONFIG_EIC7700X_PINCTRL),y) +CHIP_CSRCS += eic7700x_pinctrl.c eic7700x_pinctrl_ops.c +endif diff --git a/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c new file mode 100644 index 0000000000000..1dc22401af2c5 --- /dev/null +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c @@ -0,0 +1,836 @@ +/**************************************************************************** + * arch/risc-v/src/eic7700x/eic7700x_pinctrl.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "riscv_internal.h" +#include "eic7700x_pinctrl.h" +#include "hardware/eic7700x_pinctrl.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* One table row per pad, in register order, so a row's position in the + * array is the pad id and the offset in the trailing comment is redundant + * by construction. There is a macro per field layout rather than a shape + * argument, so that a row cannot silently claim a layout its fields do not + * match. + */ + +#define PADGEN(w, d, fm, gf, fl) \ + { \ + .wmask = (w), .shape = EIC7700X_PADSHAPE_GENERAL, .dflt = (d), \ + .funcmask = (fm), .gpiofunc = (gf), .flags = (fl) \ + } + +#define PADRGM(w, d, fm, gf, fl) \ + { \ + .wmask = (w), .shape = EIC7700X_PADSHAPE_RGMII, .dflt = (d), \ + .funcmask = (fm), .gpiofunc = (gf), .flags = (fl) \ + } + +#define PADOSC(w, d, fm, gf, fl) \ + { \ + .wmask = (w), .shape = EIC7700X_PADSHAPE_OSC, .dflt = (d), \ + .funcmask = (fm), .gpiofunc = (gf), .flags = (fl) \ + } + +#define PADMSEL(w, d, fm, gf, fl) \ + { \ + .wmask = (w), .shape = EIC7700X_PADSHAPE_MODESEL, .dflt = (d), \ + .funcmask = (fm), .gpiofunc = (gf), .flags = (fl) \ + } + +/* Shorthands so a table row fits a line. */ + +#define NOGP EIC7700X_PAD_NOGPIO +#define LOCK EIC7700X_PAD_LOCKED + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* The reset values the manual gives, one per field, reassembled into + * words. Fifteen cover all 166 pads, so the table above stores an index. + */ + +const uint32_t g_eic7700x_pad_defaults[EIC7700X_PAD_NDEFAULTS] = +{ + 0x00000000, /* 0 */ + 0x00000001, /* 1 */ + 0x00000008, /* 2 */ + 0x00000009, /* 3 */ + 0x0000000a, /* 4 */ + 0x0000000b, /* 5 */ + 0x0000000d, /* 6 */ + 0x00000010, /* 7 */ + 0x00000011, /* 8 */ + 0x00000083, /* 9 */ + 0x00000085, /* 10 */ + 0x00000089, /* 11 */ + 0x0000008b, /* 12 */ + 0x000000c8, /* 13 */ + 0x00000301, /* 14 */ +}; + +/* Every pad of the block, from TRM part 4 section 12.1.2.2 pages 371 to + * 410. The write mask is the manual's access column: a bit is set here + * only where the manual says RW. + * + * Five pads have a zero write mask. They are not omissions: CHIP_MODE and + * POR_SEL report how the chip was strapped, KEY_RESET_N reports a button, + * and two reserved pads report a state nothing can change. Reading them + * is useful and writing them is not possible, which is a distinction the + * write path has to keep. + */ + +const struct eic7700x_pad_s g_eic7700x_pads[EIC7700X_PAD_NPADS] = +{ + PADGEN(0x00000000, 10, 0x01, NOGP, 0), /* 0x080 CHIP_MODE */ + PADGEN(0x000700ff, 11, 0x05, 2 , 0), /* 0x084 MODE_SET0 */ + PADGEN(0x000700ff, 11, 0x05, 2 , 0), /* 0x088 MODE_SET1 */ + PADGEN(0x000700ff, 11, 0x05, 2 , 0), /* 0x08c MODE_SET2 */ + PADGEN(0x000700ff, 11, 0x05, 2 , 0), /* 0x090 MODE_SET3 */ + PADOSC(0x000000ff, 13, 0x01, NOGP, 0), /* 0x094 XIN */ + PADOSC(0x000000ff, 13, 0x01, NOGP, 0), /* 0x098 RESERVED0 */ + PADGEN(0x000000fe, 4, 0x01, NOGP, 0), /* 0x09c RST_OUT_N */ + PADGEN(0x00000000, 9, 0x01, NOGP, 0), /* 0x0a0 KEY_RESET_N */ + PADGEN(0x00000000, 9, 0x01, NOGP, 0), /* 0x0a4 RESERVED1 */ + PADGEN(0x00000000, 9, 0x01, NOGP, 0), /* 0x0a8 RESERVED2 */ + PADGEN(0x00000078, 4, 0x01, NOGP, 0), /* 0x0ac RESERVED3 */ + PADGEN(0x000000ff, 2, 0x01, 0 , 0), /* 0x0b0 GPIO0 */ + PADGEN(0x00000000, 1, 0x01, NOGP, 0), /* 0x0b4 POR_SEL */ + PADGEN(0x000700ff, 6, 0x07, 2 , 0), /* 0x0b8 JTAG0_TCK */ + PADGEN(0x000700ff, 5, 0x07, 2 , 0), /* 0x0bc JTAG0_TMS */ + PADGEN(0x000700ff, 5, 0x07, 2 , 0), /* 0x0c0 JTAG0_TDI */ + PADGEN(0x000700ff, 2, 0x07, 2 , 0), /* 0x0c4 JTAG0_TDO */ + PADGEN(0x000700ff, 2, 0x01, NOGP, 0), /* 0x0c8 JTAG0_TRST */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x0cc SPI2_CS0_N */ + PADGEN(0x000700ff, 6, 0x05, 2 , 0), /* 0x0d0 JTAG1_TCK */ + PADGEN(0x000700ff, 5, 0x05, 2 , 0), /* 0x0d4 JTAG1_TMS */ + PADGEN(0x000700ff, 5, 0x05, 2 , 0), /* 0x0d8 JTAG1_TDI */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x0dc JTAG1_TDO */ + PADGEN(0x000000ff, 2, 0x01, NOGP, 0), /* 0x0e0 JTAG1_TRST */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x0e4 SPI2_CS1_N */ + PADGEN(0x000000ff, 3, 0x01, NOGP, 0), /* 0x0e8 PCIE_CLKREQ_N */ + PADGEN(0x000000ff, 5, 0x01, NOGP, 0), /* 0x0ec PCIE_WAKE_N */ + PADGEN(0x000000ff, 2, 0x01, NOGP, 0), /* 0x0f0 PCIE_PERST_N */ + PADGEN(0x000000ff, 3, 0x01, NOGP, 0), /* 0x0f4 HDMI_SCL */ + PADGEN(0x000000ff, 3, 0x01, NOGP, 0), /* 0x0f8 HDMI_SDA */ + PADGEN(0x000000ff, 4, 0x01, NOGP, 0), /* 0x0fc HDMI_CEC */ + PADGEN(0x000700ff, 12, 0x05, 2 , 0), /* 0x100 JTAG2_TRST */ + PADGEN(0x000700ff, 8, 0x01, NOGP, 0), /* 0x104 RGMII0_CLK_125 */ + PADGEN(0x000700ff, 7, 0x01, NOGP, 0), /* 0x108 RGMII0_TXEN */ + PADGEN(0x000700ff, 7, 0x01, NOGP, 0), /* 0x10c RGMII0_TXCLK */ + PADGEN(0x000700ff, 7, 0x01, NOGP, 0), /* 0x110 RGMII0_TXD0 */ + PADGEN(0x000700ff, 7, 0x01, NOGP, 0), /* 0x114 RGMII0_TXD1 */ + PADGEN(0x000700ff, 7, 0x01, NOGP, 0), /* 0x118 RGMII0_TXD2 */ + PADGEN(0x000700ff, 7, 0x01, NOGP, 0), /* 0x11c RGMII0_TXD3 */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x120 I2S0_BCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x124 I2S0_WCLK */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x128 I2S0_SDI */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x12c I2S0_SDO */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x130 I2S_MCLK */ + PADGEN(0x000700ff, 1, 0x01, NOGP, 0), /* 0x134 RGMII0_RXCLK */ + PADGEN(0x000700ff, 1, 0x01, NOGP, 0), /* 0x138 RGMII0_RXDV */ + PADGEN(0x000700ff, 1, 0x01, NOGP, 0), /* 0x13c RGMII0_RXD0 */ + PADGEN(0x000700ff, 1, 0x01, NOGP, 0), /* 0x140 RGMII0_RXD1 */ + PADGEN(0x000700ff, 1, 0x01, NOGP, 0), /* 0x144 RGMII0_RXD2 */ + PADGEN(0x000700ff, 1, 0x01, NOGP, 0), /* 0x148 RGMII0_RXD3 */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x14c I2S2_BCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x150 I2S2_WCLK */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x154 I2S2_SDI */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x158 I2S2_SDO */ + PADGEN(0x000700ff, 2, 0x03, 0 , 0), /* 0x15c GPIO27 */ + PADGEN(0x000000ff, 2, 0x01, 0 , 0), /* 0x160 GPIO28 */ + PADGEN(0x000700ff, 3, 0x07, 2 , 0), /* 0x164 GPIO29 */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x168 RGMII0_MDC */ + PADGEN(0x000000ff, 8, 0x01, NOGP, 0), /* 0x16c RGMII0_MDIO */ + PADGEN(0x000000ff, 8, 0x01, NOGP, 0), /* 0x170 RGMII0_INTB */ + PADGEN(0x000000ff, 8, 0x01, NOGP, 0), /* 0x174 RGMII1_CLK_125 */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x178 RGMII1_TXEN */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x17c RGMII1_TXCLK */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x180 RGMII1_TXD0 */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x184 RGMII1_TXD1 */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x188 RGMII1_TXD2 */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x18c RGMII1_TXD3 */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x190 I2S1_BCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x194 I2S1_WCLK */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x198 I2S1_SDI */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x19c I2S1_SDO */ + PADGEN(0x000700ff, 3, 0x07, 2 , 0), /* 0x1a0 GPIO34 */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x1a4 RGMII1_RXCLK */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x1a8 RGMII1_RXDV */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x1ac RGMII1_RXD0 */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x1b0 RGMII1_RXD1 */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x1b4 RGMII1_RXD2 */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x1b8 RGMII1_RXD3 */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x1bc SPI1_CS0_N */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x1c0 SPI1_CLK */ + PADGEN(0x000700ff, 2, 0x0f, 2 , 0), /* 0x1c4 SPI1_D0 */ + PADGEN(0x000700ff, 3, 0x0f, 2 , 0), /* 0x1c8 SPI1_D1 */ + PADGEN(0x000700ff, 3, 0x07, 2 , 0), /* 0x1cc SPI1_D2 */ + PADGEN(0x000700ff, 3, 0x07, 2 , 0), /* 0x1d0 SPI1_D3 */ + PADGEN(0x000700ff, 2, 0x07, 2 , 0), /* 0x1d4 SPI1_CS1_N */ + PADGEN(0x000000ff, 7, 0x01, NOGP, 0), /* 0x1d8 RGMII1_MDC */ + PADGEN(0x000000ff, 8, 0x01, NOGP, 0), /* 0x1dc RGMII1_MDIO */ + PADGEN(0x000000ff, 8, 0x01, NOGP, 0), /* 0x1e0 RGMII1_INTB */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x1e4 USB0_PWREN */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x1e8 USB1_PWREN */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x1ec I2C0_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x1f0 I2C0_SDA */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x1f4 I2C1_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x1f8 I2C1_SDA */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x1fc I2C2_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x200 I2C2_SDA */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x204 I2C3_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x208 I2C3_SDA */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x20c I2C4_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x210 I2C4_SDA */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x214 I2C5_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x218 I2C5_SDA */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x21c UART0_TX */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x220 UART0_RX */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x224 UART1_TX */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x228 UART1_RX */ + PADGEN(0x000700ff, 3, 0x07, 2 , 0), /* 0x22c UART1_CTS */ + PADGEN(0x000700ff, 2, 0x07, 2 , 0), /* 0x230 UART1_RTS */ + PADGEN(0x000700ff, 2, 0x07, 2 , 0), /* 0x234 UART2_TX */ + PADGEN(0x000700ff, 3, 0x07, 2 , 0), /* 0x238 UART2_RX */ + PADGEN(0x000700ff, 6, 0x05, 2 , 0), /* 0x23c JTAG2_TCK */ + PADGEN(0x000700ff, 5, 0x05, 2 , 0), /* 0x240 JTAG2_TMS */ + PADGEN(0x000700ff, 5, 0x05, 2 , 0), /* 0x244 JTAG2_TDI */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x248 JTAG2_TDO */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x24c FAN_PWM */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x250 FAN_TACH */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x254 MIPI_CSI0_XVS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x258 MIPI_CSI0_XHS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x25c MIPI_CSI0_MCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x260 MIPI_CSI1_XVS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x264 MIPI_CSI1_XHS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x268 MIPI_CSI1_MCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x26c MIPI_CSI2_XVS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x270 MIPI_CSI2_XHS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x274 MIPI_CSI2_MCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x278 MIPI_CSI3_XVS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x27c MIPI_CSI3_XHS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x280 MIPI_CSI3_MCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x284 MIPI_CSI4_XVS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x288 MIPI_CSI4_XHS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x28c MIPI_CSI4_MCLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x290 MIPI_CSI5_XVS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x294 MIPI_CSI5_XHS */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x298 MIPI_CSI5_MCLK */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x29c SPI3_CS_N */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2a0 SPI3_CLK */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2a4 SPI3_DI */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x2a8 SPI3_DO */ + PADGEN(0x000700ff, 3, 0x0f, 2 , 0), /* 0x2ac GPIO92 */ + PADGEN(0x000700ff, 3, 0x0f, 2 , 0), /* 0x2b0 GPIO93 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2b4 S_MODE */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2b8 GPIO95 */ + PADGEN(0x000700ff, 4, 0x05, 2 , 0), /* 0x2bc SPI0_CS_N */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x2c0 SPI0_CLK */ + PADGEN(0x000700ff, 2, 0x05, 2 , 0), /* 0x2c4 SPI0_D0 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2c8 SPI0_D1 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2cc SPI0_D2 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2d0 SPI0_D3 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2d4 I2C10_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2d8 I2C10_SDA */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2dc I2C11_SCL */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2e0 I2C11_SDA */ + PADGEN(0x000000ff, 2, 0x01, 0 , 0), /* 0x2e4 GPIO106 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2e8 BOOT_SEL0 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2ec BOOT_SEL1 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2f0 BOOT_SEL2 */ + PADGEN(0x000700ff, 3, 0x05, 2 , 0), /* 0x2f4 BOOT_SEL3 */ + PADGEN(0x000000ff, 2, 0x01, 0 , 0), /* 0x2f8 GPIO111 */ + PADGEN(0x000000ff, 1, 0x01, NOGP, 0), /* 0x2fc RESERVED4 */ + PADGEN(0x000000ff, 2, 0x01, NOGP, 0), /* 0x300 RESERVED5 */ + PADGEN(0x000000ff, 9, 0x01, NOGP, 0), /* 0x304 RESERVED6 */ + PADGEN(0x000000ff, 4, 0x01, NOGP, 0), /* 0x308 RESERVED7 */ + PADRGM(0x000003ff, 14, 0x01, NOGP, LOCK), /* 0x30c LPDDR_REF_CLK */ + PADMSEL(0x00000003, 0, 0x01, NOGP, LOCK), /* 0x310 ADDR_RGMII0_SEL_MODE */ + PADMSEL(0x00000003, 0, 0x01, NOGP, LOCK), /* 0x314 ADDR_RGMII1_SEL_MODE */ +}; + +static_assert(nitems(g_eic7700x_pads) == EIC7700X_PAD_NPADS, + "pad table length does not match the pad count"); +static_assert(nitems(g_eic7700x_pad_defaults) == EIC7700X_PAD_NDEFAULTS, + "reset default table length does not match the count"); +static_assert(EIC7700X_PAD_OFFSET(EIC7700X_PAD_NPADS - 1) == 0x0314, + "last pad does not land on the last register of the block"); + +/* Which pad carries each GPIO line, for the GPIO driver to come. + * + * GPIO 5 and 11 are balls that part 1 table 2-4 documents but that the + * register detail description gives no pad register for, and none of the + * eight reserved registers can be attributed to them without guessing. + * They are marked NOPAD rather than guessed at. The consequence is real: + * both lines exist in port A and are interruptible, but their input + * enable cannot be reached, so neither can be configured as an input. + */ + +#define NOPAD EIC7700X_PAD_NOPAD + +const uint8_t g_eic7700x_pad_bygpio[EIC7700X_PAD_NGPIOS] = +{ + 12, 14, 15, 16, 17, NOPAD, 19, 20, /* 0 - 7 */ + 21, 22, 23, NOPAD, 25, 1, 2, 3, /* 8 - 15 */ + 4, 32, 40, 41, 42, 43, 44, 51, /* 16 - 23 */ + 52, 53, 54, 55, 56, 57, 68, 69, /* 24 - 31 */ + 70, 71, 72, 79, 80, 81, 82, 83, /* 32 - 39 */ + 84, 85, 89, 90, 91, 92, 93, 94, /* 40 - 47 */ + 95, 96, 97, 98, 99, 100, 101, 102, /* 48 - 55 */ + 103, 104, 105, 106, 107, 108, 109, 110, /* 56 - 63 */ + 111, 112, 113, 114, 115, 116, 117, 118, /* 64 - 71 */ + 119, 120, 121, 122, 123, 124, 125, 126, /* 72 - 79 */ + 127, 128, 129, 130, 131, 132, 133, 134, /* 80 - 87 */ + 135, 136, 137, 138, 139, 140, 141, 142, /* 88 - 95 */ + 143, 144, 145, 146, 147, 148, 149, 150, /* 96 - 103 */ + 151, 152, 153, 154, 155, 156, 157, 158, /* 104 - 111 */ +}; + +static_assert(nitems(g_eic7700x_pad_bygpio) == EIC7700X_PAD_NGPIOS, + "GPIO reverse map length does not match the GPIO count"); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The device handed to the pinctrl framework. struct pinctrl_dev_s holds + * an operations pointer and nothing else, and pinctrl_register() stores + * the address rather than copying, so this has to outlive registration. + */ + +static struct pinctrl_dev_s g_eic7700x_pinctrl_dev = +{ + .ops = &g_eic7700x_pinctrl_ops, + .npins = EIC7700X_PAD_NPADS +}; + +#ifdef HAVE_PINCTRL_TEXT + +/* Every pad's name and the name of each function select the manual + * documents, in select order, for /proc/pinctrl and PINCTRLC_GETPAD. + * The names are the manual's own; a pad's name describes its default + * function, not its current one. + */ + +static const struct pinctrl_padname_s +g_eic7700x_pad_names[EIC7700X_PAD_NPADS] = +{ + [EIC7700X_PAD_CHIP_MODE] = + PINCTRL_PADNAME("CHIP_MODE", "CHIP_MODE"), + [EIC7700X_PAD_MODE_SET0] = + PINCTRL_PADNAME("MODE_SET0", "SDIO0_DETECT", NULL, "GPIO13"), + [EIC7700X_PAD_MODE_SET1] = + PINCTRL_PADNAME("MODE_SET1", "SDIO0_WRITE_PROT", NULL, "GPIO14"), + [EIC7700X_PAD_MODE_SET2] = + PINCTRL_PADNAME("MODE_SET2", "SDIO1_DETECT", NULL, "GPIO15"), + [EIC7700X_PAD_MODE_SET3] = + PINCTRL_PADNAME("MODE_SET3", "SDIO1_WRITE_PROT", NULL, "GPIO16"), + [EIC7700X_PAD_XIN] = + PINCTRL_PADNAME("XIN", "XIN_24M"), + [EIC7700X_PAD_RESERVED0] = + PINCTRL_PADNAME("RESERVED0", "XOUT_24M"), + [EIC7700X_PAD_RST_OUT_N] = + PINCTRL_PADNAME("RST_OUT_N", "RST_OUT_N"), + [EIC7700X_PAD_KEY_RESET_N] = + PINCTRL_PADNAME("KEY_RESET_N", "KEY_RESET_N"), + [EIC7700X_PAD_RESERVED1] = + PINCTRL_PADNAME("RESERVED1", NULL), + [EIC7700X_PAD_RESERVED2] = + PINCTRL_PADNAME("RESERVED2", NULL), + [EIC7700X_PAD_RESERVED3] = + PINCTRL_PADNAME("RESERVED3", NULL), + [EIC7700X_PAD_GPIO0] = + PINCTRL_PADNAME("GPIO0", "GPIO0"), + [EIC7700X_PAD_POR_SEL] = + PINCTRL_PADNAME("POR_SEL", "POR_SEL"), + [EIC7700X_PAD_JTAG0_TCK] = + PINCTRL_PADNAME("JTAG0_TCK", "JTAG0_TCK", "SPI2_CLK", "GPIO1"), + [EIC7700X_PAD_JTAG0_TMS] = + PINCTRL_PADNAME("JTAG0_TMS", "JTAG0_TMS", "SPI2_D0", "GPIO2"), + [EIC7700X_PAD_JTAG0_TDI] = + PINCTRL_PADNAME("JTAG0_TDI", "JTAG0_TDI", "SPI2_D1", "GPIO3"), + [EIC7700X_PAD_JTAG0_TDO] = + PINCTRL_PADNAME("JTAG0_TDO", "JTAG0_TDO", "SPI2_D2", "GPIO4"), + [EIC7700X_PAD_JTAG0_TRST] = + PINCTRL_PADNAME("JTAG0_TRST", NULL), + [EIC7700X_PAD_SPI2_CS0_N] = + PINCTRL_PADNAME("SPI2_CS0_N", "SPI2_CS0_N", NULL, "GPIO6"), + [EIC7700X_PAD_JTAG1_TCK] = + PINCTRL_PADNAME("JTAG1_TCK", "JTAG1_TCK", NULL, "GPIO7"), + [EIC7700X_PAD_JTAG1_TMS] = + PINCTRL_PADNAME("JTAG1_TMS", "JTAG1_TMS", NULL, "GPIO8"), + [EIC7700X_PAD_JTAG1_TDI] = + PINCTRL_PADNAME("JTAG1_TDI", "JTAG1_TDI", NULL, "GPIO9"), + [EIC7700X_PAD_JTAG1_TDO] = + PINCTRL_PADNAME("JTAG1_TDO", "JTAG1_TDO", NULL, "GPIO10"), + [EIC7700X_PAD_JTAG1_TRST] = + PINCTRL_PADNAME("JTAG1_TRST", NULL), + [EIC7700X_PAD_SPI2_CS1_N] = + PINCTRL_PADNAME("SPI2_CS1_N", "SPI2_CS1_N", NULL, "GPIO12"), + [EIC7700X_PAD_PCIE_CLKREQ_N] = + PINCTRL_PADNAME("PCIE_CLKREQ_N", "PCIE_CLKREQ_N"), + [EIC7700X_PAD_PCIE_WAKE_N] = + PINCTRL_PADNAME("PCIE_WAKE_N", "PCIE_WAKE_N"), + [EIC7700X_PAD_PCIE_PERST_N] = + PINCTRL_PADNAME("PCIE_PERST_N", "PCIE_PERST_N"), + [EIC7700X_PAD_HDMI_SCL] = + PINCTRL_PADNAME("HDMI_SCL", "HDMI_SCL"), + [EIC7700X_PAD_HDMI_SDA] = + PINCTRL_PADNAME("HDMI_SDA", "HDMI_SDA"), + [EIC7700X_PAD_HDMI_CEC] = + PINCTRL_PADNAME("HDMI_CEC", "HDMI_CEC"), + [EIC7700X_PAD_JTAG2_TRST] = + PINCTRL_PADNAME("JTAG2_TRST", "JTAG2_TRST", NULL, "GPIO17"), + [EIC7700X_PAD_RGMII0_CLK_125] = + PINCTRL_PADNAME("RGMII0_CLK_125", "RGMII0_CLK_125"), + [EIC7700X_PAD_RGMII0_TXEN] = + PINCTRL_PADNAME("RGMII0_TXEN", "RGMII0_TXEN"), + [EIC7700X_PAD_RGMII0_TXCLK] = + PINCTRL_PADNAME("RGMII0_TXCLK", "RGMII0_TXCLK"), + [EIC7700X_PAD_RGMII0_TXD0] = + PINCTRL_PADNAME("RGMII0_TXD0", "RGMII0_TXD0"), + [EIC7700X_PAD_RGMII0_TXD1] = + PINCTRL_PADNAME("RGMII0_TXD1", "RGMII0_TXD1"), + [EIC7700X_PAD_RGMII0_TXD2] = + PINCTRL_PADNAME("RGMII0_TXD2", "RGMII0_TXD2"), + [EIC7700X_PAD_RGMII0_TXD3] = + PINCTRL_PADNAME("RGMII0_TXD3", "RGMII0_TXD3"), + [EIC7700X_PAD_I2S0_BCLK] = + PINCTRL_PADNAME("I2S0_BCLK", "I2S0_BCLK", NULL, "GPIO18"), + [EIC7700X_PAD_I2S0_WCLK] = + PINCTRL_PADNAME("I2S0_WCLK", "I2S0_WCLK", NULL, "GPIO19"), + [EIC7700X_PAD_I2S0_SDI] = + PINCTRL_PADNAME("I2S0_SDI", "I2S0_SDI", NULL, "GPIO20"), + [EIC7700X_PAD_I2S0_SDO] = + PINCTRL_PADNAME("I2S0_SDO", "I2S0_SDO", NULL, "GPIO21"), + [EIC7700X_PAD_I2S_MCLK] = + PINCTRL_PADNAME("I2S_MCLK", "I2S_MCLK", NULL, "GPIO22"), + [EIC7700X_PAD_RGMII0_RXCLK] = + PINCTRL_PADNAME("RGMII0_RXCLK", "RGMII0_RXCLK"), + [EIC7700X_PAD_RGMII0_RXDV] = + PINCTRL_PADNAME("RGMII0_RXDV", "RGMII0_RXDV"), + [EIC7700X_PAD_RGMII0_RXD0] = + PINCTRL_PADNAME("RGMII0_RXD0", "RGMII0_RXD0"), + [EIC7700X_PAD_RGMII0_RXD1] = + PINCTRL_PADNAME("RGMII0_RXD1", "RGMII0_RXD1"), + [EIC7700X_PAD_RGMII0_RXD2] = + PINCTRL_PADNAME("RGMII0_RXD2", "RGMII0_RXD2"), + [EIC7700X_PAD_RGMII0_RXD3] = + PINCTRL_PADNAME("RGMII0_RXD3", "RGMII0_RXD3"), + [EIC7700X_PAD_I2S2_BCLK] = + PINCTRL_PADNAME("I2S2_BCLK", "I2S2_BCLK", NULL, "GPIO23"), + [EIC7700X_PAD_I2S2_WCLK] = + PINCTRL_PADNAME("I2S2_WCLK", "I2S2_WCLK", NULL, "GPIO24"), + [EIC7700X_PAD_I2S2_SDI] = + PINCTRL_PADNAME("I2S2_SDI", "I2S2_SDI", NULL, "GPIO25"), + [EIC7700X_PAD_I2S2_SDO] = + PINCTRL_PADNAME("I2S2_SDO", "I2S2_SDO", NULL, "GPIO26"), + [EIC7700X_PAD_GPIO27] = + PINCTRL_PADNAME("GPIO27", "GPIO27", "SATA_ACT_LED"), + [EIC7700X_PAD_GPIO28] = + PINCTRL_PADNAME("GPIO28", "GPIO28"), + [EIC7700X_PAD_GPIO29] = + PINCTRL_PADNAME("GPIO29", "POR_TIME_SEL0", "EMMC_LED_CONTROL", "GPIO29"), + [EIC7700X_PAD_RGMII0_MDC] = + PINCTRL_PADNAME("RGMII0_MDC", "RGMII0_MDC"), + [EIC7700X_PAD_RGMII0_MDIO] = + PINCTRL_PADNAME("RGMII0_MDIO", "RGMII0_MDIO"), + [EIC7700X_PAD_RGMII0_INTB] = + PINCTRL_PADNAME("RGMII0_INTB", "RGMII0_INTB"), + [EIC7700X_PAD_RGMII1_CLK_125] = + PINCTRL_PADNAME("RGMII1_CLK_125", "RGMII1_CLK_125"), + [EIC7700X_PAD_RGMII1_TXEN] = + PINCTRL_PADNAME("RGMII1_TXEN", "RGMII1_TXEN"), + [EIC7700X_PAD_RGMII1_TXCLK] = + PINCTRL_PADNAME("RGMII1_TXCLK", "RGMII1_TXCLK"), + [EIC7700X_PAD_RGMII1_TXD0] = + PINCTRL_PADNAME("RGMII1_TXD0", "RGMII1_TXD0"), + [EIC7700X_PAD_RGMII1_TXD1] = + PINCTRL_PADNAME("RGMII1_TXD1", "RGMII1_TXD1"), + [EIC7700X_PAD_RGMII1_TXD2] = + PINCTRL_PADNAME("RGMII1_TXD2", "RGMII1_TXD2"), + [EIC7700X_PAD_RGMII1_TXD3] = + PINCTRL_PADNAME("RGMII1_TXD3", "RGMII1_TXD3"), + [EIC7700X_PAD_I2S1_BCLK] = + PINCTRL_PADNAME("I2S1_BCLK", "I2S1_BCLK", NULL, "GPIO30"), + [EIC7700X_PAD_I2S1_WCLK] = + PINCTRL_PADNAME("I2S1_WCLK", "I2S1_WCLK", NULL, "GPIO31"), + [EIC7700X_PAD_I2S1_SDI] = + PINCTRL_PADNAME("I2S1_SDI", "I2S1_SDI", NULL, "GPIO32"), + [EIC7700X_PAD_I2S1_SDO] = + PINCTRL_PADNAME("I2S1_SDO", "I2S1_SDO", NULL, "GPIO33"), + [EIC7700X_PAD_GPIO34] = + PINCTRL_PADNAME("GPIO34", "POR_TIME_SEL1", "SD0_LED_CONTROL", "GPIO34"), + [EIC7700X_PAD_RGMII1_RXCLK] = + PINCTRL_PADNAME("RGMII1_RXCLK", "RGMII1_RXCLK"), + [EIC7700X_PAD_RGMII1_RXDV] = + PINCTRL_PADNAME("RGMII1_RXDV", "RGMII1_RXDV"), + [EIC7700X_PAD_RGMII1_RXD0] = + PINCTRL_PADNAME("RGMII1_RXD0", "RGMII1_RXD0"), + [EIC7700X_PAD_RGMII1_RXD1] = + PINCTRL_PADNAME("RGMII1_RXD1", "RGMII1_RXD1"), + [EIC7700X_PAD_RGMII1_RXD2] = + PINCTRL_PADNAME("RGMII1_RXD2", "RGMII1_RXD2"), + [EIC7700X_PAD_RGMII1_RXD3] = + PINCTRL_PADNAME("RGMII1_RXD3", "RGMII1_RXD3"), + [EIC7700X_PAD_SPI1_CS0_N] = + PINCTRL_PADNAME("SPI1_CS0_N", "SPI1_CS0_N", NULL, "GPIO35"), + [EIC7700X_PAD_SPI1_CLK] = + PINCTRL_PADNAME("SPI1_CLK", "SPI1_CLK", NULL, "GPIO36"), + [EIC7700X_PAD_SPI1_D0] = + PINCTRL_PADNAME("SPI1_D0", "SPI1_D0", "I2C9_SCL", "GPIO37", "UART4_TX"), + [EIC7700X_PAD_SPI1_D1] = + PINCTRL_PADNAME("SPI1_D1", "SPI1_D1", "I2C9_SDA", "GPIO38", "UART4_RX"), + [EIC7700X_PAD_SPI1_D2] = + PINCTRL_PADNAME("SPI1_D2", "SPI1_D2", "SD1_LED_CONTROL", "GPIO39"), + [EIC7700X_PAD_SPI1_D3] = + PINCTRL_PADNAME("SPI1_D3", "SPI1_D3", "PWM1", "GPIO40"), + [EIC7700X_PAD_SPI1_CS1_N] = + PINCTRL_PADNAME("SPI1_CS1_N", "SPI1_CS1_N", "PWM2", "GPIO41"), + [EIC7700X_PAD_RGMII1_MDC] = + PINCTRL_PADNAME("RGMII1_MDC", "RGMII1_MDC"), + [EIC7700X_PAD_RGMII1_MDIO] = + PINCTRL_PADNAME("RGMII1_MDIO", "RGMII1_MDIO"), + [EIC7700X_PAD_RGMII1_INTB] = + PINCTRL_PADNAME("RGMII1_INTB", "RGMII1_INTB"), + [EIC7700X_PAD_USB0_PWREN] = + PINCTRL_PADNAME("USB0_PWREN", "USB0_PWREN", NULL, "GPIO42"), + [EIC7700X_PAD_USB1_PWREN] = + PINCTRL_PADNAME("USB1_PWREN", "USB1_PWREN", NULL, "GPIO43"), + [EIC7700X_PAD_I2C0_SCL] = + PINCTRL_PADNAME("I2C0_SCL", "I2C0_SCL", NULL, "GPIO44"), + [EIC7700X_PAD_I2C0_SDA] = + PINCTRL_PADNAME("I2C0_SDA", "I2C0_SDA", NULL, "GPIO45"), + [EIC7700X_PAD_I2C1_SCL] = + PINCTRL_PADNAME("I2C1_SCL", "I2C1_SCL", NULL, "GPIO46"), + [EIC7700X_PAD_I2C1_SDA] = + PINCTRL_PADNAME("I2C1_SDA", "I2C1_SDA", NULL, "GPIO47"), + [EIC7700X_PAD_I2C2_SCL] = + PINCTRL_PADNAME("I2C2_SCL", "I2C2_SCL", NULL, "GPIO48"), + [EIC7700X_PAD_I2C2_SDA] = + PINCTRL_PADNAME("I2C2_SDA", "I2C2_SDA", NULL, "GPIO49"), + [EIC7700X_PAD_I2C3_SCL] = + PINCTRL_PADNAME("I2C3_SCL", "I2C3_SCL", NULL, "GPIO50"), + [EIC7700X_PAD_I2C3_SDA] = + PINCTRL_PADNAME("I2C3_SDA", "I2C3_SDA", NULL, "GPIO51"), + [EIC7700X_PAD_I2C4_SCL] = + PINCTRL_PADNAME("I2C4_SCL", "I2C4_SCL", NULL, "GPIO52"), + [EIC7700X_PAD_I2C4_SDA] = + PINCTRL_PADNAME("I2C4_SDA", "I2C4_SDA", NULL, "GPIO53"), + [EIC7700X_PAD_I2C5_SCL] = + PINCTRL_PADNAME("I2C5_SCL", "I2C5_SCL", NULL, "GPIO54"), + [EIC7700X_PAD_I2C5_SDA] = + PINCTRL_PADNAME("I2C5_SDA", "I2C5_SDA", NULL, "GPIO55"), + [EIC7700X_PAD_UART0_TX] = + PINCTRL_PADNAME("UART0_TX", "UART0_TX", NULL, "GPIO56"), + [EIC7700X_PAD_UART0_RX] = + PINCTRL_PADNAME("UART0_RX", "UART0_RX", NULL, "GPIO57"), + [EIC7700X_PAD_UART1_TX] = + PINCTRL_PADNAME("UART1_TX", "UART1_TX", NULL, "GPIO58"), + [EIC7700X_PAD_UART1_RX] = + PINCTRL_PADNAME("UART1_RX", "UART1_RX", NULL, "GPIO59"), + [EIC7700X_PAD_UART1_CTS] = + PINCTRL_PADNAME("UART1_CTS", "UART1_CTS", "I2C6_SCL", "GPIO60"), + [EIC7700X_PAD_UART1_RTS] = + PINCTRL_PADNAME("UART1_RTS", "UART1_RTS", "I2C6_SDA", "GPIO61"), + [EIC7700X_PAD_UART2_TX] = + PINCTRL_PADNAME("UART2_TX", "UART2_TX", "I2C7_SCL", "GPIO62"), + [EIC7700X_PAD_UART2_RX] = + PINCTRL_PADNAME("UART2_RX", "UART2_RX", "I2C7_SDA", "GPIO63"), + [EIC7700X_PAD_JTAG2_TCK] = + PINCTRL_PADNAME("JTAG2_TCK", "JTAG2_TCK", NULL, "GPIO64"), + [EIC7700X_PAD_JTAG2_TMS] = + PINCTRL_PADNAME("JTAG2_TMS", "JTAG2_TMS", NULL, "GPIO65"), + [EIC7700X_PAD_JTAG2_TDI] = + PINCTRL_PADNAME("JTAG2_TDI", "JTAG2_TDI", NULL, "GPIO66"), + [EIC7700X_PAD_JTAG2_TDO] = + PINCTRL_PADNAME("JTAG2_TDO", "JTAG2_TDO", NULL, "GPIO67"), + [EIC7700X_PAD_FAN_PWM] = + PINCTRL_PADNAME("FAN_PWM", "FAN_PWM", NULL, "GPIO68"), + [EIC7700X_PAD_FAN_TACH] = + PINCTRL_PADNAME("FAN_TACH", "FAN_TACH", NULL, "GPIO69"), + [EIC7700X_PAD_MIPI_CSI0_XVS] = + PINCTRL_PADNAME("MIPI_CSI0_XVS", "MIPI_CSI0_XVS", NULL, "GPIO70"), + [EIC7700X_PAD_MIPI_CSI0_XHS] = + PINCTRL_PADNAME("MIPI_CSI0_XHS", "MIPI_CSI0_XHS", NULL, "GPIO71"), + [EIC7700X_PAD_MIPI_CSI0_MCLK] = + PINCTRL_PADNAME("MIPI_CSI0_MCLK", "MIPI_CSI0_MCLK", NULL, "GPIO72"), + [EIC7700X_PAD_MIPI_CSI1_XVS] = + PINCTRL_PADNAME("MIPI_CSI1_XVS", "MIPI_CSI1_XVS", NULL, "GPIO73"), + [EIC7700X_PAD_MIPI_CSI1_XHS] = + PINCTRL_PADNAME("MIPI_CSI1_XHS", "MIPI_CSI1_XHS", NULL, "GPIO74"), + [EIC7700X_PAD_MIPI_CSI1_MCLK] = + PINCTRL_PADNAME("MIPI_CSI1_MCLK", "MIPI_CSI1_MCLK", NULL, "GPIO75"), + [EIC7700X_PAD_MIPI_CSI2_XVS] = + PINCTRL_PADNAME("MIPI_CSI2_XVS", "MIPI_CSI2_XVS", NULL, "GPIO76"), + [EIC7700X_PAD_MIPI_CSI2_XHS] = + PINCTRL_PADNAME("MIPI_CSI2_XHS", "MIPI_CSI2_XHS", NULL, "GPIO77"), + [EIC7700X_PAD_MIPI_CSI2_MCLK] = + PINCTRL_PADNAME("MIPI_CSI2_MCLK", "MIPI_CSI2_MCLK", NULL, "GPIO78"), + [EIC7700X_PAD_MIPI_CSI3_XVS] = + PINCTRL_PADNAME("MIPI_CSI3_XVS", "MIPI_CSI3_XVS", NULL, "GPIO79"), + [EIC7700X_PAD_MIPI_CSI3_XHS] = + PINCTRL_PADNAME("MIPI_CSI3_XHS", "MIPI_CSI3_XHS", NULL, "GPIO80"), + [EIC7700X_PAD_MIPI_CSI3_MCLK] = + PINCTRL_PADNAME("MIPI_CSI3_MCLK", "MIPI_CSI3_MCLK", NULL, "GPIO81"), + [EIC7700X_PAD_MIPI_CSI4_XVS] = + PINCTRL_PADNAME("MIPI_CSI4_XVS", "MIPI_CSI4_XVS", NULL, "GPIO82"), + [EIC7700X_PAD_MIPI_CSI4_XHS] = + PINCTRL_PADNAME("MIPI_CSI4_XHS", "MIPI_CSI4_XHS", NULL, "GPIO83"), + [EIC7700X_PAD_MIPI_CSI4_MCLK] = + PINCTRL_PADNAME("MIPI_CSI4_MCLK", "MIPI_CSI4_MCLK", NULL, "GPIO84"), + [EIC7700X_PAD_MIPI_CSI5_XVS] = + PINCTRL_PADNAME("MIPI_CSI5_XVS", "MIPI_CSI5_XVS", NULL, "GPIO85"), + [EIC7700X_PAD_MIPI_CSI5_XHS] = + PINCTRL_PADNAME("MIPI_CSI5_XHS", "MIPI_CSI5_XHS", NULL, "GPIO86"), + [EIC7700X_PAD_MIPI_CSI5_MCLK] = + PINCTRL_PADNAME("MIPI_CSI5_MCLK", "MIPI_CSI5_MCLK", NULL, "GPIO87"), + [EIC7700X_PAD_SPI3_CS_N] = + PINCTRL_PADNAME("SPI3_CS_N", "SPI3_CS_N", NULL, "GPIO88"), + [EIC7700X_PAD_SPI3_CLK] = + PINCTRL_PADNAME("SPI3_CLK", "SPI3_CLK", NULL, "GPIO89"), + [EIC7700X_PAD_SPI3_DI] = + PINCTRL_PADNAME("SPI3_DI", "SPI3_DI", NULL, "GPIO90"), + [EIC7700X_PAD_SPI3_DO] = + PINCTRL_PADNAME("SPI3_DO", "SPI3_DO", NULL, "GPIO91"), + [EIC7700X_PAD_GPIO92] = + PINCTRL_PADNAME("GPIO92", + "I2C8_SCL", "MIPI_CSI_XTRIG0", "GPIO92", "UART3_TX"), + [EIC7700X_PAD_GPIO93] = + PINCTRL_PADNAME("GPIO93", + "I2C8_SDA", "MIPI_CSI_XTRIG1", "GPIO93", "UART3_RX"), + [EIC7700X_PAD_S_MODE] = + PINCTRL_PADNAME("S_MODE", "S_MODE", NULL, "GPIO94"), + [EIC7700X_PAD_GPIO95] = + PINCTRL_PADNAME("GPIO95", "LPDDR_REFCLK_SEL", NULL, "GPIO95"), + [EIC7700X_PAD_SPI0_CS_N] = + PINCTRL_PADNAME("SPI0_CS_N", "SPI0_CS_N", NULL, "GPIO96"), + [EIC7700X_PAD_SPI0_CLK] = + PINCTRL_PADNAME("SPI0_CLK", "SPI0_CLK", NULL, "GPIO97"), + [EIC7700X_PAD_SPI0_D0] = + PINCTRL_PADNAME("SPI0_D0", "SPI0_D0", NULL, "GPIO98"), + [EIC7700X_PAD_SPI0_D1] = + PINCTRL_PADNAME("SPI0_D1", "SPI0_D1", NULL, "GPIO99"), + [EIC7700X_PAD_SPI0_D2] = + PINCTRL_PADNAME("SPI0_D2", "SPI0_D2", NULL, "GPIO100"), + [EIC7700X_PAD_SPI0_D3] = + PINCTRL_PADNAME("SPI0_D3", "SPI0_D3", NULL, "GPIO101"), + [EIC7700X_PAD_I2C10_SCL] = + PINCTRL_PADNAME("I2C10_SCL", "I2C10_SCL", NULL, "GPIO102"), + [EIC7700X_PAD_I2C10_SDA] = + PINCTRL_PADNAME("I2C10_SDA", "I2C10_SDA", NULL, "GPIO103"), + [EIC7700X_PAD_I2C11_SCL] = + PINCTRL_PADNAME("I2C11_SCL", "I2C11_SCL", NULL, "GPIO104"), + [EIC7700X_PAD_I2C11_SDA] = + PINCTRL_PADNAME("I2C11_SDA", "I2C11_SDA", NULL, "GPIO105"), + [EIC7700X_PAD_GPIO106] = + PINCTRL_PADNAME("GPIO106", "GPIO106"), + [EIC7700X_PAD_BOOT_SEL0] = + PINCTRL_PADNAME("BOOT_SEL0", "BOOT_SEL0", NULL, "GPIO107"), + [EIC7700X_PAD_BOOT_SEL1] = + PINCTRL_PADNAME("BOOT_SEL1", "BOOT_SEL1", NULL, "GPIO108"), + [EIC7700X_PAD_BOOT_SEL2] = + PINCTRL_PADNAME("BOOT_SEL2", "BOOT_SEL2", NULL, "GPIO109"), + [EIC7700X_PAD_BOOT_SEL3] = + PINCTRL_PADNAME("BOOT_SEL3", "BOOT_SEL3", NULL, "GPIO110"), + [EIC7700X_PAD_GPIO111] = + PINCTRL_PADNAME("GPIO111", "GPIO111"), + [EIC7700X_PAD_RESERVED4] = + PINCTRL_PADNAME("RESERVED4", NULL), + [EIC7700X_PAD_RESERVED5] = + PINCTRL_PADNAME("RESERVED5", NULL), + [EIC7700X_PAD_RESERVED6] = + PINCTRL_PADNAME("RESERVED6", NULL), + [EIC7700X_PAD_RESERVED7] = + PINCTRL_PADNAME("RESERVED7", NULL), + [EIC7700X_PAD_LPDDR_REF_CLK] = + PINCTRL_PADNAME("LPDDR_REF_CLK", "LPDDR_REF_CLK"), + [EIC7700X_PAD_ADDR_RGMII0_SEL_MODE] = + PINCTRL_PADNAME("ADDR_RGMII0_SEL_MODE", NULL), + [EIC7700X_PAD_ADDR_RGMII1_SEL_MODE] = + PINCTRL_PADNAME("ADDR_RGMII1_SEL_MODE", NULL), +}; + +#endif /* HAVE_PINCTRL_TEXT */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: eic7700x_pinctrl_initialize + * + * Description: + * Bring up the pad multiplexing block. This writes nothing to the + * hardware: a pad only moves when a driver asks it to. + * + * Returned Value: + * OK on success, or a negated errno on failure. + * + ****************************************************************************/ + +int eic7700x_pinctrl_initialize(void) +{ +#ifdef CONFIG_DEBUG_ASSERTIONS + unsigned int i; + + for (i = 0; i < nitems(g_eic7700x_pads); i++) + { + FAR const struct eic7700x_pad_s *pad = &g_eic7700x_pads[i]; + + DEBUGASSERT(pad->dflt < EIC7700X_PAD_NDEFAULTS); + DEBUGASSERT(pad->shape <= EIC7700X_PADSHAPE_MODESEL); + + /* A reset value with bits outside the register is a transcription + * error, not a property of the hardware. The general layout uses + * bits 0 to 18, and the other three use bits 0 to 9. + */ + + DEBUGASSERT((g_eic7700x_pad_defaults[pad->dflt] & + ~(pad->shape == EIC7700X_PADSHAPE_GENERAL ? + 0x0007ffff : 0x000003ff)) == 0); + + /* A pad that offers GPIO must offer it as one of its documented + * functions, or select_gpio would hand out a value the write path + * is about to refuse. + */ + + DEBUGASSERT(pad->gpiofunc == EIC7700X_PAD_NOGPIO || + (pad->funcmask & (1 << pad->gpiofunc)) != 0); + + /* Locking a pad the hardware already refuses to drive would say + * nothing. The three that are locked are all writable, which is + * exactly why the lock has to exist. + */ + + DEBUGASSERT((pad->flags & EIC7700X_PAD_LOCKED) == 0 || + pad->wmask != 0); + } + + for (i = 0; i < nitems(g_eic7700x_pad_bygpio); i++) + { + DEBUGASSERT(g_eic7700x_pad_bygpio[i] == EIC7700X_PAD_NOPAD || + g_eic7700x_pad_bygpio[i] < EIC7700X_PAD_NPADS); + } +#endif + + /* Publish the block as /dev/pinctrl0. The framework allocates nothing + * and keeps no state of its own, so the device below is all there is and + * a file static one is enough: there is one mux block on this SoC and it + * has no per instance state. + */ + + return pinctrl_register(&g_eic7700x_pinctrl_dev, 0); +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_count + * + * Description: + * How many pads the block has, and through changed how many currently + * differ from their reset defaults, which after boot is the set of pads + * the boot loader and the drivers have configured. + * + ****************************************************************************/ + +unsigned int eic7700x_pinctrl_count(FAR unsigned int *changed) +{ + unsigned int ndiff = 0; + unsigned int i; + + for (i = 0; i < nitems(g_eic7700x_pads); i++) + { + FAR const struct eic7700x_pad_s *pad = &g_eic7700x_pads[i]; + + if (getreg32(EIC7700X_PINCTRL_PAD(i)) != + g_eic7700x_pad_defaults[pad->dflt]) + { + ndiff++; + } + } + + if (changed != NULL) + { + *changed = ndiff; + } + + return EIC7700X_PAD_NPADS; +} + +/**************************************************************************** + * Name: eic7700x_pad_name + * + * Description: + * The manual's name for a pad, or NULL if the pad id is out of range or + * the name tables are not built. + * + ****************************************************************************/ + +FAR const char *eic7700x_pad_name(unsigned int pad) +{ +#ifdef HAVE_PINCTRL_TEXT + return pinctrl_padname(g_eic7700x_pad_names, EIC7700X_PAD_NPADS, pad); +#else + return NULL; +#endif +} + +/**************************************************************************** + * Name: eic7700x_pad_funcname + * + * Description: + * The name of function select func on pad, or NULL if the manual does + * not document it or the name tables are not built. + * + ****************************************************************************/ + +FAR const char *eic7700x_pad_funcname(unsigned int pad, unsigned int func) +{ +#ifdef HAVE_PINCTRL_TEXT + return pinctrl_funcname(g_eic7700x_pad_names, EIC7700X_PAD_NPADS, + pad, func); +#else + return NULL; +#endif +} diff --git a/arch/risc-v/src/eic7700x/eic7700x_pinctrl.h b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.h new file mode 100644 index 0000000000000..937544db5df47 --- /dev/null +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.h @@ -0,0 +1,250 @@ +/**************************************************************************** + * arch/risc-v/src/eic7700x/eic7700x_pinctrl.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_EIC7700X_EIC7700X_PINCTRL_H +#define __ARCH_RISCV_SRC_EIC7700X_EIC7700X_PINCTRL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Whether anything wants a pad's name in text. The names cost about nine + * kilobytes, so they are only compiled when something will print them. + * GPIO_PROCFS is a consumer to come: the GPIO driver's procfs entry names + * the pad behind each line. + */ + +#if defined(CONFIG_PINCTRL_PROCFS) || defined(CONFIG_GPIO_PROCFS) +# define HAVE_PINCTRL_TEXT 1 +#endif + +/* How many distinct reset values the 166 pads have between them. The + * manual gives a reset value per field; reassembled into words they + * collapse to this many, so the table stores an index instead of a word. + */ + +#define EIC7700X_PAD_NDEFAULTS (15) + +/* How many GPIO lines the SoC has. Two of them, 5 and 11, are balls in + * part 1 table 2-4 that the register detail description gives no pad + * register for, so the reverse map below has holes there. + */ + +#define EIC7700X_PAD_NGPIOS (112) +#define EIC7700X_PAD_NOPAD (0xff) + +/* A pad's gpiofunc when the pad offers no GPIO function at all. */ + +#define EIC7700X_PAD_NOGPIO (0xff) + +/* Pad flags */ + +#define EIC7700X_PAD_LOCKED (1 << 0) /* Refuses to be written */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Which of the four field layouts a pad uses. See the layout notes in + * hardware/eic7700x_pinctrl.h: the same bit means different things, or + * nothing, depending on this. + */ + +enum eic7700x_padshape_e +{ + EIC7700X_PADSHAPE_GENERAL = 0, /* Function select, pull, drive, input */ + EIC7700X_PADSHAPE_RGMII, /* Voltage mode instead of function */ + EIC7700X_PADSHAPE_OSC, /* Drive, damping and feedback only */ + EIC7700X_PADSHAPE_MODESEL /* Group voltage select, carries no pin */ +}; + +/* One pad register. + * + * wmask comes straight from the access column of the manual's register + * detail description, one bit per writable register bit. It is the only + * thing standing between a caller and a write the hardware will ignore, + * and five pads have it zero: the hardware reports their state and nothing + * more. + */ + +struct eic7700x_pad_s +{ + uint32_t wmask; /* Bits the hardware will let software drive */ + uint8_t shape; /* enum eic7700x_padshape_e */ + uint8_t dflt; /* Index into g_eic7700x_pad_defaults[] */ + uint8_t funcmask; /* Bit n set: function select n is documented */ + uint8_t gpiofunc; /* Function select giving GPIO, or NOGPIO */ + uint8_t flags; /* EIC7700X_PAD_* flags */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +EXTERN const struct eic7700x_pad_s + g_eic7700x_pads[EIC7700X_PAD_NPADS]; +EXTERN const uint32_t + g_eic7700x_pad_defaults[EIC7700X_PAD_NDEFAULTS]; +EXTERN const uint8_t + g_eic7700x_pad_bygpio[EIC7700X_PAD_NGPIOS]; +EXTERN const struct pinctrl_ops_s g_eic7700x_pinctrl_ops; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: eic7700x_pinctrl_initialize + * + * Description: + * Bring up the pad multiplexing block. This writes nothing to the + * hardware: a pad only moves when a driver asks it to. + * + * Returned Value: + * OK on success, or a negated errno on failure. + * + ****************************************************************************/ + +int eic7700x_pinctrl_initialize(void); + +/**************************************************************************** + * Name: eic7700x_pinctrl_count + * + * Description: + * How many pads the block has, and through changed how many currently + * differ from their reset defaults. + * + * Input Parameters: + * changed - Receives the changed-pad count; may be NULL. + * + * Returned Value: + * The number of pads. + * + ****************************************************************************/ + +unsigned int eic7700x_pinctrl_count(FAR unsigned int *changed); + +/**************************************************************************** + * Name: eic7700x_pad_name + * + * Description: + * The manual's name for a pad. + * + * Input Parameters: + * pad - The pad id, an enum eic7700x_pad_e value + * + * Returned Value: + * The name, or NULL if the pad id is out of range or the name tables + * are not built. + * + ****************************************************************************/ + +FAR const char *eic7700x_pad_name(unsigned int pad); + +/**************************************************************************** + * Name: eic7700x_pad_funcname + * + * Description: + * The name of one of a pad's function selects. + * + * Input Parameters: + * pad - The pad id, an enum eic7700x_pad_e value + * func - The function select + * + * Returned Value: + * The name, or NULL if the manual does not document that select or the + * name tables are not built. + * + ****************************************************************************/ + +FAR const char *eic7700x_pad_funcname(unsigned int pad, unsigned int func); + +/**************************************************************************** + * Name: eic7700x_pad_lookup + * + * Description: + * Bound a pad id and return the row describing it. Nothing else in this + * driver may index the pad table directly: this is the single place an + * out of range id is caught. + * + * Input Parameters: + * pad - The pad id, an enum eic7700x_pad_e value + * + * Returned Value: + * The pad description, or NULL if the id names no pad. + * + ****************************************************************************/ + +FAR const struct eic7700x_pad_s *eic7700x_pad_lookup(unsigned int pad); + +/**************************************************************************** + * Name: eic7700x_pad_config + * + * Description: + * Configure one pad. The value is a whole pad register, built from the + * PINCTRL_* field macros for the layout the pad uses, and every field + * lands in a single write so that a pad is never briefly half + * configured. Bits the hardware will not let software drive keep the + * value they already had. + * + * Input Parameters: + * pad - The pad id, an enum eic7700x_pad_e value + * cfg - The register value to install + * + * Returned Value: + * OK on success, or a negated errno: + * + * -EINVAL the id names no pad, or the value selects a function the + * manual does not document for this pad + * -EROFS the value tries to drive a bit that reports state only + * -EPERM the pad is one this driver refuses to move + * + ****************************************************************************/ + +int eic7700x_pad_config(unsigned int pad, uint32_t cfg); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_RISCV_SRC_EIC7700X_EIC7700X_PINCTRL_H */ diff --git a/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c b/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c new file mode 100644 index 0000000000000..7a0b3f9543313 --- /dev/null +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c @@ -0,0 +1,581 @@ +/**************************************************************************** + * arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "riscv_internal.h" +#include "eic7700x_pinctrl.h" +#include "hardware/eic7700x_pinctrl.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int eic7700x_pinctrl_setfunction(FAR struct pinctrl_dev_s *dev, + uint32_t pin, uint32_t function); +static int eic7700x_pinctrl_setstrength(FAR struct pinctrl_dev_s *dev, + uint32_t pin, uint32_t strength); +static int eic7700x_pinctrl_setdriver(FAR struct pinctrl_dev_s *dev, + uint32_t pin, + enum pinctrl_drivertype_e type); +static int eic7700x_pinctrl_setslewrate(FAR struct pinctrl_dev_s *dev, + uint32_t pin, uint32_t slewrate); +static int eic7700x_pinctrl_selectgpio(FAR struct pinctrl_dev_s *dev, + uint32_t pin); +static int eic7700x_pinctrl_getpad(FAR struct pinctrl_dev_s *dev, + uint32_t pin, + FAR struct pinctrl_padinfo_s *info); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* All five operations are supplied even though this hardware has nothing + * behind one of them. drivers/pinctrl/pinctrl.c reaches an operation as + * dev->ops->method(...) with no check that the pointer is there, so + * leaving a member NULL turns the matching ioctl into a jump through NULL + * that any process holding /dev/pinctrl0 can make. set_slewrate returns + * -ENOTSUP instead. + */ + +const struct pinctrl_ops_s g_eic7700x_pinctrl_ops = +{ + .set_function = eic7700x_pinctrl_setfunction, + .set_strength = eic7700x_pinctrl_setstrength, + .set_driver = eic7700x_pinctrl_setdriver, + .set_slewrate = eic7700x_pinctrl_setslewrate, + .select_gpio = eic7700x_pinctrl_selectgpio, + .get_pad = eic7700x_pinctrl_getpad, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: eic7700x_pad_setfield + * + * Description: + * Change one field of a pad and leave the others as they are. + * + * The framework's operations each carry a single field, so a read has to + * happen somewhere. It happens here, and the result goes back through + * eic7700x_pad_config() so that one set of checks covers both entry + * points. Note the consequence: a pad the boot loader left holding an + * undocumented function select cannot have its drive strength or pull + * changed through this path, because the value read back fails the + * function check on the way out. Refusing is the right answer there, + * since the alternative is quietly rewriting a function select the + * caller said nothing about. + * + * Input Parameters: + * pin - The pad id + * mask - The field's bits within the pad register + * val - The field's new value, already positioned + * + * Returned Value: + * -EINVAL if the id names no pad, otherwise whatever + * eic7700x_pad_config() makes of the result. + * + ****************************************************************************/ + +static int eic7700x_pad_setfield(uint32_t pin, uint32_t mask, uint32_t val) +{ + FAR const struct eic7700x_pad_s *desc; + uint32_t cur; + + desc = eic7700x_pad_lookup(pin); + if (desc == NULL) + { + return -EINVAL; + } + + cur = getreg32(EIC7700X_PINCTRL_PAD(pin)) & desc->wmask; + return eic7700x_pad_config(pin, (cur & ~mask) | (val & mask)); +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_setfunction + * + * Description: + * Select what a pad is wired to. Only the general layout has a function + * select at all; the oscillator pads and the two RGMII mode registers do + * not, and say so rather than silently writing nothing. + * + * Input Parameters: + * dev - The pinctrl device + * pin - The pad id + * function - The function select to install + * + * Returned Value: + * -EINVAL if the id names no pad, -ENOTSUP if the pad has no function + * select, otherwise the result of writing the field. + * + ****************************************************************************/ + +static int eic7700x_pinctrl_setfunction(FAR struct pinctrl_dev_s *dev, + uint32_t pin, uint32_t function) +{ + FAR const struct eic7700x_pad_s *desc; + + desc = eic7700x_pad_lookup(pin); + if (desc == NULL) + { + return -EINVAL; + } + + if (desc->shape != EIC7700X_PADSHAPE_GENERAL) + { + pinctrlerr("pad %" PRIu32 ": this pad has no function select\n", pin); + return -ENOTSUP; + } + + return eic7700x_pad_setfield(pin, PINCTRL_GEN_FUNC_MASK, + PINCTRL_GEN_FUNC(function)); +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_setstrength + * + * Description: + * Set the pad drive strength. The field is four bits wide on every + * layout that has one, though it sits in different places, so the shape + * decides which mask is used. + * + * Section 12.1.2.1 recommends leaving this alone. + * + * Input Parameters: + * dev - The pinctrl device + * pin - The pad id + * strength - The drive strength field value + * + * Returned Value: + * -EINVAL if the id names no pad, -ENOTSUP if the pad has no such + * field, otherwise the result of writing it. + * + ****************************************************************************/ + +static int eic7700x_pinctrl_setstrength(FAR struct pinctrl_dev_s *dev, + uint32_t pin, uint32_t strength) +{ + FAR const struct eic7700x_pad_s *desc; + + desc = eic7700x_pad_lookup(pin); + if (desc == NULL) + { + return -EINVAL; + } + + if (strength > 15) + { + pinctrlerr("pad %" PRIu32 ": drive strength %" PRIu32 " is over 15\n", + pin, strength); + return -EINVAL; + } + + switch (desc->shape) + { + case EIC7700X_PADSHAPE_GENERAL: + return eic7700x_pad_setfield(pin, PINCTRL_GEN_DS_MASK, + PINCTRL_GEN_DS(strength)); + + case EIC7700X_PADSHAPE_RGMII: + return eic7700x_pad_setfield(pin, PINCTRL_RGMII_DS_MASK, + strength << PINCTRL_RGMII_DS_SHIFT); + + case EIC7700X_PADSHAPE_OSC: + return eic7700x_pad_setfield(pin, PINCTRL_OSC_DS_MASK, + strength << PINCTRL_OSC_DS_SHIFT); + + default: + pinctrlerr("pad %" PRIu32 ": this pad has no drive strength\n", pin); + return -ENOTSUP; + } +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_setdriver + * + * Description: + * Set the pad bias. The hardware has a pull up bit and a pull down bit + * and nothing else, so a request for a strong pull down is refused + * rather than served as an ordinary one: quietly giving a caller a + * weaker pull than it asked for is how a bus ends up marginal. + * + * Input Parameters: + * dev - The pinctrl device + * pin - The pad id + * type - The bias to apply + * + * Returned Value: + * -EINVAL if the id names no pad, -ENOTSUP for a bias this hardware + * cannot make, otherwise the result of writing the field. + * + ****************************************************************************/ + +static int eic7700x_pinctrl_setdriver(FAR struct pinctrl_dev_s *dev, + uint32_t pin, + enum pinctrl_drivertype_e type) +{ + FAR const struct eic7700x_pad_s *desc; + uint32_t val; + + desc = eic7700x_pad_lookup(pin); + if (desc == NULL) + { + return -EINVAL; + } + + if (desc->shape == EIC7700X_PADSHAPE_OSC || + desc->shape == EIC7700X_PADSHAPE_MODESEL) + { + pinctrlerr("pad %" PRIu32 ": this pad has no pull up or down\n", pin); + return -ENOTSUP; + } + + switch (type) + { + case BIAS_DISABLE: + val = 0; + break; + + case BIAS_PULLUP: + val = PINCTRL_GEN_PU; + break; + + case BIAS_PULLDOWN: + val = PINCTRL_GEN_PD; + break; + + default: + pinctrlerr("pad %" PRIu32 ": bias %d has no equivalent here\n", + pin, type); + return -ENOTSUP; + } + + return eic7700x_pad_setfield(pin, PINCTRL_GEN_PU | PINCTRL_GEN_PD, val); +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_setslewrate + * + * Description: + * Refuse. These pads have a Schmitt trigger on the input and no slew + * rate control on the output, so there is nothing this could set. + * + * It exists only because the framework calls through the operations + * table without checking, so a NULL here would be reachable from user + * space. + * + * Input Parameters: + * dev - The pinctrl device + * pin - The pad id + * slewrate - Ignored + * + * Returned Value: + * -ENOTSUP, always. + * + ****************************************************************************/ + +static int eic7700x_pinctrl_setslewrate(FAR struct pinctrl_dev_s *dev, + uint32_t pin, uint32_t slewrate) +{ + pinctrlerr("pad %" PRIu32 ": these pads have no slew rate control\n", pin); + return -ENOTSUP; +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_selectgpio + * + * Description: + * Point a pad at the GPIO block. Which function select value does that + * differs per pad, so it comes from the table rather than being a + * constant: it is 2 on most pads and 0 on the few whose only function is + * GPIO. + * + * The input enable is set at the same time. Section 12.6.3.1 says a + * GPIO used as an input needs it, this is the only place that knows + * where the bit lives, and enabling the input buffer does not stop the + * pad driving, so setting it costs an output nothing. + * + * Input Parameters: + * dev - The pinctrl device + * pin - The pad id + * + * Returned Value: + * -EINVAL if the id names no pad, -ENOTSUP if it cannot be pointed at + * the GPIO block, otherwise the result of writing the fields. + * + ****************************************************************************/ + +static int eic7700x_pinctrl_selectgpio(FAR struct pinctrl_dev_s *dev, + uint32_t pin) +{ + FAR const struct eic7700x_pad_s *desc; + + desc = eic7700x_pad_lookup(pin); + if (desc == NULL) + { + return -EINVAL; + } + + if (desc->gpiofunc == EIC7700X_PAD_NOGPIO) + { + pinctrlerr("pad %" PRIu32 ": no GPIO function is documented\n", pin); + return -ENOTSUP; + } + + return eic7700x_pad_setfield(pin, + PINCTRL_GEN_FUNC_MASK | PINCTRL_GEN_IE, + PINCTRL_GEN_FUNC(desc->gpiofunc) | + PINCTRL_GEN_IE); +} + +/**************************************************************************** + * Name: eic7700x_pinctrl_getpad + * + * Description: + * Describe one pad for the framework: the common fields the pad's + * layout has, with their validity bits, and the layout's own fields as + * key:value text. The name helpers return NULL when the name tables + * are not built, which leaves the strings empty as the contract asks. + * + * Input Parameters: + * dev - The pinctrl device + * pin - The pad id + * info - Receives the pad description + * + * Returned Value: + * OK, or -EINVAL if the id names no pad. + * + ****************************************************************************/ + +static int eic7700x_pinctrl_getpad(FAR struct pinctrl_dev_s *dev, + uint32_t pin, + FAR struct pinctrl_padinfo_s *info) +{ + FAR const struct eic7700x_pad_s *desc; + FAR const char *name; + uint32_t val; + + desc = eic7700x_pad_lookup(pin); + if (desc == NULL) + { + return -EINVAL; + } + + val = getreg32(EIC7700X_PINCTRL_PAD(pin)); + + name = eic7700x_pad_name(pin); + if (name != NULL) + { + strlcpy(info->name, name, sizeof(info->name)); + } + + switch (desc->shape) + { + case EIC7700X_PADSHAPE_GENERAL: + info->have = PINCTRL_HAVE_FUNCTION | PINCTRL_HAVE_STRENGTH | + PINCTRL_HAVE_PULL | PINCTRL_HAVE_INPUT | + PINCTRL_HAVE_SCHMITT; + info->function = (val & PINCTRL_GEN_FUNC_MASK) >> + PINCTRL_GEN_FUNC_SHIFT; + info->strength = (val & PINCTRL_GEN_DS_MASK) >> + PINCTRL_GEN_DS_SHIFT; + info->pullup = (val & PINCTRL_GEN_PU) != 0; + info->pulldown = (val & PINCTRL_GEN_PD) != 0; + info->input = (val & PINCTRL_GEN_IE) != 0; + info->schmitt = (val & PINCTRL_GEN_SMT) != 0; + + name = eic7700x_pad_funcname(pin, info->function); + if (name != NULL) + { + strlcpy(info->funcname, name, sizeof(info->funcname)); + } + break; + + case EIC7700X_PADSHAPE_RGMII: + info->have = PINCTRL_HAVE_STRENGTH | PINCTRL_HAVE_PULL | + PINCTRL_HAVE_INPUT | PINCTRL_HAVE_SCHMITT; + info->strength = (val & PINCTRL_RGMII_DS_MASK) >> + PINCTRL_RGMII_DS_SHIFT; + info->pullup = (val & PINCTRL_RGMII_PU) != 0; + info->pulldown = (val & PINCTRL_RGMII_PD) != 0; + info->input = (val & PINCTRL_RGMII_IE) != 0; + info->schmitt = (val & PINCTRL_RGMII_SMT) != 0; + + snprintf(info->extra, sizeof(info->extra), "ms:%u", + (unsigned int)((val & + (PINCTRL_RGMII_MS2 | PINCTRL_RGMII_MS1)) >> 8)); + break; + + case EIC7700X_PADSHAPE_OSC: + info->have = PINCTRL_HAVE_STRENGTH; + info->strength = (val & PINCTRL_OSC_DS_MASK) >> + PINCTRL_OSC_DS_SHIFT; + + snprintf(info->extra, sizeof(info->extra), "frs:%u rd:%u", + (unsigned int)((val & PINCTRL_OSC_FRS_MASK) >> + PINCTRL_OSC_FRS_SHIFT), + (unsigned int)((val & PINCTRL_OSC_RD_MASK) >> + PINCTRL_OSC_RD_SHIFT)); + break; + + default: + snprintf(info->extra, sizeof(info->extra), "ms1:%u ms2:%u", + (val & PINCTRL_MODESEL_MS1) != 0, + (val & PINCTRL_MODESEL_MS2) != 0); + break; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: eic7700x_pad_lookup + * + * Description: + * Bound a pad id and return the row describing it. Nothing else in this + * driver may index the pad table directly: this is the single place an + * out of range id is caught. + * + * The pinctrl framework bounds nothing. pinctrl_register() records the + * device and every ioctl hands the pin number straight through, so a pin + * number arriving from user space is whatever the caller typed. The + * provider is the only bound there is. + * + * Input Parameters: + * pad - The pad id, an enum eic7700x_pad_e value + * + * Returned Value: + * The pad description, or NULL if the id names no pad. + * + ****************************************************************************/ + +FAR const struct eic7700x_pad_s *eic7700x_pad_lookup(unsigned int pad) +{ + if (pad >= EIC7700X_PAD_NPADS) + { + pinctrlerr("pad %u is past the end of the block\n", pad); + return NULL; + } + + return &g_eic7700x_pads[pad]; +} + +/**************************************************************************** + * Name: eic7700x_pad_config + * + * Description: + * Configure one pad. See the prototype for the contract. + * + * Three things are checked before anything is written, in order of how + * much they cost to get wrong. + * + * First the policy: three registers in this range are refused outright. + * LPDDR_REF_CLK carries the DDR reference clock, and the two RGMII mode + * registers select the IO voltage for a whole group, where the manual + * says values other than the two it lists are forbidden. Note that the + * hardware would allow all three to be written; only this refuses. + * + * Then the write mask, which is the manual's access column. Asking to + * drive a bit that reports state only is a mistake worth reporting + * rather than a write to drop silently, so it fails instead of being + * masked away. + * + * Last the function select, and only for pads that have one. A pad's + * documented functions are a subset of the eight the field can hold, and + * the two are not the same thing: seventeen pads have a writable + * function select but only one function named for them anywhere in the + * manual. Selecting an undocumented value would be asking the pad for + * something nobody has written down, so it is refused. + * + ****************************************************************************/ + +int eic7700x_pad_config(unsigned int pad, uint32_t cfg) +{ + FAR const struct eic7700x_pad_s *desc; + + desc = eic7700x_pad_lookup(pad); + if (desc == NULL) + { + return -EINVAL; + } + + if ((desc->flags & EIC7700X_PAD_LOCKED) != 0) + { + pinctrlerr("pad %u: refusing to move a pad the system runs on\n", + pad); + return -EPERM; + } + + if ((cfg & ~desc->wmask) != 0) + { + pinctrlerr("pad %u: %08" PRIx32 " drives bits outside %08" PRIx32 + "\n", pad, cfg, desc->wmask); + return -EROFS; + } + + if (desc->shape == EIC7700X_PADSHAPE_GENERAL) + { + unsigned int func; + + func = (cfg & PINCTRL_GEN_FUNC_MASK) >> PINCTRL_GEN_FUNC_SHIFT; + if ((desc->funcmask & (1 << func)) == 0) + { + pinctrlerr("pad %u: function %u is not documented, have %02x\n", + pad, func, desc->funcmask); + return -EINVAL; + } + } + + /* Write the writable bits and leave the rest as they were. modifyreg32 + * takes a spinlock with interrupts disabled, so the read modify write is + * safe against another hart configuring a different pad in the same + * register. Nothing here serialises two callers configuring the same + * pad. Two callers configuring one pad is not something a board does, + * and guarding against it would mean a lock the framework does not + * expect this provider to hold. + */ + + modifyreg32(EIC7700X_PINCTRL_PAD(pad), desc->wmask, cfg); + + pinctrlinfo("pad %u: %08" PRIx32 "\n", pad, cfg); + return OK; +} diff --git a/arch/risc-v/src/eic7700x/eic7700x_start.c b/arch/risc-v/src/eic7700x/eic7700x_start.c index b2df89c9b401b..36e69a835f5e3 100644 --- a/arch/risc-v/src/eic7700x/eic7700x_start.c +++ b/arch/risc-v/src/eic7700x/eic7700x_start.c @@ -42,6 +42,9 @@ #ifdef CONFIG_EIC7700X_CLK # include "eic7700x_clk.h" #endif +#ifdef CONFIG_EIC7700X_PINCTRL +# include "eic7700x_pinctrl.h" +#endif /**************************************************************************** * Pre-processor Definitions @@ -477,4 +480,13 @@ void weak_function riscv_soc_initialize(void) #ifdef CONFIG_EIC7700X_CLK eic7700x_clk_initialize(); #endif + + /* After the clocks. A pad is only worth moving once the clock behind + * it can be moved too, and like the clock tree this call only reads: + * a pad moves when a driver asks it to, not before. + */ + +#ifdef CONFIG_EIC7700X_PINCTRL + eic7700x_pinctrl_initialize(); +#endif } diff --git a/arch/risc-v/src/eic7700x/hardware/eic7700x_pinctrl.h b/arch/risc-v/src/eic7700x/hardware/eic7700x_pinctrl.h new file mode 100644 index 0000000000000..236bf7464568b --- /dev/null +++ b/arch/risc-v/src/eic7700x/hardware/eic7700x_pinctrl.h @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/risc-v/src/eic7700x/hardware/eic7700x_pinctrl.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_EIC7700X_HARDWARE_EIC7700X_PINCTRL_H +#define __ARCH_RISCV_SRC_EIC7700X_HARDWARE_EIC7700X_PINCTRL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Chip Level Mode Mux (CLMM), the pad multiplexing block. + * + * TRM part 4 section 12.1 page 369 describes the block, table 12-1 on page + * 369 places it. The base address is shared with the GPIO controller: GPIO + * owns 0x51600000 to 0x5160007f and CLMM everything above, so the first pad + * register sits at offset 0x80 rather than at zero. + * + * The pad registers run from 0x80 to 0x314 with no holes, one 32 bit + * register per pad, which is why a pad id is an index and needs no lookup + * table. Registers past 0x314 up to the end of the 2 MiB window are not + * described by the manual and are not touched here. + */ + +#define EIC7700X_PINCTRL_BASE 0x51600000ul +#define EIC7700X_PINCTRL_PAD0 (EIC7700X_PINCTRL_BASE + 0x0080) +#define EIC7700X_PINCTRL_PAD(n) (EIC7700X_PINCTRL_PAD0 + ((n) << 2)) + +/* Pad register layouts, TRM part 4 section 12.1.2.1 page 370 and the + * register detail description in section 12.1.2.2 pages 371 to 410. + * + * Four layouts appear. Every pad uses exactly one of them and the pad + * table records which, because a field only means what it says below when + * the pad has that layout: bit 8 is MS1 on the one RGMII style pad and part + * of nothing at all on a general pad. + */ + +/* Layout 1, general IO. 161 of the 166 pads. */ + +#define PINCTRL_GEN_FUNC_SHIFT (16) /* Bits 16-18: function select */ +#define PINCTRL_GEN_FUNC_MASK (7ul << PINCTRL_GEN_FUNC_SHIFT) +#define PINCTRL_GEN_FUNC(n) ((uint32_t)(n) << PINCTRL_GEN_FUNC_SHIFT) +#define PINCTRL_GEN_SMT (1ul << 7) /* Bit 7: Schmitt trigger */ +#define PINCTRL_GEN_DS_SHIFT (3) /* Bits 3-6: drive strength */ +#define PINCTRL_GEN_DS_MASK (15ul << PINCTRL_GEN_DS_SHIFT) +#define PINCTRL_GEN_DS(n) ((uint32_t)(n) << PINCTRL_GEN_DS_SHIFT) +#define PINCTRL_GEN_PD (1ul << 2) /* Bit 2: pull down enable */ +#define PINCTRL_GEN_PU (1ul << 1) /* Bit 1: pull up enable */ +#define PINCTRL_GEN_IE (1ul << 0) /* Bit 0: input enable */ + +/* Layout 2, RGMII style pad. LPDDR_REF_CLK only. + * + * This pad has no function select at all. The two voltage mode bits sit + * where the general layout has nothing, and the manual forbids values of + * {MS2,MS1} other than 2'b11 for 1.8 V and 2'b00 for 3.3 V. + */ + +#define PINCTRL_RGMII_MS2 (1ul << 9) /* Bit 9: voltage select */ +#define PINCTRL_RGMII_MS1 (1ul << 8) /* Bit 8: voltage select */ +#define PINCTRL_RGMII_SMT (1ul << 7) /* Bit 7: Schmitt trigger */ +#define PINCTRL_RGMII_DS_SHIFT (3) /* Bits 3-6: drive strength */ +#define PINCTRL_RGMII_DS_MASK (15ul << PINCTRL_RGMII_DS_SHIFT) +#define PINCTRL_RGMII_PD (1ul << 2) /* Bit 2: pull down enable */ +#define PINCTRL_RGMII_PU (1ul << 1) /* Bit 1: pull up enable */ +#define PINCTRL_RGMII_IE (1ul << 0) /* Bit 0: input enable */ + +/* Layout 3, oscillator pad. XIN and the pad at 0x98, which the register + * table leaves unnamed but which table 2-4 in part 1 lists as XOUT_24M. + * + * Section 12.1.2.1 page 370 and the register detail description disagree + * about the low four bits. The prose calls bits 3-2 the damping resistor + * RD and bits 1-0 the feedback resistor REF; the register table calls bits + * 3-2 FRS and bits 1-0 RD. The register table is followed here, being the + * authoritative per register description, and neither field is written by + * this driver. + */ + +#define PINCTRL_OSC_DS_SHIFT (4) /* Bits 4-7: drive strength */ +#define PINCTRL_OSC_DS_MASK (15ul << PINCTRL_OSC_DS_SHIFT) +#define PINCTRL_OSC_FRS_SHIFT (2) /* Bits 2-3: see note above */ +#define PINCTRL_OSC_FRS_MASK (3ul << PINCTRL_OSC_FRS_SHIFT) +#define PINCTRL_OSC_RD_SHIFT (0) /* Bits 0-1: see note above */ +#define PINCTRL_OSC_RD_MASK (3ul << PINCTRL_OSC_RD_SHIFT) + +/* Layout 4, RGMII voltage mode select. The two registers at 0x310 and + * 0x314, which are not pads at all: they select the IO voltage for the + * RGMII0 and RGMII1 groups as a whole. They are in the pad address range + * and so are described here, but they carry no pin. + */ + +#define PINCTRL_MODESEL_MS1 (1ul << 1) /* Bit 1: voltage select */ +#define PINCTRL_MODESEL_MS2 (1ul << 0) /* Bit 0: voltage select */ + +#endif /* __ARCH_RISCV_SRC_EIC7700X_HARDWARE_EIC7700X_PINCTRL_H */ diff --git a/boards/risc-v/eic7700x/common/src/eic7700x_boot.c b/boards/risc-v/eic7700x/common/src/eic7700x_boot.c index 3d86b3420ccf0..a7bd42288ac6b 100644 --- a/boards/risc-v/eic7700x/common/src/eic7700x_boot.c +++ b/boards/risc-v/eic7700x/common/src/eic7700x_boot.c @@ -41,6 +41,7 @@ #ifdef CONFIG_EIC7700X_CPUCLK # include "eic7700x_cpuclk.h" #endif +#include "eic7700x_pinctrl.h" #include "board_config.h" @@ -58,6 +59,25 @@ * Private Functions ****************************************************************************/ +#ifdef CONFIG_EIC7700X_PINCTRL +/**************************************************************************** + * Name: report_pads + * + * Description: + * Report the pad census. Its own function so that nothing it needs + * stays on the stack for the bring up that follows. + * + ****************************************************************************/ + +static void report_pads(void) +{ + unsigned int nchanged; + unsigned int npads = eic7700x_pinctrl_count(&nchanged); + + syslog(LOG_INFO, "pinctrl: %u pads, %u configured\n", npads, nchanged); +} +#endif /* CONFIG_EIC7700X_PINCTRL */ + /**************************************************************************** * Name: mount_ramdisk * @@ -156,6 +176,9 @@ void board_late_initialize(void) mount(NULL, "/proc", "procfs", 0, NULL); report_clocks(); +#ifdef CONFIG_EIC7700X_PINCTRL + report_pads(); +#endif /* CONFIG_EIC7700X_PINCTRL */ /* Devices whose presence or order is this board's business */ diff --git a/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig b/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig index ce4a8a086acc8..2b689a66f68e1 100644 --- a/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig +++ b/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig @@ -63,6 +63,8 @@ CONFIG_DEBUG_FS_ERROR=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_MM=y CONFIG_DEBUG_MM_ERROR=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DEBUG_PINCTRL_ERROR=y CONFIG_DEBUG_SCHED=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 @@ -71,6 +73,7 @@ CONFIG_ELF=y CONFIG_ELF_STACKSIZE=2048 CONFIG_EXAMPLES_HELLO=m CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y CONFIG_FS_ROMFS=y CONFIG_IDLETHREAD_STACKSIZE=3072 CONFIG_INIT_FILEPATH="/system/bin/init" @@ -89,6 +92,7 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_FILE_APPS=y CONFIG_NSH_READLINE=y CONFIG_PATH_INITIAL="/system/bin" +CONFIG_PINCTRL_PROCFS=y CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=2048 CONFIG_RAMLOG=y CONFIG_RAMLOG_BUFSIZE=32768 diff --git a/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig b/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig index 88dbbc3a19552..52d32bdaa792e 100644 --- a/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig +++ b/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig @@ -59,6 +59,8 @@ CONFIG_DEBUG_FS_ERROR=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_MM=y CONFIG_DEBUG_MM_ERROR=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DEBUG_PINCTRL_ERROR=y CONFIG_DEBUG_SCHED=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 @@ -67,6 +69,7 @@ CONFIG_ELF=y CONFIG_ELF_STACKSIZE=2048 CONFIG_EXAMPLES_HELLO=m CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y CONFIG_FS_ROMFS=y CONFIG_IDLETHREAD_STACKSIZE=3072 CONFIG_INIT_FILEPATH="/system/bin/init" @@ -85,6 +88,7 @@ CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_FILE_APPS=y CONFIG_NSH_READLINE=y CONFIG_PATH_INITIAL="/system/bin" +CONFIG_PINCTRL_PROCFS=y CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE=2048 CONFIG_RAMLOG=y CONFIG_RAMLOG_BUFSIZE=32768