| // 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; |
| } |