sunxi: set PIO voltage to hardware-detected value on startup on H6
authorIcenowy Zheng <icenowy@aosc.io>
Wed, 24 Apr 2019 05:44:12 +0000 (13:44 +0800)
committerJagan Teki <jagan@amarulasolutions.com>
Fri, 25 Oct 2019 09:10:34 +0000 (14:40 +0530)
The Allwinner H6 SoC has a register to set the PIO banks' voltage. When
it mismatches the real voltage supplied to the VCC to the PIO supply,
the PIO will work improperly.

The PIO controller also has a register that contains the status of each
VCC rail of the PIO supplies, and it has the same definition with the
configuration register. so we can just copy the content of this register
to the configuration register at startup, to ensure the configuration is
correct at startup stage.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
[jagan: s/__maybe__unused/__maybe_unused]
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Acked-by: Jagan Teki <jagan@amarulasolutions.com>
arch/arm/include/asm/arch-sunxi/gpio.h
arch/arm/mach-sunxi/board.c

index 40a3f84..a646ea6 100644 (file)
@@ -73,6 +73,9 @@ struct sunxi_gpio_reg {
        struct sunxi_gpio_int gpio_int;
 };
 
+#define SUN50I_H6_GPIO_POW_MOD_SEL     0x340
+#define SUN50I_H6_GPIO_POW_MOD_VAL     0x348
+
 #define BANK_TO_GPIO(bank)     (((bank) < SUNXI_GPIO_L) ? \
        &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
        &((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
index 8e9bb63..db50636 100644 (file)
@@ -65,6 +65,7 @@ struct mm_region *mem_map = sunxi_mem_map;
 
 static int gpio_init(void)
 {
+       __maybe_unused uint val;
 #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
 #if defined(CONFIG_MACH_SUN4I) || \
     defined(CONFIG_MACH_SUN7I) || \
@@ -139,6 +140,14 @@ static int gpio_init(void)
 #error Unsupported console port number. Please fix pin mux settings in board.c
 #endif
 
+#ifdef CONFIG_MACH_SUN50I_H6
+       /* Update PIO power bias configuration by copy hardware detected value */
+       val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+       writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+       val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+       writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+#endif
+
        return 0;
 }