blob: c36765f1191c5e864327028e7f64889058cbd3f0 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 BayLibre SAS
*/
#include <common.h>
#include <dm.h>
#include <i2c.h>
#include <mmc.h>
#include "../../../drivers/crypto/nxp/a71ch.h"
#include "../../../drivers/watchdog/mtk_wdt.h"
#define WDT_DRIVER_NAME "mtk_wdt"
#define REBOOT_BOOTLOADER_VALUE (1)
#define REBOOT_BOOTLOADER_MASK (1)
#define REBOOT_BOOTLOADER_SHIFT (2)
int fastboot_set_reboot_flag(void) {
struct udevice *dev;
struct uclass *uc;
int ret = -ENOSYS;
ret = uclass_get(UCLASS_WDT, &uc);
if (ret)
return -ENOSYS;
uclass_foreach_dev(dev, uc) {
if (strncmp(dev->driver->name, WDT_DRIVER_NAME, strlen(WDT_DRIVER_NAME)) == 0) {
mtk_wdt_set_nonrst2(dev, REBOOT_BOOTLOADER_MASK << REBOOT_BOOTLOADER_SHIFT,
REBOOT_BOOTLOADER_VALUE << REBOOT_BOOTLOADER_SHIFT);
return 0;
}
}
return -ENOSYS;
}
int misc_init_r(void) {
int ret;
struct udevice *dev;
struct uclass *uc;
struct mmc *mmc;
int reg_val;
int mmc_dev = 0;
ret = uclass_get(UCLASS_WDT, &uc);
if (ret)
return -ENOSYS;
uclass_foreach_dev(dev, uc) {
if (strncmp(dev->driver->name, WDT_DRIVER_NAME, strlen(WDT_DRIVER_NAME)) == 0) {
reg_val = mtk_wdt_get_nonrst2(dev);
if (reg_val & (REBOOT_BOOTLOADER_VALUE << REBOOT_BOOTLOADER_SHIFT)) {
env_set("force_fastboot", "1");
mtk_wdt_set_nonrst2(dev, REBOOT_BOOTLOADER_MASK << REBOOT_BOOTLOADER_SHIFT, 0);
}
}
}
// Set a default serial number.
// If a crypto chip is detected, override it.
env_set("serial#", "0123456789ABCDEF");
mmc = find_mmc_device(mmc_dev);
if (mmc) {
if (!mmc_init(mmc) && mmc->capacity >= 7000000000) {
printf("EVT2 detected\n");
env_set("evt2_board", "1");
// Try to detect A71CH on the I2C bus.
// This usually fails on the first try, so retry a little.
int retries = 3;
struct udevice *devp;
do {
ret = i2c_get_chip_for_busnum(2, 0x49, 0, &devp);
retries--;
udelay(10000);
} while (retries && ret);
if (!ret) {
// Retrieve the UID of the A71CH,
// and convert it into a string.
u8* uid = a71ch_uid(devp);
char uid_str[(A71CH_UID_LEN*2)+1];
memset(uid_str, 0, sizeof(uid_str));
for (int i = 0; i < A71CH_UID_LEN; i++) {
sprintf(uid_str+(i*2), "%02x", uid[i]);
}
env_set("serial#", uid_str);
}
}
}
return 0;
}
int board_init(void)
{
struct udevice *dev;
uclass_first_device_err(UCLASS_USB_GADGET_GENERIC, &dev);
#ifdef CONFIG_USB_ETHER
usb_ether_init();
#endif
return 0;
}