/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef _SOC_GPIO_H_ #define _SOC_GPIO_H_ #include #include #include #define CROS_GPIO_DEVICE_NAME "Braswell" #define COMMUNITY_SIZE 0x20000 #define COMMUNITY_GPSOUTHWEST_BASE \ (IO_BASE_ADDRESS + COMMUNITY_OFFSET_GPSOUTHWEST) #define COMMUNITY_GPNORTH_BASE \ (IO_BASE_ADDRESS + COMMUNITY_OFFSET_GPNORTH) #define COMMUNITY_GPEAST_BASE \ (IO_BASE_ADDRESS + COMMUNITY_OFFSET_GPEAST) #define COMMUNITY_GPSOUTHEAST_BASE \ (IO_BASE_ADDRESS + COMMUNITY_OFFSET_GPSOUTHEAST) #define GPIO_COMMUNITY_COUNT 4 #define GPIO_FAMILIES_MAX_PER_COMM 7 #define GP_SOUTHWEST 0 #define GP_NORTH 1 #define GP_EAST 2 #define GP_SOUTHEAST 3 #define COMMUNITY_BASE(community) \ (IO_BASE_ADDRESS + community * 0x8000) #define GP_READ_ACCESS_POLICY_BASE(community) \ (COMMUNITY_BASE(community) + 0x000) #define GP_WRITE_ACCESS_POLICY_BASE(community) \ (COMMUNITY_BASE(community) + 0x100) #define GP_WAKE_STATUS_REG_BASE(community) \ (COMMUNITY_BASE(community) + 0x200) #define GP_WAKE_MASK_REG_BASE(community) \ (COMMUNITY_BASE(community) + 0x280) #define GP_INT_STATUS_REG_BASE(community) \ (COMMUNITY_BASE(community) + 0x300) #define GP_INT_MASK_REG_BASE(community) \ (COMMUNITY_BASE(community) + 0x380) #define GP_FAMILY_RCOMP_CTRL(community, family) \ (COMMUNITY_BASE(community) + 0x1080 + 0x80 * family) #define GP_FAMILY_RCOMP_OFFSET(community, family) \ (COMMUNITY_BASE(community) + 0x1084 + 0x80 * family) #define GP_FAMILY_RCOMP_OVERRIDE(community, family) \ (COMMUNITY_BASE(community) + 0x1088 + 0x80 * family) #define GP_FAMILY_RCOMP_VALUE(community, family) \ (COMMUNITY_BASE(community) + 0x108C + 0x80 * family) #define GP_FAMILY_CONF_COMP(community, family) \ (COMMUNITY_BASE(community) + 0x1090 + 0x80 * family) #define GP_FAMILY_CONF_REG(community, family) \ (COMMUNITY_BASE(community) + 0x1094 + 0x80 * family) /* Value written into pad control reg 0 */ #define PAD_CONTROL_REG0_TRISTATE (PAD_CONFIG0_DEFAULT|PAD_GPIOFG_HI_Z) /* Calculate the MMIO Address for specific GPIO pin * control register pointed by index. */ #define FAMILY_NUMBER(gpio_pad) (gpio_pad / MAX_FAMILY_PAD_GPIO_NO) #define INTERNAL_PAD_NUM(gpio_pad) (gpio_pad % MAX_FAMILY_PAD_GPIO_NO) #define GPIO_OFFSET(gpio_pad) (FAMILY_PAD_REGS_OFF \ + (FAMILY_PAD_REGS_SIZE * FAMILY_NUMBER(gpio_pad) \ + (GPIO_REGS_SIZE * INTERNAL_PAD_NUM(gpio_pad)))) /* Gpio to Pad mapping */ #define SDMMC1_CMD_MMIO_OFFSET GPIO_OFFSET(23) #define SDMMC1_D0_MMIO_OFFSET GPIO_OFFSET(17) #define SDMMC1_D1_MMIO_OFFSET GPIO_OFFSET(24) #define SDMMC1_D2_MMIO_OFFSET GPIO_OFFSET(20) #define SDMMC1_D3_MMIO_OFFSET GPIO_OFFSET(26) #define MMC1_D4_SD_WE_MMIO_OFFSET GPIO_OFFSET(67) #define MMC1_D5_MMIO_OFFSET GPIO_OFFSET(65) #define MMC1_D6_MMIO_OFFSET GPIO_OFFSET(63) #define MMC1_D7_MMIO_OFFSET GPIO_OFFSET(68) #define MMC1_RCLK_OFFSET GPIO_OFFSET(69) #define HV_DDI2_DDC_SDA_MMIO_OFFSET GPIO_OFFSET(62) #define HV_DDI2_DDC_SCL_MMIO_OFFSET GPIO_OFFSET(67) #define CFIO_139_MMIO_OFFSET GPIO_OFFSET(64) #define CFIO_140_MMIO_OFFSET GPIO_OFFSET(67) /* GPIO Security registers offset */ #define GPIO_READ_ACCESS_POLICY_REG 0x0000 #define GPIO_WRITE_ACCESS_POLICY_REG 0x0100 #define GPIO_WAKE_STATUS_REG 0x0200 #define GPIO_WAKE_MASK_REG0 0x0280 #define GPIO_WAKE_MASK_REG1 0x0284 #define GPIO_INTERRUPT_STATUS 0x0300 #define GPIO_INTERRUPT_MASK 0x0380 #define GPE0A_STS_REG 0x20 #define GPE0A_EN_REG 0x28 #define ALT_GPIO_SMI_REG 0x38 #define GPIO_ROUT_REG 0x58 /* Pad register offset */ #define PAD_CONF0_REG 0x0 #define PAD_CONF1_REG 0x4 /* Number of GPIOs in each bank */ #define GP_SOUTHWEST_COUNT 56 #define GP_NORTH_COUNT 59 #define GP_EAST_COUNT 24 #define GP_SOUTHEAST_COUNT 55 #define MAX_GPIO_CNT (GP_SOUTHWEST_COUNT + GP_NORTH_COUNT + GP_EAST_COUNT + GP_SOUTHEAST_COUNT) /* General */ #define GPIO_REGS_SIZE 8 #define NA 0 #define MASK_WAKE 0 #define UNMASK_WAKE 1 #define GPE_CAPABLE 1 #define GPE_CAPABLE_NONE 0 #define MAX_FAMILY_PAD_GPIO_NO 15 #define FAMILY_PAD_REGS_OFF 0x4400 #define FAMILY_PAD_REGS_SIZE 0x400 /* config0[31:28] - Interrupt Selection Interrupt Select */ #define PAD_INT_SEL(int_s) (int_s << 28) /* config0[27:26] - Glitch Filter Config */ #define PAD_GFCFG(glitch_cfg) (glitch_cfg << 26) #define PAD_GFCFG_DISABLE (0 << 26) #define PAD_ENABLE_EDGE_DETECTION (1 << 26) /* EDGE DETECTION ONLY */ #define PAD_ENABLE_RX_DETECTION (2 << 26) /* RX DETECTION ONLY */ #define PAD_ENABLE_EDGE_RX_DETECTION (3 << 26) /* RX & EDGE DETECTION */ /* config0[25:24] - RX/TX Enable Config */ #define PAD_FUNC_CTRL(tx_rx_enable) (tx_rx_enable << 24) #define PAD_FUNC_CTRL_RX_TX_ENABLE (0 << 24) #define PAD_FUNC_CTRL_TX_ENABLE_RX_DISABLE (1 << 24) #define PAD_FUNC_CTRL_TX_ENABLE_RX_ENABLE (2 << 24) #define PAD_TX_RX_ENABLE (3 << 24) /* config0[23:20] - Termination */ #define PAD_PULL(TERM) (TERM << 20) #define PAD_PULL_DISABLE (0 << 20) #define PAD_PULL_DOWN_20K (1 << 20) #define PAD_PULL_DOWN_5K (2 << 20) #define PAD_PULL_DOWN_1K (4 << 20) #define PAD_PULL_UP_20K (9 << 20) #define PAD_PULL_UP_5K (10 << 20) #define PAD_PULL_UP_1K (12 << 20) /* config0[19:16] - PAD Mode */ #define PAD_MODE_SELECTION(MODE_SEL) (MODE_SEL<<16) #define SET_PAD_MODE_SELECTION(pad_config, mode) \ ((pad_config & 0xfff0ffff) | PAD_MODE_SELECTION(mode)) /* config0[15] - GPIO Enable */ #define PAD_GPIO_DISABLE (0 << 15) #define PAD_GPIO_ENABLE (1 << 15) /* config0[14:11] - Reserver2 */ /* config0[10:8] - GPIO Config */ #define PAD_GPIO_CFG(gpio_cfg) (gpio_cfg << 8) #define PAD_GPIOFG_GPIO (0 << 8) #define PAD_GPIOFG_GPO (1 << 8) #define PAD_GPIOFG_GPI (2 << 8) #define PAD_GPIOFG_HI_Z (3 << 8) /* config0[7] - Gpio Light Mode Bar */ /* config0[6:2] - Reserved1 */ /* config0[1] - GPIO TX State */ #define PAD_DEFAULT_TX(STATE) (STATE<<1) /* config0[0] - GPIO RX State */ #define PAD_RX_BIT 1 /* Pad Control Register 1 configuration */ #define PAD_DISABLE_INT (0 << 0) #define PAD_TRIG_EDGE_LOW (1 << 0) #define PAD_TRIG_EDGE_HIGH (2 << 0) #define PAD_TRIG_EDGE_BOTH (3 << 0) #define PAD_TRIG_EDGE_LEVEL (4 << 0) /* Pad config0 power-on values */ #define PAD_CONFIG0_DEFAULT 0x00010300 #define PAD_CONFIG0_DEFAULT0 0x00910300 #define PAD_CONFIG0_DEFAULT1 0x00110300 #define PAD_CONFIG0_GPI_DEFAULT 0x00010200 /* Pad config1 reg power-on values */ #define PAD_CONFIG1_DEFAULT0 0x05C00000 #define PAD_CONFIG1_CSEN 0x0DC00000 #define PAD_CONFIG1_DEFAULT1 0x05C00020 #define GPIO_INPUT_PULL(pull) \ { .pad_conf0 = pull | PAD_GPIO_ENABLE | PAD_CONFIG0_GPI_DEFAULT, \ .pad_conf1 = PAD_CONFIG1_DEFAULT0 } #define GPIO_INPUT_NO_PULL GPIO_INPUT_PULL(PAD_PULL_DISABLE) #define GPIO_INPUT_PU_20K GPIO_INPUT_PULL(PAD_PULL_UP_20K) #define GPIO_INPUT_PU_5K GPIO_INPUT_PULL(PAD_PULL_UP_5K) #define GPIO_INPUT_PU_1K GPIO_INPUT_PULL(PAD_PULL_UP_1K) #define GPIO_INPUT_PD_20K GPIO_INPUT_PULL(PAD_PULL_DOWN_20K) #define GPIO_INPUT_PD_5K GPIO_INPUT_PULL(PAD_PULL_DOWN_5K) #define GPIO_INPUT_PD_1K GPIO_INPUT_PULL(PAD_PULL_DOWN_1K) #define GPI(int_type, int_sel, term, int_msk, glitch_cfg, wake_msk, gpe_val) { \ .pad_conf0 = PAD_INT_SEL(int_sel) | PAD_GFCFG(glitch_cfg) \ | PAD_PULL(term) | PAD_GPIO_ENABLE | PAD_GPIOFG_GPI, \ .pad_conf1 = int_type << 0 | PAD_CONFIG1_DEFAULT0, \ .wake_mask = wake_msk, \ .int_mask = int_msk, \ .gpe = gpe_val } #define GPO_FUNC(term, tx_state) {\ .pad_conf0 = PAD_GPIO_ENABLE | PAD_GPIOFG_GPO | PAD_PULL(term) \ | tx_state << 1, \ .pad_conf1 = PAD_CONFIG1_DEFAULT0 } #define NATIVE_FUNC(mode, term, inv_rx_tx) {\ .pad_conf0 = PAD_GPIO_DISABLE | PAD_GPIOFG_HI_Z \ | PAD_MODE_SELECTION(mode) | PAD_PULL(term),\ .pad_conf1 = PAD_CONFIG1_DEFAULT0 | inv_rx_tx << 4 } #define NATIVE_FUNC_TX_RX(tx_rx_enable, mode, term, inv_rx_tx) {\ .pad_conf0 = PAD_FUNC_CTRL(tx_rx_enable) | PAD_GPIO_DISABLE \ | PAD_GPIOFG_GPIO | PAD_MODE_SELECTION(mode) \ | PAD_PULL(term),\ .pad_conf1 = PAD_CONFIG1_DEFAULT0 | inv_rx_tx << 4 } #define NATIVE_FUNC_CSEN(mode, term, inv_rx_tx) {\ .pad_conf0 = PAD_GPIO_DISABLE | PAD_GPIOFG_HI_Z \ | PAD_MODE_SELECTION(mode) | PAD_PULL(term),\ .pad_conf1 = PAD_CONFIG1_CSEN | inv_rx_tx << 4 } #define NATIVE_INT(mode, int_sel) {\ .pad_conf0 = PAD_INT_SEL(int_sel) | PAD_GPIO_DISABLE \ | PAD_GPIOFG_HI_Z | PAD_MODE_SELECTION(mode),\ .pad_conf1 = PAD_CONFIG1_DEFAULT0 } #define NATIVE_INT_PU20K(mode, int_sel) {\ .pad_conf0 = PAD_PULL_UP_20K | PAD_INT_SEL(int_sel) | PAD_GPIO_DISABLE \ | PAD_GPIOFG_HI_Z | PAD_MODE_SELECTION(mode),\ .pad_conf1 = PAD_CONFIG1_DEFAULT0 } #define SPEAKER \ { .pad_conf0 = PAD_CONFIG0_DEFAULT0, \ .pad_conf1 = PAD_CONFIG1_DEFAULT0 } #define SPARE_PIN\ { .pad_conf0 = 0x00110300,\ .pad_conf1 = PAD_CONFIG1_DEFAULT0 } /* SCI , SMI, Wake */ #define GPIO_SCI(int_sel) \ { .pad_conf0 = PAD_PULL_DISABLE | PAD_ENABLE_EDGE_RX_DETECTION\ | PAD_GPIO_ENABLE | PAD_GPIOFG_GPI \ | PAD_INT_SEL(int_sel), \ .pad_conf1 = PAD_TRIG_EDGE_LOW | PAD_CONFIG1_DEFAULT0, \ .gpe = SCI, \ .int_mask = 1 } #define GPIO_WAKE(int_sel) \ { .pad_conf0 = PAD_PULL_DISABLE | PAD_ENABLE_EDGE_RX_DETECTION\ | PAD_GPIO_ENABLE | PAD_GPIOFG_GPI \ | PAD_INT_SEL(int_sel), \ .pad_conf1 = PAD_TRIG_EDGE_LOW | PAD_CONFIG1_DEFAULT0, \ .int_mask = 1,\ .wake_mask = 1 } #define GPIO_SMI(int_sel) \ { .pad_conf0 = PAD_PULL_DISABLE | PAD_ENABLE_EDGE_RX_DETECTION\ | PAD_GPIO_ENABLE | PAD_GPIOFG_GPI \ | PAD_INT_SEL(int_sel), \ .pad_conf1 = PAD_TRIG_EDGE_LOW | PAD_CONFIG1_DEFAULT0, \ .int_mask = 1,\ .gpe = SMI } #define GPIO_SKIP { .skip_config = 1 } /* Common GPIO settings */ #define NATIVE_DEFAULT(mode) NATIVE_FUNC(mode, 0, 0) /* no pull */ #define NATIVE_PU20K(mode) NATIVE_FUNC(mode, 9, 0) /* PH 20k */ #define NATIVE_PU5K(mode) NATIVE_FUNC(mode, 10, 0) /* PH 5k */ #define NATIVE_PU5K_INVTX(mode) NATIVE_FUNC(mode, 10, inv_tx_enable) /* PH 5k */ #define NATIVE_PU1K(mode) NATIVE_FUNC(mode, 12, 0) /* PH 1k */ #define NATIVE_PU1K_CSEN_INVTX(mode) \ NATIVE_FUNC_CSEN(mode, 12, inv_tx_enable) /* PH 1k */ #define NATIVE_PU1K_INVTX(mode) NATIVE_FUNC(mode, 12, inv_tx_enable) /* PH 1k */ #define NATIVE_PD20K(mode) NATIVE_FUNC(mode, 1, 0) /* PD 20k */ #define NATIVE_PD5K(mode) NATIVE_FUNC(mode, 2, 0) /* PD 5k */ #define NATIVE_PD1K(mode) NATIVE_FUNC(mode, 4, 0) /* PD 1k */ #define NATIVE_PD1K_CSEN_INVTX(mode) NATIVE_FUNC_CSEN(mode, 4, inv_tx_enable) /* no pull */ #define NATIVE_TX_RX_EN NATIVE_FUNC_TX_RX(3, 1, 0, inv_tx_enable) #define NATIVE_TX_RX_M1 NATIVE_FUNC_TX_RX(0, 1, 0, 0) /* no pull */ #define NATIVE_TX_RX_M3 NATIVE_FUNC_TX_RX(0, 3, 0, 0) /* no pull */ #define NATIVE_PU1K_M1 NATIVE_PU1K(1) /* PU1k M1 */ /* Default native functions */ #define Native_M0 NATIVE_DEFAULT(0) #define Native_M1 NATIVE_DEFAULT(1) #define Native_M2 NATIVE_DEFAULT(2) #define Native_M3 NATIVE_DEFAULT(3) #define Native_M4 NATIVE_DEFAULT(4) #define Native_M5 NATIVE_DEFAULT(5) #define Native_M6 NATIVE_DEFAULT(6) #define Native_M7 NATIVE_DEFAULT(7) #define Native_M8 NATIVE_DEFAULT(8) #define GPIO_OUT_LOW GPO_FUNC(0, 0) /* gpo low */ #define GPIO_OUT_HIGH GPO_FUNC(0, 1) /* gpo high */ #define GPIO_NC GPIO_INPUT_PU_20K /* not connect */ /* End marker */ #define GPIO_LIST_END 0xffffffff #define GPIO_END \ { .pad_conf0 = GPIO_LIST_END } /* Functions / defines for changing GPIOs in romstage */ #define UART_RXD_PAD 82 #define UART_TXD_PAD 83 #define PCU_SMB_CLK_PAD 88 #define PCU_SMB_DATA_PAD 90 #define SOC_DDI1_VDDEN_PAD 16 #define UART1_RXD_PAD 9 #define UART1_TXD_PAD 13 #define DDI2_DDC_SCL 48 #define DDI2_DDC_SDA 53 struct soc_gpio_map { u32 pad_conf0; u32 pad_conf1; u32 gpe; u32 int_mask:1; u32 wake_mask:1; u32 is_gpio:1; u32 skip_config:1; } __packed; struct soc_gpio_config { const struct soc_gpio_map *north; const struct soc_gpio_map *southeast; const struct soc_gpio_map *southwest; const struct soc_gpio_map *east; }; /* Description of a GPIO 'community' */ struct gpio_bank { const int gpio_count; const u8 *gpio_to_pad; const unsigned long pad_base; const u8 has_gpe_en:1; const u8 has_wake_en:1; }; typedef enum { P_NONE = 0, /* Pull None */ P_20K_L = 1, /* Pull Down 20K */ P_5K_L = 2, /* Pull Down 5K */ P_1K_L = 4, /* Pull Down 1K */ P_20K_H = 9, /* Pull Up 20K */ P_5K_H = 10, /* Pull Up 5K */ P_1K_H = 12 /* Pull Up 1K */ } pull_type_t; typedef enum { M0 = 0, M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, } mode_list_t; typedef enum { L0 = 0, L1 = 1, L2 = 2, L3 = 3, L4 = 4, L5 = 5, L6 = 6, L7 = 7, L8 = 8, L9 = 9, L10 = 10, L11 = 11, L12 = 12, L13 = 13, L14 = 14, L15 = 15, } int_select_t; typedef enum { INT_DIS = 0, trig_edge_low = PAD_TRIG_EDGE_LOW, trig_edge_high = PAD_TRIG_EDGE_HIGH, trig_edge_both = PAD_TRIG_EDGE_BOTH, trig_level_high = PAD_TRIG_EDGE_LEVEL | (0 << 4), trig_level_low = PAD_TRIG_EDGE_LEVEL | (4 << 4), } int_type_t; typedef enum { glitch_disable = 0, en_edge_detect, en_rx_data, en_edge_rx_data, } glitch_cfg; typedef enum { maskable = 0, non_maskable, } mask_t; typedef enum { GPE = 0, SMI, SCI, } gpe_config_t; /* * InvertRxTx 7:4 * 0 - No Inversion * 1 - Inversion * [0] RX Enable * [1] TX Enable * [2] RX Data * [3] TX Data */ typedef enum { no_inversion = 0, inv_rx_enable = 0x1, inv_tx_enable = 0x2, inv_rx_tx_enable = 0x3, inv_rx_data = 0x4, inv_tx_data = 0x8, } invert_rx_tx_t; #define PAD_VAL_HIGH (1 << 0) void setup_soc_gpios(struct soc_gpio_config *config, u8 enable_xdp_tap); struct soc_gpio_config *mainboard_get_gpios(void); typedef int gpio_t; int get_gpio(int community_base, int pad0_offset); uint16_t gpio_family_number(uint8_t community, uint8_t pad); uint32_t *gpio_pad_config_reg(uint8_t community, uint8_t pad); void lpc_init(void); void lpc_set_low_power(void); #endif /* _SOC_GPIO_H_ */