ARM: am335x: Add phyCORE AM335x R2 support
[oweals/u-boot.git] / board / sunxi / board.c
index d1d7f9f40061fc927bd2c93c63b02b67cd86e491..98bc3cd0c13cd5c03a4e404a4079957a526ec83b 100644 (file)
@@ -28,7 +28,7 @@
 #endif
 #include <asm/gpio.h>
 #include <asm/io.h>
-#include <crc.h>
+#include <u-boot/crc.h>
 #include <environment.h>
 #include <linux/libfdt.h>
 #include <nand.h>
@@ -98,6 +98,10 @@ void i2c_init_board(void)
        sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
        sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
        clock_twi_onoff(0, 1);
+#elif defined(CONFIG_MACH_SUN50I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0);
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0);
+       clock_twi_onoff(0, 1);
 #endif
 #endif
 
@@ -120,6 +124,10 @@ void i2c_init_board(void)
        sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
        sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
        clock_twi_onoff(1, 1);
+#elif defined(CONFIG_MACH_SUN50I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1);
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1);
+       clock_twi_onoff(1, 1);
 #endif
 #endif
 
@@ -142,6 +150,10 @@ void i2c_init_board(void)
        sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
        sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
        clock_twi_onoff(2, 1);
+#elif defined(CONFIG_MACH_SUN50I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPE(14), SUN50I_GPE_TWI2);
+       sunxi_gpio_set_cfgpin(SUNXI_GPE(15), SUN50I_GPE_TWI2);
+       clock_twi_onoff(2, 1);
 #endif
 #endif
 
@@ -168,10 +180,16 @@ void i2c_init_board(void)
 #endif
 
 #ifdef CONFIG_R_I2C_ENABLE
+#ifdef CONFIG_MACH_SUN50I
+       clock_twi_onoff(5, 1);
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
+#else
        clock_twi_onoff(5, 1);
        sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
        sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
 #endif
+#endif
 }
 
 #if defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_ENV_IS_IN_FAT)
@@ -190,6 +208,10 @@ enum env_location env_get_location(enum env_operation op, int prio)
 }
 #endif
 
+#ifdef CONFIG_DM_MMC
+static void mmc_pinmux_setup(int sdc);
+#endif
+
 /* add board specific code here */
 int board_init(void)
 {
@@ -251,13 +273,57 @@ int board_init(void)
        i2c_init_board();
 #endif
 
+#ifdef CONFIG_DM_MMC
+       /*
+        * Temporary workaround for enabling MMC clocks until a sunxi DM
+        * pinctrl driver lands.
+        */
+       mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
+       mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
+#endif
+#endif /* CONFIG_DM_MMC */
+
        /* Uses dm gpio code so do this here and not in i2c_init_board() */
        return soft_i2c_board_init();
 }
 
+/*
+ * On older SoCs the SPL is actually at address zero, so using NULL as
+ * an error value does not work.
+ */
+#define INVALID_SPL_HEADER ((void *)~0UL)
+
+static struct boot_file_head * get_spl_header(uint8_t req_version)
+{
+       struct boot_file_head *spl = (void *)(ulong)SPL_ADDR;
+       uint8_t spl_header_version = spl->spl_signature[3];
+
+       /* Is there really the SPL header (still) there? */
+       if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
+               return INVALID_SPL_HEADER;
+
+       if (spl_header_version < req_version) {
+               printf("sunxi SPL version mismatch: expected %u, got %u\n",
+                      req_version, spl_header_version);
+               return INVALID_SPL_HEADER;
+       }
+
+       return spl;
+}
+
 int dram_init(void)
 {
-       gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE);
+       struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION);
+
+       if (spl == INVALID_SPL_HEADER)
+               gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0,
+                                           PHYS_SDRAM_0_SIZE);
+       else
+               gd->ram_size = (phys_addr_t)spl->dram_size << 20;
+
+       if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE)
+               gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
 
        return 0;
 }
@@ -521,6 +587,21 @@ int board_mmc_init(bd_t *bis)
 #endif
 
 #ifdef CONFIG_SPL_BUILD
+
+static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
+{
+       struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
+
+       if (spl == INVALID_SPL_HEADER)
+               return;
+
+       /* Promote the header version for U-Boot proper, if needed. */
+       if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION)
+               spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION;
+
+       spl->dram_size = dram_size >> 20;
+}
+
 void sunxi_board_init(void)
 {
        int power_failed = 0;
@@ -589,6 +670,8 @@ void sunxi_board_init(void)
        if (!gd->ram_size)
                hang();
 
+       sunxi_spl_store_dram_size(gd->ram_size);
+
        /*
         * Only clock up the CPU to full speed if we are reasonably
         * assured it's being powered with suitable core voltage
@@ -607,7 +690,7 @@ int g_dnl_board_usb_cable_connected(void)
        struct phy phy;
        int ret;
 
-       ret = uclass_get_device(UCLASS_USB_DEV_GENERIC, 0, &dev);
+       ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
        if (ret) {
                pr_err("%s: Cannot find USB device\n", __func__);
                return ret;
@@ -662,16 +745,11 @@ void get_board_serial(struct tag_serialnr *serialnr)
  */
 static void parse_spl_header(const uint32_t spl_addr)
 {
-       struct boot_file_head *spl = (void *)(ulong)spl_addr;
-       if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
-               return; /* signature mismatch, no usable header */
+       struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
 
-       uint8_t spl_header_version = spl->spl_signature[3];
-       if (spl_header_version != SPL_HEADER_VERSION) {
-               printf("sunxi SPL version mismatch: expected %u, got %u\n",
-                      SPL_HEADER_VERSION, spl_header_version);
+       if (spl == INVALID_SPL_HEADER)
                return;
-       }
+
        if (!spl->fel_script_address)
                return;
 
@@ -806,11 +884,11 @@ int ft_board_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_SPL_LOAD_FIT
 int board_fit_config_name_match(const char *name)
 {
-       struct boot_file_head *spl = (void *)(ulong)SPL_ADDR;
-       const char *cmp_str = (void *)(ulong)SPL_ADDR;
+       struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
+       const char *cmp_str = (const char *)spl;
 
        /* Check if there is a DT name stored in the SPL header and use that. */
-       if (spl->dt_name_offset) {
+       if (spl != INVALID_SPL_HEADER && spl->dt_name_offset) {
                cmp_str += spl->dt_name_offset;
        } else {
 #ifdef CONFIG_DEFAULT_DEVICE_TREE
@@ -820,6 +898,7 @@ int board_fit_config_name_match(const char *name)
 #endif
        };
 
+#ifdef CONFIG_PINE64_DT_SELECTION
 /* Differentiate the two Pine64 board DTs by their DRAM size. */
        if (strstr(name, "-pine64") && strstr(cmp_str, "-pine64")) {
                if ((gd->ram_size > 512 * 1024 * 1024))
@@ -829,5 +908,7 @@ int board_fit_config_name_match(const char *name)
        } else {
                return strcmp(name, cmp_str);
        }
+#endif
+       return strcmp(name, cmp_str);
 }
 #endif