// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2018 Synopsys, Inc. All rights reserved. */ #include #include #include #include DECLARE_GLOBAL_DATA_PTR; #define ARC_PERIPHERAL_BASE 0xF0000000 #define CGU_ARC_FMEAS_ARC (void *)(ARC_PERIPHERAL_BASE + 0x84) #define CGU_ARC_FMEAS_ARC_START BIT(31) #define CGU_ARC_FMEAS_ARC_DONE BIT(30) #define CGU_ARC_FMEAS_ARC_CNT_MASK GENMASK(14, 0) #define CGU_ARC_FMEAS_ARC_RCNT_OFFSET 0 #define CGU_ARC_FMEAS_ARC_FCNT_OFFSET 15 #define SDIO_BASE (void *)(ARC_PERIPHERAL_BASE + 0x10000) int mach_cpu_init(void) { int rcnt, fcnt; u32 data; /* Start frequency measurement */ writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC); /* Poll DONE bit */ do { data = readl(CGU_ARC_FMEAS_ARC); } while (!(data & CGU_ARC_FMEAS_ARC_DONE)); /* Amount of reference 100 MHz clocks */ rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) & CGU_ARC_FMEAS_ARC_CNT_MASK); /* Amount of CPU clocks */ fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) & CGU_ARC_FMEAS_ARC_CNT_MASK); gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000; return 0; } int board_mmc_init(bd_t *bis) { struct dwmci_host *host = NULL; host = malloc(sizeof(struct dwmci_host)); if (!host) { printf("dwmci_host malloc fail!\n"); return 1; } memset(host, 0, sizeof(struct dwmci_host)); host->name = "Synopsys Mobile storage"; host->ioaddr = SDIO_BASE; host->buswidth = 4; host->dev_index = 0; host->bus_hz = 50000000; add_dwmci(host, host->bus_hz / 2, 400000); return 0; } int board_mmc_getcd(struct mmc *mmc) { struct dwmci_host *host = mmc->priv; return !(dwmci_readl(host, DWMCI_CDETECT) & 1); } #define CREG_BASE 0xF0001000 #define CREG_BOOT (void *)(CREG_BASE + 0x0FF0) #define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0) #define CREG_IP_VERSION (void *)(CREG_BASE + 0x0FF8) /* Bits in CREG_BOOT register */ #define CREG_BOOT_WP_BIT BIT(8) void reset_cpu(ulong addr) { writel(1, CREG_IP_SW_RESET); while (1) ; /* loop forever till reset */ } static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { u32 creg_boot = readl(CREG_BOOT); if (!strcmp(argv[1], "unlock")) creg_boot &= ~CREG_BOOT_WP_BIT; else if (!strcmp(argv[1], "lock")) creg_boot |= CREG_BOOT_WP_BIT; else return CMD_RET_USAGE; writel(creg_boot, CREG_BOOT); return CMD_RET_SUCCESS; } cmd_tbl_t cmd_emsdp[] = { U_BOOT_CMD_MKENT(rom, 2, 0, do_emsdp_rom, "", ""), }; static int do_emsdp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { cmd_tbl_t *c; c = find_cmd_tbl(argv[1], cmd_emsdp, ARRAY_SIZE(cmd_emsdp)); /* Strip off leading 'emsdp' command */ argc--; argv++; if (c == NULL || argc > c->maxargs) return CMD_RET_USAGE; return c->cmd(cmdtp, flag, argc, argv); } U_BOOT_CMD( emsdp, CONFIG_SYS_MAXARGS, 0, do_emsdp, "Synopsys EMSDP specific commands", "rom unlock - Unlock non-volatile memory for writing\n" "emsdp rom lock - Lock non-volatile memory to prevent writing\n" ); int checkboard(void) { int version = readl(CREG_IP_VERSION); printf("Board: ARC EM Software Development Platform v%d.%d\n", (version >> 16) & 0xff, version & 0xff); return 0; };