From 793e50b6640e09a63fa9844a03c101bd3fa36e67 Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Sun, 16 Aug 2026 01:48:04 +0800 Subject: [PATCH 1/4] arch/risc-v/eic7700x: Describe and configure the pads. Every ball on this SoC is shared between several functions, and nothing in this port could see which function a pad carried or change it. A driver that finds nothing cannot tell a dead block from a pad still pointed somewhere else. Registers the CLMM pad multiplexer with the pinctrl framework and defines every pad and every function select the manual documents, across the straps, JTAG, PCIe, HDMI, Ethernet, I2S, SPI, GPIO, USB, I2C, UART, fan and MIPI CSI groups. Writes nothing at start up: a pad only moves when a driver asks. eic7700x_pinctrl_count() reports how many pads currently differ from their reset defaults, which after boot is the set the boot loader and the drivers have configured; the board start up logs it. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond --- .../include/eic7700x/eic7700x_pinctrl.h | 662 ++++++++++++++++++ arch/risc-v/src/eic7700x/Kconfig | 19 +- arch/risc-v/src/eic7700x/Make.defs | 4 + arch/risc-v/src/eic7700x/eic7700x_pinctrl.c | 449 ++++++++++++ arch/risc-v/src/eic7700x/eic7700x_pinctrl.h | 205 ++++++ .../src/eic7700x/eic7700x_pinctrl_ops.c | 475 +++++++++++++ arch/risc-v/src/eic7700x/eic7700x_start.c | 12 + .../src/eic7700x/hardware/eic7700x_pinctrl.h | 118 ++++ 8 files changed, 1943 insertions(+), 1 deletion(-) create mode 100644 arch/risc-v/include/eic7700x/eic7700x_pinctrl.h create mode 100644 arch/risc-v/src/eic7700x/eic7700x_pinctrl.c create mode 100644 arch/risc-v/src/eic7700x/eic7700x_pinctrl.h create mode 100644 arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c create mode 100644 arch/risc-v/src/eic7700x/hardware/eic7700x_pinctrl.h 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..40cde71c9c538 --- /dev/null +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c @@ -0,0 +1,449 @@ +/**************************************************************************** + * 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 +}; + +/**************************************************************************** + * 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; +} 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..9f72ddfd60c13 --- /dev/null +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.h @@ -0,0 +1,205 @@ +/**************************************************************************** + * 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 + ****************************************************************************/ + +/* 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_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..abcf10fe933b4 --- /dev/null +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c @@ -0,0 +1,475 @@ +/**************************************************************************** + * 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 "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); + +/**************************************************************************** + * 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, +}; + +/**************************************************************************** + * 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); +} + +/**************************************************************************** + * 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 */ From 6854b7254385ad176e430e37dc9a5b70669343f5 Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Mon, 17 Aug 2026 00:03:54 +0800 Subject: [PATCH 2/4] boards/risc-v/eic7700x: Report the pads at startup. Log one line from board start up with the pad count and how many differ from their reset defaults, through eic7700x_pinctrl_count(). A helper holds its locals so nothing stays on the stack for the bring up that follows. Turn the pinctrl driver's error output on for both boards, so a refused pad write says why rather than merely failing. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond --- .../eic7700x/common/src/eic7700x_boot.c | 23 +++++++++++++++++++ .../eic7700-evb/configs/nsh/defconfig | 2 ++ .../eic7700x/starpro64/configs/nsh/defconfig | 2 ++ 3 files changed, 27 insertions(+) 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..bab5b3aa839d0 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 diff --git a/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig b/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig index 88dbbc3a19552..71e9b276e1349 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 From 9efcc65596e8b909b797c466f34e587aaaa7eccb Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Mon, 17 Aug 2026 00:08:21 +0800 Subject: [PATCH 3/4] arch/risc-v/eic7700x: Describe the pads through procfs. Implements the pinctrl get_pad method, so /proc/pinctrl and PINCTRLC_GETPAD carry what this block is actually holding: each layout's common fields with their validity bits, and the layout's own fields, the RGMII and mode-select voltage bits and the oscillator tuning, as key:value text. Names every pad and every documented function select in one PINCTRL_PADNAME() table, so func:2 on S_MODE reads as GPIO94 rather than as a number. The names are the manual's own; a pad's name describes its default function, not its current one. The table costs about 9 KiB and is built only with the file that reads it; the name helpers return NULL without it and the strings stay empty. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond --- arch/risc-v/src/eic7700x/eic7700x_pinctrl.c | 389 +++++++++++++++++- arch/risc-v/src/eic7700x/eic7700x_pinctrl.h | 45 ++ .../src/eic7700x/eic7700x_pinctrl_ops.c | 106 +++++ 3 files changed, 539 insertions(+), 1 deletion(-) diff --git a/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c index 40cde71c9c538..1dc22401af2c5 100644 --- a/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.c @@ -337,9 +337,359 @@ static_assert(nitems(g_eic7700x_pad_bygpio) == EIC7700X_PAD_NGPIOS, static struct pinctrl_dev_s g_eic7700x_pinctrl_dev = { - .ops = &g_eic7700x_pinctrl_ops + .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 ****************************************************************************/ @@ -447,3 +797,40 @@ unsigned int eic7700x_pinctrl_count(FAR unsigned int *changed) 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 index 9f72ddfd60c13..937544db5df47 100644 --- a/arch/risc-v/src/eic7700x/eic7700x_pinctrl.h +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl.h @@ -39,6 +39,16 @@ * 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. @@ -153,6 +163,41 @@ int eic7700x_pinctrl_initialize(void); 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 * diff --git a/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c b/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c index abcf10fe933b4..7a0b3f9543313 100644 --- a/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c +++ b/arch/risc-v/src/eic7700x/eic7700x_pinctrl_ops.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -52,6 +54,9 @@ 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 @@ -72,6 +77,7 @@ const struct pinctrl_ops_s g_eic7700x_pinctrl_ops = .set_driver = eic7700x_pinctrl_setdriver, .set_slewrate = eic7700x_pinctrl_setslewrate, .select_gpio = eic7700x_pinctrl_selectgpio, + .get_pad = eic7700x_pinctrl_getpad, }; /**************************************************************************** @@ -357,6 +363,106 @@ static int eic7700x_pinctrl_selectgpio(FAR struct pinctrl_dev_s *dev, 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 ****************************************************************************/ From 2010cd2961420f66ccff30d90eca0b5be17266b1 Mon Sep 17 00:00:00 2001 From: Justin Hammond Date: Sun, 2 Aug 2026 16:02:16 +0800 Subject: [PATCH 4/4] boards/risc-v/eic7700x: Enable the pinctrl procfs entry. Publishes /proc/pinctrl on both boards, which lists every pad with the function it currently carries. The startup banner counts how many pads differ from their reset values, once, at boot; this answers the same question at any later moment, which is what is wanted when a driver has just reconfigured a pad and the result is not what was expected. PINCTRL_PROCFS depends on FS_PROCFS_REGISTER, the entry registering itself at run time rather than being one of the built in ones. Neither board set it, and without it the symbol is dropped when the configuration is regenerated and the entry never appears, which is silent: the defconfig still reads as though the feature were on. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond --- boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig | 2 ++ boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig b/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig index bab5b3aa839d0..2b689a66f68e1 100644 --- a/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig +++ b/boards/risc-v/eic7700x/eic7700-evb/configs/nsh/defconfig @@ -73,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" @@ -91,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 71e9b276e1349..52d32bdaa792e 100644 --- a/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig +++ b/boards/risc-v/eic7700x/starpro64/configs/nsh/defconfig @@ -69,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" @@ -87,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