#include <common.h>
#include <clk.h>
+#include <cpu.h>
+#include <cpu_func.h>
#include <dm.h>
+#include <init.h>
+#include <log.h>
+#include <asm/cache.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass.h>
#include <errno.h>
+#include <spl.h>
+#include <thermal.h>
#include <asm/arch/sci/sci.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch-imx/cpu.h>
#include <asm/armv8/cpu.h>
#include <asm/armv8/mmu.h>
+#include <asm/setup.h>
#include <asm/mach-imx/boot_mode.h>
+#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
-u32 get_cpu_rev(void)
+#define BT_PASSOVER_TAG 0x504F
+struct pass_over_info_t *get_pass_over_info(void)
{
- u32 id = 0, rev = 0;
- int ret;
+ struct pass_over_info_t *p =
+ (struct pass_over_info_t *)PASS_OVER_INFO_ADDR;
- ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id);
- if (ret)
- return 0;
+ if (p->barker != BT_PASSOVER_TAG ||
+ p->len != sizeof(struct pass_over_info_t))
+ return NULL;
- rev = (id >> 5) & 0xf;
- id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */
-
- return (id << 12) | rev;
+ return p;
}
-#ifdef CONFIG_DISPLAY_CPUINFO
-const char *get_imx8_type(u32 imxtype)
+int arch_cpu_init(void)
{
- switch (imxtype) {
- case MXC_CPU_IMX8QXP:
- return "8QXP";
- default:
- return "??";
- }
-}
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION)
+ spl_save_restore_data();
+#endif
-const char *get_imx8_rev(u32 rev)
-{
- switch (rev) {
- case CHIP_REV_A:
- return "A";
- case CHIP_REV_B:
- return "B";
- default:
- return "?";
+#ifdef CONFIG_SPL_BUILD
+ struct pass_over_info_t *pass_over;
+
+ if (is_soc_rev(CHIP_REV_A)) {
+ pass_over = get_pass_over_info();
+ if (pass_over && pass_over->g_ap_mu == 0) {
+ /*
+ * When ap_mu is 0, means the U-Boot booted
+ * from first container
+ */
+ sc_misc_boot_status(-1, SC_MISC_BOOT_STATUS_SUCCESS);
+ }
}
-}
+#endif
-const char *get_core_name(void)
-{
- if (is_cortex_a35())
- return "A35";
- else
- return "?";
+ return 0;
}
-int print_cpuinfo(void)
+int arch_cpu_init_dm(void)
{
- struct udevice *dev;
- struct clk cpu_clk;
- int ret;
+ struct udevice *devp;
+ int node, ret;
- ret = uclass_get_device(UCLASS_CPU, 0, &dev);
- if (ret)
- return 0;
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "fsl,imx8-mu");
- ret = clk_get_by_index(dev, 0, &cpu_clk);
+ ret = uclass_get_device_by_of_offset(UCLASS_MISC, node, &devp);
if (ret) {
- dev_err(dev, "failed to clk\n");
- return 0;
+ printf("could not get scu %d\n", ret);
+ return ret;
}
- u32 cpurev;
-
- cpurev = get_cpu_rev();
-
- printf("CPU: Freescale i.MX%s rev%s %s at %ld MHz\n",
- get_imx8_type((cpurev & 0xFF000) >> 12),
- get_imx8_rev((cpurev & 0xFFF)),
- get_core_name(),
- clk_get_rate(&cpu_clk) / 1000000);
+ if (is_imx8qm()) {
+ ret = sc_pm_set_resource_power_mode(-1, SC_R_SMMU,
+ SC_PM_PW_MODE_ON);
+ if (ret)
+ return ret;
+ }
return 0;
}
-#endif
int print_bootinfo(void)
{
return boot_dev;
}
+#ifdef CONFIG_SERIAL_TAG
+#define FUSE_UNIQUE_ID_WORD0 16
+#define FUSE_UNIQUE_ID_WORD1 17
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+ sc_err_t err;
+ u32 val1 = 0, val2 = 0;
+ u32 word1, word2;
+
+ if (!serialnr)
+ return;
+
+ word1 = FUSE_UNIQUE_ID_WORD0;
+ word2 = FUSE_UNIQUE_ID_WORD1;
+
+ err = sc_misc_otp_fuse_read(-1, word1, &val1);
+ if (err != SC_ERR_NONE) {
+ printf("%s fuse %d read error: %d\n", __func__, word1, err);
+ return;
+ }
+
+ err = sc_misc_otp_fuse_read(-1, word2, &val2);
+ if (err != SC_ERR_NONE) {
+ printf("%s fuse %d read error: %d\n", __func__, word2, err);
+ return;
+ }
+ serialnr->low = val1;
+ serialnr->high = val2;
+}
+#endif /*CONFIG_SERIAL_TAG*/
+
#ifdef CONFIG_ENV_IS_IN_MMC
__weak int board_mmc_get_env_dev(int devno)
{
phys_size_t get_effective_memsize(void)
{
sc_rm_mr_t mr;
- sc_faddr_t start, end, end1;
+ sc_faddr_t start, end, end1, start_aligned;
int err;
end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE;
for (mr = 0; mr < 64; mr++) {
err = get_owned_memreg(mr, &start, &end);
if (!err) {
- start = roundup(start, MEMSTART_ALIGNMENT);
+ start_aligned = roundup(start, MEMSTART_ALIGNMENT);
/* Too small memory region, not use it */
- if (start > end)
+ if (start_aligned > end)
continue;
- /* Find the memory region runs the u-boot */
+ /* Find the memory region runs the U-Boot */
if (start >= PHYS_SDRAM_1 && start <= end1 &&
(start <= CONFIG_SYS_TEXT_BASE &&
end >= CONFIG_SYS_TEXT_BASE)) {
dcache_enable();
}
-#ifndef CONFIG_SYS_DCACHE_OFF
+#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
u64 get_page_table_size(void)
{
u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
return size;
}
#endif
+
+#if defined(CONFIG_IMX8QM)
+#define FUSE_MAC0_WORD0 452
+#define FUSE_MAC0_WORD1 453
+#define FUSE_MAC1_WORD0 454
+#define FUSE_MAC1_WORD1 455
+#elif defined(CONFIG_IMX8QXP)
+#define FUSE_MAC0_WORD0 708
+#define FUSE_MAC0_WORD1 709
+#define FUSE_MAC1_WORD0 710
+#define FUSE_MAC1_WORD1 711
+#endif
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+ u32 word[2], val[2] = {};
+ int i, ret;
+
+ if (dev_id == 0) {
+ word[0] = FUSE_MAC0_WORD0;
+ word[1] = FUSE_MAC0_WORD1;
+ } else {
+ word[0] = FUSE_MAC1_WORD0;
+ word[1] = FUSE_MAC1_WORD1;
+ }
+
+ for (i = 0; i < 2; i++) {
+ ret = sc_misc_otp_fuse_read(-1, word[i], &val[i]);
+ if (ret < 0)
+ goto err;
+ }
+
+ mac[0] = val[0];
+ mac[1] = val[0] >> 8;
+ mac[2] = val[0] >> 16;
+ mac[3] = val[0] >> 24;
+ mac[4] = val[1];
+ mac[5] = val[1] >> 8;
+
+ debug("%s: MAC%d: %02x.%02x.%02x.%02x.%02x.%02x\n",
+ __func__, dev_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return;
+err:
+ printf("%s: fuse %d, err: %d\n", __func__, word[i], ret);
+}
+
+u32 get_cpu_rev(void)
+{
+ u32 id = 0, rev = 0;
+ int ret;
+
+ ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id);
+ if (ret)
+ return 0;
+
+ rev = (id >> 5) & 0xf;
+ id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */
+
+ return (id << 12) | rev;
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = spl_boot_device();
+
+ if (spl_boot_list[0] == BOOT_DEVICE_SPI) {
+ /* Check whether we own the flexspi0, if not, use NOR boot */
+ if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0))
+ spl_boot_list[0] = BOOT_DEVICE_NOR;
+ }
+}
+
+bool m4_parts_booted(void)
+{
+ sc_rm_pt_t m4_parts[2];
+ int err;
+
+ err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]);
+ if (err) {
+ printf("%s get resource [%d] owner error: %d\n", __func__,
+ SC_R_M4_0_PID0, err);
+ return false;
+ }
+
+ if (sc_pm_is_partition_started(-1, m4_parts[0]))
+ return true;
+
+ if (is_imx8qm()) {
+ err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]);
+ if (err) {
+ printf("%s get resource [%d] owner error: %d\n",
+ __func__, SC_R_M4_1_PID0, err);
+ return false;
+ }
+
+ if (sc_pm_is_partition_started(-1, m4_parts[1]))
+ return true;
+ }
+
+ return false;
+}