Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/linux-sunxi/sunxi-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIcenowy Zheng <uwu@icenowy.me>2022-07-06 00:01:00 +0300
committerAndre Przywara <osp@andrep.de>2022-07-29 12:11:36 +0300
commitbb00a855c42ff021df50e139b00e1e4bf27d2b9a (patch)
tree2c1d13fd077e00e028aba7b6b4306a911ac2d71a
parentd39b0a7d6eb7753c1ba753ff70ed26d818cc1f4b (diff)
uart0-helloworld-sdboot: implement support for new GPIO controllers
GPIO controllers in some new Allwinner SoCs has altered register map. Add basical support for the new GPIO controller register map. Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
-rw-r--r--uart0-helloworld-sdboot.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/uart0-helloworld-sdboot.c b/uart0-helloworld-sdboot.c
index 019461b..37211a9 100644
--- a/uart0-helloworld-sdboot.c
+++ b/uart0-helloworld-sdboot.c
@@ -83,26 +83,19 @@ typedef unsigned int u32;
#define SUNXI_GPIO_H 7
#define SUNXI_GPIO_I 8
-struct sunxi_gpio {
- u32 cfg[4];
- u32 dat;
- u32 drv[2];
- u32 pull[2];
-};
-
-struct sunxi_gpio_reg {
- struct sunxi_gpio gpio_bank[10];
-};
-
#define GPIO_BANK(pin) ((pin) >> 5)
#define GPIO_NUM(pin) ((pin) & 0x1F)
+#define GPIO_CFG_BASE(bank) ((u32 *)(pio_base + (bank) * pio_bank_size))
#define GPIO_CFG_INDEX(pin) (((pin) & 0x1F) >> 3)
#define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1F) & 0x7) << 2)
+#define GPIO_PULL_BASE(bank) ((u32 *)(pio_base + (bank) * pio_bank_size + pio_pull_off))
#define GPIO_PULL_INDEX(pin) (((pin) & 0x1f) >> 4)
#define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1)
+#define GPIO_DAT_BASE(bank) ((u32 *)(pio_base + (bank) * pio_bank_size + pio_dat_off))
+
/* GPIO bank sizes */
#define SUNXI_GPIO_A_NR (32)
#define SUNXI_GPIO_B_NR (32)
@@ -161,6 +154,7 @@ enum sunxi_gpio_number {
#define SUNXI_GPIO_PULL_DOWN (2)
static u32 pio_base;
+static u32 pio_bank_size, pio_dat_off, pio_pull_off;
int sunxi_gpio_set_cfgpin(u32 pin, u32 val)
{
@@ -168,12 +162,11 @@ int sunxi_gpio_set_cfgpin(u32 pin, u32 val)
u32 bank = GPIO_BANK(pin);
u32 index = GPIO_CFG_INDEX(pin);
u32 offset = GPIO_CFG_OFFSET(pin);
- struct sunxi_gpio *pio =
- &((struct sunxi_gpio_reg *)pio_base)->gpio_bank[bank];
- cfg = readl(&pio->cfg[0] + index);
+ u32 *addr = GPIO_CFG_BASE(bank) + index;
+ cfg = readl(addr);
cfg &= ~(0xf << offset);
cfg |= val << offset;
- writel(cfg, &pio->cfg[0] + index);
+ writel(cfg, addr);
return 0;
}
@@ -183,12 +176,11 @@ int sunxi_gpio_set_pull(u32 pin, u32 val)
u32 bank = GPIO_BANK(pin);
u32 index = GPIO_PULL_INDEX(pin);
u32 offset = GPIO_PULL_OFFSET(pin);
- struct sunxi_gpio *pio =
- &((struct sunxi_gpio_reg *)pio_base)->gpio_bank[bank];
- cfg = readl(&pio->pull[0] + index);
+ u32 *addr = GPIO_PULL_BASE(bank) + index;
+ cfg = readl(addr);
cfg &= ~(0x3 << offset);
cfg |= val << offset;
- writel(cfg, &pio->pull[0] + index);
+ writel(cfg, addr);
return 0;
}
@@ -197,14 +189,13 @@ int sunxi_gpio_output(u32 pin, u32 val)
u32 dat;
u32 bank = GPIO_BANK(pin);
u32 num = GPIO_NUM(pin);
- struct sunxi_gpio *pio =
- &((struct sunxi_gpio_reg *)pio_base)->gpio_bank[bank];
- dat = readl(&pio->dat);
+ u32 *addr = GPIO_DAT_BASE(bank);
+ dat = readl(addr);
if(val)
dat |= 1 << num;
else
dat &= ~(1 << num);
- writel(dat, &pio->dat);
+ writel(dat, addr);
return 0;
}
@@ -213,9 +204,8 @@ int sunxi_gpio_input(u32 pin)
u32 dat;
u32 bank = GPIO_BANK(pin);
u32 num = GPIO_NUM(pin);
- struct sunxi_gpio *pio =
- &((struct sunxi_gpio_reg *)pio_base)->gpio_bank[bank];
- dat = readl(&pio->dat);
+ u32 *addr = GPIO_DAT_BASE(bank);
+ dat = readl(addr);
dat >>= num;
return (dat & 0x1);
}
@@ -416,6 +406,18 @@ void clock_init_uart(void)
void gpio_init(void)
{
+ if (0) {
+ /* GPIO V2 */
+ pio_bank_size = 0x30;
+ pio_dat_off = 0x10;
+ pio_pull_off = 0x24;
+ } else {
+ /* GPIO V1 */
+ pio_bank_size = 0x24;
+ pio_dat_off = 0x10;
+ pio_pull_off = 0x1c;
+ }
+
if (soc_is_a10() || soc_is_a20() || soc_is_r40()) {
sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB_UART0);
sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB_UART0);