diff options
author | Icenowy Zheng <icenowy@aosc.xyz> | 2016-12-19 20:57:48 +0300 |
---|---|---|
committer | Bernhard Nortmann <bernhard.nortmann@web.de> | 2016-12-28 15:30:09 +0300 |
commit | 4d62e7cb63e7c0cc27b458e6f36d0e9a60ea3f6f (patch) | |
tree | 04151d5f514fc57922543c4878578309d522b9ec /uart0-helloworld-sdboot.c | |
parent | fcde876250fcb4f6eb4f535aa158f25e1937ddd8 (diff) |
uart0-helloworld-sdboot: differ H2+ with H3
With fixed SID reading routine, it's now possible to differ H2+ with H3
with SID.
Tested on an Orange Pi One and an Orange Pi Zero.
Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
Diffstat (limited to 'uart0-helloworld-sdboot.c')
-rw-r--r-- | uart0-helloworld-sdboot.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/uart0-helloworld-sdboot.c b/uart0-helloworld-sdboot.c index 377529e..f3ccf53 100644 --- a/uart0-helloworld-sdboot.c +++ b/uart0-helloworld-sdboot.c @@ -232,6 +232,34 @@ int gpio_direction_output(unsigned gpio, int value) #define VER_REG (AW_SRAMCTRL_BASE + 0x24) #define SUN4I_SID_BASE 0x01C23800 +#define SUN8I_SIDC_BASE 0x01C14000 + +#define SIDC_PRCTL 0x40 +#define SIDC_RDKEY 0x60 + +#define SIDC_OP_LOCK 0xAC + +u32 sun8i_efuse_read(u32 offset) +{ + u32 reg_val; + + reg_val = readl(SUN8I_SIDC_BASE + SIDC_PRCTL); + reg_val &= ~(((0x1ff) << 16) | 0x3); + reg_val |= (offset << 16); + writel(reg_val, SUN8I_SIDC_BASE + SIDC_PRCTL); + + reg_val &= ~(((0xff) << 8) | 0x3); + reg_val |= (SIDC_OP_LOCK << 8) | 0x2; + writel(reg_val, SUN8I_SIDC_BASE + SIDC_PRCTL); + + while (readl(SUN8I_SIDC_BASE + SIDC_PRCTL) & 0x2); + + reg_val &= ~(((0x1ff) << 16) | ((0xff) << 8) | 0x3); + writel(reg_val, SUN8I_SIDC_BASE + SIDC_PRCTL); + + reg_val = readl(SUN8I_SIDC_BASE + SIDC_RDKEY); + return reg_val; +} static u32 soc_id; @@ -255,7 +283,6 @@ void soc_detection_init(void) #define soc_is_a31() (soc_id == 0x1633) #define soc_is_a80() (soc_id == 0x1639) #define soc_is_a64() (soc_id == 0x1689) -#define soc_is_h3() (soc_id == 0x1680) #define soc_is_h5() (soc_id == 0x1718) #define soc_is_r40() (soc_id == 0x1701) #define soc_is_v3s() (soc_id == 0x1681) @@ -274,6 +301,20 @@ int soc_is_a13(void) (readl(SUN4I_SID_BASE + 8) & 0xf000) != 0x7000; } +int soc_is_h2_plus(void) +{ + return soc_id == 0x1680 && ( + (sun8i_efuse_read(0) & 0xff) == 0x42 || + (sun8i_efuse_read(0) & 0xff) == 0x83); +} + +int soc_is_h3(void) +{ + return soc_id == 0x1680 && + (sun8i_efuse_read(0) & 0xff) != 0x42 && + (sun8i_efuse_read(0) & 0xff) != 0x83; +} + /***************************************************************************** * UART is mostly the same on A10/A13/A20/A31/H3/A64, except that newer SoCs * * have changed the APB numbering scheme (A10/A13/A20 used to have APB0 and * @@ -330,7 +371,7 @@ void gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(8), SUN50I_A64_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_A64_GPB_UART0); sunxi_gpio_set_pull(SUNXI_GPB(9), SUNXI_GPIO_PULL_UP); - } else if (soc_is_h3()) { + } else if (soc_is_h3() || soc_is_h2_plus()) { sunxi_gpio_set_cfgpin(SUNXI_GPA(4), SUN8I_H3_GPA_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPA(5), SUN8I_H3_GPA_UART0); sunxi_gpio_set_pull(SUNXI_GPA(5), SUNXI_GPIO_PULL_UP); @@ -449,6 +490,8 @@ int main(void) uart0_puts("Allwinner A31/A31s!\n"); else if (soc_is_a64()) uart0_puts("Allwinner A64!\n"); + else if (soc_is_h2_plus()) + uart0_puts("Allwinner H2+!\n"); else if (soc_is_h3()) uart0_puts("Allwinner H3!\n"); else if (soc_is_h5()) |