diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h index 0e3b57d0ef..1aaec5faec 100644 --- a/arch/arm/include/asm/arch-rockchip/gpio.h +++ b/arch/arm/include/asm/arch-rockchip/gpio.h @@ -31,4 +31,27 @@ enum gpio_pu_pd { GPIO_PULL_REPEAT, }; +/* These defines are only used by spl_gpio.h */ +enum { + /* Banks have 8 GPIOs, so 3 bits, and there are 4 banks, so 2 bits */ + GPIO_BANK_SHIFT = 3, + GPIO_BANK_MASK = 3 << GPIO_BANK_SHIFT, + + GPIO_OFFSET_MASK = 0x1f, +}; + +#define GPIO(bank, offset) ((bank) << GPIO_BANK_SHIFT | (offset)) + +enum gpio_bank_t { + BANK_A = 0, + BANK_B, + BANK_C, + BANK_D, +}; + +enum gpio_dir_t { + GPIO_INPUT = 0, + GPIO_OUTPUT, +}; + #endif diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c index a8f311bbd6..21df227717 100644 --- a/drivers/gpio/rk_gpio.c +++ b/drivers/gpio/rk_gpio.c @@ -91,6 +91,52 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset) #endif } +/* Simple SPL interface to GPIOs */ +#ifdef CONFIG_SPL_BUILD + +enum { + PULL_NONE_1V8 = 0, + PULL_DOWN_1V8 = 1, + PULL_UP_1V8 = 3, +}; + +int spl_gpio_set_pull(void *vregs, uint gpio, int pull) +{ + u32 *regs = vregs; + uint val; + + regs += gpio >> GPIO_BANK_SHIFT; + gpio &= GPIO_OFFSET_MASK; + switch (pull) { + case GPIO_PULL_UP: + val = PULL_UP_1V8; + break; + case GPIO_PULL_DOWN: + val = PULL_DOWN_1V8; + break; + case GPIO_PULL_NORMAL: + default: + val = PULL_NONE_1V8; + break; + } + clrsetbits_le32(regs, 3 << (gpio * 2), val << (gpio * 2)); + + return 0; +} + +int spl_gpio_output(void *vregs, uint gpio, int value) +{ + struct rockchip_gpio_regs * const regs = vregs; + + clrsetbits_le32(®s->swport_dr, 1 << gpio, value << gpio); + + /* Set direction */ + clrsetbits_le32(®s->swport_ddr, 1 << gpio, 1 << gpio); + + return 0; +} +#endif /* CONFIG_SPL_BUILD */ + static int rockchip_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);