Ravi kumar has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/47077 )
Change subject: SC7280: Add GPIO driver in coreboot ......................................................................
SC7280: Add GPIO driver in coreboot
Add support for gpio driver for SC7280
Change-Id: Ibefa2fc04db09f1837f65f5a6d4b8534df040785 --- M src/soc/qualcomm/sc7280/Makefile.inc A src/soc/qualcomm/sc7280/gpio.c M src/soc/qualcomm/sc7280/include/soc/addressmap.h M src/soc/qualcomm/sc7280/include/soc/gpio.h 4 files changed, 378 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/47077/1
diff --git a/src/soc/qualcomm/sc7280/Makefile.inc b/src/soc/qualcomm/sc7280/Makefile.inc index f94a425..a6112b3 100644 --- a/src/soc/qualcomm/sc7280/Makefile.inc +++ b/src/soc/qualcomm/sc7280/Makefile.inc @@ -8,12 +8,14 @@ bootblock-y += spi.c bootblock-$(CONFIG_SC7280_QSPI) += qspi.c bootblock-y += clock.c +bootblock-y += gpio.c
################################################################################ verstage-y += timer.c verstage-y += spi.c verstage-$(CONFIG_SC7280_QSPI) += qspi.c verstage-y += clock.c +verstage-y += gpio.c
################################################################################ romstage-y += cbmem.c @@ -25,6 +27,7 @@ romstage-y += spi.c romstage-$(CONFIG_SC7280_QSPI) += qspi.c romstage-y += clock.c +romstage-y += gpio.c
################################################################################ ramstage-y += soc.c @@ -33,6 +36,7 @@ ramstage-y += spi.c ramstage-$(CONFIG_SC7280_QSPI) += qspi.c ramstage-y += clock.c +ramstage-y += gpio.c
################################################################################
diff --git a/src/soc/qualcomm/sc7280/gpio.c b/src/soc/qualcomm/sc7280/gpio.c new file mode 100644 index 0000000..67204e8 --- /dev/null +++ b/src/soc/qualcomm/sc7280/gpio.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <device/mmio.h> +#include <types.h> + +#include <gpio.h> + +void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, + uint32_t drive_str, uint32_t enable) +{ + uint32_t reg_val; + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + /* gpio pull only PULLNONE, PULLUP, KEEPER, PULLDOWN status */ + assert(pull <= GPIO_PULL_UP); + + reg_val = ((enable & GPIO_CFG_OE_BMSK) << GPIO_CFG_OE_SHFT) | + ((drive_str & GPIO_CFG_DRV_BMSK) << GPIO_CFG_DRV_SHFT) | + ((func & GPIO_CFG_FUNC_BMSK) << GPIO_CFG_FUNC_SHFT) | + ((pull & GPIO_CFG_PULL_BMSK) << GPIO_CFG_PULL_SHFT); + + write32(®s->cfg, reg_val); +} + +void gpio_set(gpio_t gpio, int value) +{ + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + write32(®s->in_out, (!!value) << GPIO_IO_OUT_SHFT); +} + +int gpio_get(gpio_t gpio) +{ + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + return ((read32(®s->in_out) >> GPIO_IO_IN_SHFT) & + GPIO_IO_IN_BMSK); +} + +void gpio_input_pulldown(gpio_t gpio) +{ + gpio_configure(gpio, GPIO_FUNC_GPIO, + GPIO_PULL_DOWN, GPIO_2MA, GPIO_OUTPUT_DISABLE); +} + +void gpio_input_pullup(gpio_t gpio) +{ + gpio_configure(gpio, GPIO_FUNC_GPIO, + GPIO_PULL_UP, GPIO_2MA, GPIO_OUTPUT_DISABLE); +} + +void gpio_input(gpio_t gpio) +{ + gpio_configure(gpio, GPIO_FUNC_GPIO, + GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_DISABLE); +} + +void gpio_output(gpio_t gpio, int value) +{ + gpio_set(gpio, value); + gpio_configure(gpio, GPIO_FUNC_GPIO, + GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_ENABLE); +} + +void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull) +{ + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + gpio_configure(gpio, GPIO_FUNC_GPIO, + pull, GPIO_2MA, GPIO_OUTPUT_DISABLE); + + clrsetbits32(®s->intr_cfg, GPIO_INTR_DECT_CTL_MASK << + GPIO_INTR_DECT_CTL_SHIFT, type << GPIO_INTR_DECT_CTL_SHIFT); + clrsetbits32(®s->intr_cfg, GPIO_INTR_RAW_STATUS_ENABLE + << GPIO_INTR_RAW_STATUS_EN_SHIFT, GPIO_INTR_RAW_STATUS_ENABLE + << GPIO_INTR_RAW_STATUS_EN_SHIFT); +} + +int gpio_irq_status(gpio_t gpio) +{ + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + if (!(read32(®s->intr_status) & GPIO_INTR_STATUS_MASK)) + return 0; + + write32(®s->intr_status, GPIO_INTR_STATUS_DISABLE); + return 1; +} diff --git a/src/soc/qualcomm/sc7280/include/soc/addressmap.h b/src/soc/qualcomm/sc7280/include/soc/addressmap.h index ae31b1c..d2e50f2 100644 --- a/src/soc/qualcomm/sc7280/include/soc/addressmap.h +++ b/src/soc/qualcomm/sc7280/include/soc/addressmap.h @@ -8,5 +8,6 @@ #define AOSS_CC_BASE 0x0C2A0000 #define GCC_BASE 0x00100000 #define QSPI_BASE 0x088DC000 +#define TLMM_TILE_BASE 0x0F100000
#endif /* __SOC_QUALCOMM_SC7280_ADDRESS_MAP_H__ */ diff --git a/src/soc/qualcomm/sc7280/include/soc/gpio.h b/src/soc/qualcomm/sc7280/include/soc/gpio.h index 82a0c39..744ba49 100644 --- a/src/soc/qualcomm/sc7280/include/soc/gpio.h +++ b/src/soc/qualcomm/sc7280/include/soc/gpio.h @@ -4,9 +4,293 @@ #define _SOC_QUALCOMM_SC7280_GPIO_H_
#include <types.h> +#include <soc/addressmap.h>
typedef struct { u32 addr; } gpio_t;
+#define TLMM_TILE_SIZE 0x00300000 +#define TLMM_GPIO_OFF_DELTA 0x1000 + +#define TLMM_GPIO_IN_OUT_OFF 0x4 +#define TLMM_GPIO_ID_STATUS_OFF 0x10 + +#define GPIO_FUNC_GPIO 0 + +/* GPIO INTR CFG MASK */ +#define GPIO_INTR_DECT_CTL_MASK 0x3 +#define GPIO_INTR_RAW_STATUS_EN_MASK 0x1 + +/* GPIO INTR CFG SHIFT */ +#define GPIO_INTR_DECT_CTL_SHIFT 2 +#define GPIO_INTR_RAW_STATUS_EN_SHIFT 4 + +/* GPIO INTR STATUS MASK */ +#define GPIO_INTR_STATUS_MASK 0x1 + +/* GPIO INTR RAW STATUS */ +#define GPIO_INTR_RAW_STATUS_ENABLE 1 +#define GPIO_INTR_RAW_STATUS_DISABLE 0 + +/* GPIO INTR STATUS */ +#define GPIO_INTR_STATUS_ENABLE 1 +#define GPIO_INTR_STATUS_DISABLE 0 + +/* GPIO TLMM: Direction */ +#define GPIO_INPUT 0 +#define GPIO_OUTPUT 1 + +/* GPIO TLMM: Pullup/Pulldown */ +#define GPIO_NO_PULL 0 +#define GPIO_PULL_DOWN 1 +#define GPIO_KEEPER 2 +#define GPIO_PULL_UP 3 + +/* GPIO TLMM: Drive Strength */ +#define GPIO_2MA 0 +#define GPIO_4MA 1 +#define GPIO_6MA 2 +#define GPIO_8MA 3 +#define GPIO_10MA 4 +#define GPIO_12MA 5 +#define GPIO_14MA 6 +#define GPIO_16MA 7 + +/* GPIO TLMM: Status */ +#define GPIO_OUTPUT_DISABLE 0 +#define GPIO_OUTPUT_ENABLE 1 + +/* GPIO TLMM: Mask */ +#define GPIO_CFG_PULL_BMSK 0x3 +#define GPIO_CFG_FUNC_BMSK 0xF +#define GPIO_CFG_DRV_BMSK 0x7 +#define GPIO_CFG_OE_BMSK 0x1 + +/* GPIO TLMM: Shift */ +#define GPIO_CFG_PULL_SHFT 0 +#define GPIO_CFG_FUNC_SHFT 2 +#define GPIO_CFG_DRV_SHFT 6 +#define GPIO_CFG_OE_SHFT 9 + +/* GPIO IO: Mask */ +#define GPIO_IO_IN_BMSK 0x1 +#define GPIO_IO_OUT_BMSK 0x1 + +/* GPIO IO: Shift */ +#define GPIO_IO_IN_SHFT 0 +#define GPIO_IO_OUT_SHFT 1 + +/* GPIO ID STATUS: Mask */ +#define GPIO_ID_STATUS_BMSK 0x1 + +/* GPIO MAX Valid # */ +#define GPIO_NUM_MAX 174 + +#define GPIO(num) ((gpio_t){.addr = GPIO##num##_ADDR}) + +#define PIN(index, func1, func2, func3, func4) \ +GPIO##index##_ADDR = TLMM_TILE_BASE + index * TLMM_GPIO_OFF_DELTA, \ +GPIO##index##_FUNC_##func1 = 1, \ +GPIO##index##_FUNC_##func2 = 2, \ +GPIO##index##_FUNC_##func3 = 3, \ +GPIO##index##_FUNC_##func4 = 4 + +enum { + PIN(0, QUP0_L0, RES_2, RES_3, RES_4), + PIN(1, QUP0_L1, RES_2, RES_3, RES_4), + PIN(2, QUP0_L2, QUP0_L4, RES_3, RES_4), + PIN(3, QUP0_L3, QUP0_L5, RES_3, RES_4), + PIN(4, QUP0_L0, RES_2, RES_3, RES_4), + PIN(5, QUP0_L1, RES_2, RES_3, RES_4), + PIN(6, QUP0_L2, QUP0_L6, RES_3, RES_4), + PIN(7, USB_AUDIO_INT_N__SBU_SW_OE, QUP0_L3, RES_3, RES_4), + PIN(8, QUP0_L0, RES_2, RES_3, RES_4), + PIN(9, QUP0_L1, RES_2, RES_3, RES_4), + PIN(10, GNSS_ELNA_EN0, QUP0_L2, RES_3, RES_4), + PIN(11, GNSS_ELNA_EN1, QUP0_L3, RES_3, RES_4), + PIN(12, QUP0_L0, QSPI_DATA_0, RES_3, RES_4), + PIN(13, QUP0_L1, QSPI_DATA_1, RES_3, RES_4), + PIN(14, QUP0_L2, QSPI_CLK, RES_3, RES_4), + PIN(15, QUP0_L3, QSPI_CS_N_0, RES_3, RES_4), + PIN(16, QUP0_L0, QSPI_DATA_2, RES_3, RES_4), + PIN(17, QUP0_L1, QSPI_DATA_3, RES_3, RES_4), + PIN(18, QUP0_L2, RES_2, RES_3, RES_4), + PIN(19, QUP0_L3, QSPI_CS_N_1, RES_3, RES_4), + PIN(20, QUP0_L0, CCI_TIMER_0, RES_3, RES_4), + PIN(21, QUP0_L1, CCI_TIMER_1, RES_3, RES_4), + PIN(22, QUP0_L2, RES_2, RES_3, RES_4), + PIN(23, QUP0_L3, RES_2, RES_3, RES_4), + PIN(24, QUP0_L0, RES_2, RES_3, RES_4), + PIN(25, QUP0_L1, RES_2, RES_3, RES_4), + PIN(26, QUP0_L2, RES_2, RES_3, RES_4), + PIN(27, QUP0_L3, RES_2, RES_3, RES_4), + PIN(28, QUP0_L0, RES_2, RES_3, RES_4), + PIN(29, QUP0_L1, RES_2, RES_3, RES_4), + PIN(30, QUP0_L2, RES_2, RES_3, RES_4), + PIN(31, QUP0_L3, RES_2, RES_3, RES_4), + PIN(32, QUP1_L0, RES_2, RES_3, RES_4), + PIN(33, QUP1_L1, RES_2, RES_3, RES_4), + PIN(34, QUP1_L2, RES_2, RES_3, RES_4), + PIN(35, QUP1_L3, RES_2, RES_3, RES_4), + PIN(36, QUP1_L0, RES_2, RES_3, RES_4), + PIN(37, QUP1_L1, RES_2, RES_3, RES_4), + PIN(38, QUP1_L2, QUP1_L6, RES_3, RES_4), + PIN(39, QUP1_L3, RES_2, RES_3, RES_4), + PIN(40, QUP1_L0, RES_2, RES_3, RES_4), + PIN(41, QUP1_L1, RES_2, RES_3, RES_4), + PIN(42, QUP1_L2, RES_2, RES_3, RES_4), + PIN(43, QUP1_L3, RES_2, RES_3, RES_4), + PIN(44, QUP1_L0, RES_2, RES_3, RES_4), + PIN(45, QUP1_L1, RES_2, RES_3, RES_4), + PIN(46, QUP1_L2, RES_2, RES_3, RES_4), + PIN(47, QUP1_L3, DP_HOT_PLUG_DETECT, RES_3, RES_4), + PIN(48, QUP1_L0, RES_2, RES_3, RES_4), + PIN(49, QUP1_L1, RES_2, RES_3, RES_4), + PIN(50, QUP1_L2, QUP1_L6, RES_3, RES_4), + PIN(51, QUP1_L3, RES_2, RES_3, RES_4), + PIN(52, QUP1_L0, RES_2, RES_3, RES_4), + PIN(53, QUP1_L1, RES_2, RES_3, RES_4), + PIN(54, QUP1_L2, QUP1_L5, RES_3, RES_4), + PIN(55, QUP1_L3, QUP1_L4, RES_3, RES_4), + PIN(56, QUP1_L0, RES_2, RES_3, RES_4), + PIN(57, QUP1_L1, RES_2, RES_3, RES_4), + PIN(58, QUP1_L2, RES_2, RES_3, RES_4), + PIN(59, QUP1_L3, RES_2, RES_3, RES_4), + PIN(60, QUP1_L0, EDP_HOT_PLUG_DETECT, RES_3, RES_4), + PIN(61, QUP1_L1, SD_WRITE_PROTECT, RES_3, RES_4), + PIN(62, QUP1_L2, QUP1_L4, RES_3, RES_4), + PIN(63, QUP1_L3, QUP1_L5, RES_3, RES_4), + PIN(64, CAM_MCLK0, RES_2, RES_3, RES_4), + PIN(65, CAM_MCLK1, RES_2, RES_3, RES_4), + PIN(66, CAM_MCLK2, RES_2, RES_3, RES_4), + PIN(67, CAM_MCLK3, RES_2, RES_3, RES_4), + PIN(68, CAM_MCLK4, RES_2, RES_3, RES_4), + PIN(69, CCI_I2C_SDA0, RES_2, RES_3, RES_4), + PIN(70, CCI_I2C_SCL0, RES_2, RES_3, RES_4), + PIN(71, CCI_I2C_SDA1, RES_2, RES_3, RES_4), + PIN(72, CCI_I2C_SCL1, RES_2, RES_3, RES_4), + PIN(73, CCI_I2C_SDA2, RES_2, RES_3, RES_4), + PIN(74, CCI_I2C_SCL2, RES_2, RES_3, RES_4), + PIN(75, CCI_I2C_SDA3, RES_2, RES_3, RES_4), + PIN(76, CCI_I2C_SCL3, GCC_GP1_CLK_MIRB, RES_3, RES_4), + PIN(77, CCI_TIMER2, GCC_GP2_CLK_MIRB, RES_3, RES_4), + PIN(78, CCI_TIMER3, CCI_ASYNC_IN1, GCC_GP3_CLK_MIRB, RES_4), + PIN(79, CCI_TIMER4, CCI_ASYNC_IN2, RES_3, RES_4), + PIN(80, RES_1, RES_2, RES_3, RES_4), + PIN(81, RES_1, RES_2, RES_3, RES_4), + PIN(82, RES_1, RES_2, RES_3, RES_4), + PIN(83, RES_1, RES_2, RES_3, RES_4), + PIN(84, USB2PHY_AC_EN0, RES_2, RES_3, RES_4), + PIN(85, USB2PHY_AC_EN1, RES_2, RES_3, RES_4), + PIN(86, RES_1, RES_2, RES_3, RES_4), + PIN(87, RES_1, RES_2, RES_3, RES_4), + PIN(88, RES_1, RES_2, RES_3, RES_4), + PIN(89, RES_1, RES_2, RES_3, RES_4), + PIN(90, RES_1, RES_2, RES_3, RES_4), + PIN(91, RES_1, RES_2, RES_3, RES_4), + PIN(92, RES_1, RES_2, RES_3, RES_4), + PIN(93, CAM_MCLK5, CCI_ASYNC_IN0, RES_3, RES_4), + PIN(94, LPASS_SLIMBUS_CLK, RES_2, RES_3, RES_4), + PIN(95, LPASS_SLIMBUS_DATA0, RES_2, RES_3, RES_4), + PIN(96, PRI_MI2S_MCLK, RES_2, RES_3, RES_4), + PIN(97, MI2S0_SCK, RES_2, RES_3, RES_4), + PIN(98, MI2S0_DATA0, RES_2, RES_3, RES_4), + PIN(99, MI2S0_DATA1, RES_2, RES_3, RES_4), + PIN(100, MI2S0_WS, RES_2, RES_3, RES_4), + PIN(101, MI2S2_SCK, RES_2, RES_3, RES_4), + PIN(102, MI2S2_DATA0, RES_2, RES_3, RES_4), + PIN(103, MI2S2_WS, RES_2, RES_3, RES_4), + PIN(104, MI2S2_DATA1, RES_2, RES_3, RES_4), + PIN(105, SEC_MI2S_MCLK, MI2S1_DATA1, RES_3, GCC_GP1_CLK_MIRA), + PIN(106, MI2S1_SCK, GCC_GP2_CLK_MIRA, RES_3, RES_4), + PIN(107, MI2S1_DATA0, GCC_GP3_CLK_MIRA, RES_3, RES_4), + PIN(108, MI2S1_WS, RES_2, RES_3, RES_4), + PIN(109, RES_1, RES_2, RES_3, RES_4), + PIN(110, RES_1, RES_2, RES_3, RES_4), + PIN(111, RES_1, RES_2, RES_3, RES_4), + PIN(112, RES_1, RES_2, RES_3, RES_4), + PIN(113, RES_1, RES_2, RES_3, RES_4), + PIN(114, RES_1, RES_2, RES_3, RES_4), + PIN(115, RES_1, RES_2, RES_3, RES_4), + PIN(116, RES_1, RES_2, RES_3, RES_4), + PIN(117, RES_1, RES_2, RES_3, RES_4), + PIN(118, RES_1, RES_2, RES_3, RES_4), + PIN(119, RES_1, RES_2, RES_3, RES_4), + PIN(120, RES_1, RES_2, RES_3, RES_4), + PIN(121, RES_1, RES_2, RES_3, RES_4), + PIN(122, RES_1, RES_2, RES_3, RES_4), + PIN(123, RES_1, RES_2, RES_3, RES_4), + PIN(124, RES_1, RES_2, RES_3, RES_4), + PIN(125, RES_1, RES_2, RES_3, RES_4), + PIN(126, RES_1, RES_2, RES_3, RES_4), + PIN(127, RES_1, RES_2, RES_3, RES_4), + PIN(128, RES_1, RES_2, RES_3, RES_4), + PIN(129, RES_1, RES_2, RES_3, RES_4), + PIN(130, RES_1, RES_2, RES_3, RES_4), + PIN(131, RES_1, RES_2, RES_3, RES_4), + PIN(132, RES_1, RES_2, RES_3, RES_4), + PIN(133, RES_1, RES_2, RES_3, RES_4), + PIN(134, RES_1, RES_2, RES_3, RES_4), + PIN(135, RES_1, RES_2, RES_3, RES_4), + PIN(136, RES_1, RES_2, RES_3, RES_4), + PIN(137, RES_1, RES_2, RES_3, RES_4), + PIN(138, RES_1, RES_2, RES_3, RES_4), + PIN(139, RES_1, RES_2, RES_3, RES_4), + PIN(140, USB_PHY_PS, RES_2, RES_3, RES_4), + PIN(141, RES_1, RES_2, RES_3, RES_4), + PIN(142, RES_1, RES_2, RES_3, RES_4), + PIN(143, RES_1, RES_2, RES_3, RES_4), + PIN(144, RES_1, RES_2, RES_3, RES_4), + PIN(145, RES_1, RES_2, RES_3, RES_4), + PIN(146, RES_1, RES_2, RES_3, RES_4), + PIN(147, RES_1, RES_2, RES_3, RES_4), + PIN(148, RES_1, RES_2, RES_3, RES_4), + PIN(149, RES_1, RES_2, RES_3, RES_4), + PIN(150, RES_1, RES_2, RES_3, RES_4), + PIN(151, RES_1, RES_2, RES_3, RES_4), + PIN(152, RES_1, RES_2, RES_3, RES_4), + PIN(153, RES_1, RES_2, RES_3, RES_4), + PIN(154, RES_1, RES_2, RES_3, RES_4), + PIN(155, RES_1, RES_2, RES_3, RES_4), + PIN(156, RES_1, RES_2, RES_3, RES_4), + PIN(157, RES_1, RES_2, RES_3, RES_4), + PIN(158, RES_1, RES_2, RES_3, RES_4), + PIN(159, RES_1, RES_2, RES_3, RES_4), + PIN(160, RES_1, RES_2, RES_3, RES_4), + PIN(161, RES_1, RES_2, RES_3, RES_4), + PIN(162, RES_1, RES_2, RES_3, RES_4), + PIN(163, RES_1, RES_2, RES_3, RES_4), + PIN(164, RES_1, RES_2, RES_3, RES_4), + PIN(165, RES_1, RES_2, RES_3, RES_4), + PIN(166, RES_1, RES_2, RES_3, RES_4), + PIN(167, RES_1, RES_2, RES_3, RES_4), + PIN(168, RES_1, RES_2, RES_3, RES_4), + PIN(169, RES_1, RES_2, RES_3, RES_4), + PIN(170, RES_1, RES_2, RES_3, RES_4), + PIN(171, RES_1, RES_2, RES_3, RES_4), + PIN(172, RES_1, RES_2, RES_3, RES_4), + PIN(173, RES_1, RES_2, RES_3, RES_4), + PIN(174, RES_1, RES_2, RES_3, RES_4), +}; + +enum gpio_irq_type { + IRQ_TYPE_LEVEL = 0, + IRQ_TYPE_RISING_EDGE = 1, + IRQ_TYPE_FALLING_EDGE = 2, + IRQ_TYPE_DUAL_EDGE = 3, +}; + +struct tlmm_gpio { + uint32_t cfg; + uint32_t in_out; + uint32_t intr_cfg; + uint32_t intr_status; +}; + +void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, + uint32_t drive_str, uint32_t enable); +void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull); +int gpio_irq_status(gpio_t gpio); + #endif /* _SOC_QUALCOMM_SC7280_GPIO_H_ */