#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>
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
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
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
#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)
}
#endif
+#ifdef CONFIG_DM_MMC
+static void mmc_pinmux_setup(int sdc);
+#endif
+
/* add board specific code here */
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;
}
int board_mmc_init(bd_t *bis)
{
__maybe_unused struct mmc *mmc0, *mmc1;
- __maybe_unused char buf[512];
mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
#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;
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
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;
*/
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;
int misc_init_r(void)
{
- __maybe_unused int ret;
uint boot;
env_set("fel_booted", NULL);
#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
#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))
} else {
return strcmp(name, cmp_str);
}
+#endif
+ return strcmp(name, cmp_str);
}
#endif