1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018 Synopsys, Inc. All rights reserved. 4 */ 5 6 #include <common.h> 7 #include <dwmmc.h> 8 #include <malloc.h> 9 10 #include <asm/arcregs.h> 11 12 DECLARE_GLOBAL_DATA_PTR; 13 14 #define ARC_PERIPHERAL_BASE 0xF0000000 15 16 #define CGU_ARC_FMEAS_ARC (void *)(ARC_PERIPHERAL_BASE + 0x84) 17 #define CGU_ARC_FMEAS_ARC_START BIT(31) 18 #define CGU_ARC_FMEAS_ARC_DONE BIT(30) 19 #define CGU_ARC_FMEAS_ARC_CNT_MASK GENMASK(14, 0) 20 #define CGU_ARC_FMEAS_ARC_RCNT_OFFSET 0 21 #define CGU_ARC_FMEAS_ARC_FCNT_OFFSET 15 22 23 #define SDIO_BASE (void *)(ARC_PERIPHERAL_BASE + 0x10000) 24 25 int mach_cpu_init(void) 26 { 27 int rcnt, fcnt; 28 u32 data; 29 30 /* Start frequency measurement */ 31 writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC); 32 33 /* Poll DONE bit */ 34 do { 35 data = readl(CGU_ARC_FMEAS_ARC); 36 } while (!(data & CGU_ARC_FMEAS_ARC_DONE)); 37 38 /* Amount of reference 100 MHz clocks */ 39 rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) & 40 CGU_ARC_FMEAS_ARC_CNT_MASK); 41 42 /* Amount of CPU clocks */ 43 fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) & 44 CGU_ARC_FMEAS_ARC_CNT_MASK); 45 46 gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000; 47 48 return 0; 49 } 50 51 int board_mmc_init(bd_t *bis) 52 { 53 struct dwmci_host *host = NULL; 54 55 host = malloc(sizeof(struct dwmci_host)); 56 if (!host) { 57 printf("dwmci_host malloc fail!\n"); 58 return 1; 59 } 60 61 memset(host, 0, sizeof(struct dwmci_host)); 62 host->name = "Synopsys Mobile storage"; 63 host->ioaddr = SDIO_BASE; 64 host->buswidth = 4; 65 host->dev_index = 0; 66 host->bus_hz = 50000000; 67 68 add_dwmci(host, host->bus_hz / 2, 400000); 69 70 return 0; 71 } 72 73 int board_mmc_getcd(struct mmc *mmc) 74 { 75 struct dwmci_host *host = mmc->priv; 76 77 return !(dwmci_readl(host, DWMCI_CDETECT) & 1); 78 } 79 80 #define CREG_BASE 0xF0001000 81 #define CREG_BOOT (void *)(CREG_BASE + 0x0FF0) 82 #define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0) 83 #define CREG_IP_VERSION (void *)(CREG_BASE + 0x0FF8) 84 85 /* Bits in CREG_BOOT register */ 86 #define CREG_BOOT_WP_BIT BIT(8) 87 88 void reset_cpu(ulong addr) 89 { 90 writel(1, CREG_IP_SW_RESET); 91 while (1) 92 ; /* loop forever till reset */ 93 } 94 95 static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 96 { 97 u32 creg_boot = readl(CREG_BOOT); 98 99 if (!strcmp(argv[1], "unlock")) 100 creg_boot &= ~CREG_BOOT_WP_BIT; 101 else if (!strcmp(argv[1], "lock")) 102 creg_boot |= CREG_BOOT_WP_BIT; 103 else 104 return CMD_RET_USAGE; 105 106 writel(creg_boot, CREG_BOOT); 107 108 return CMD_RET_SUCCESS; 109 } 110 111 cmd_tbl_t cmd_emsdp[] = { 112 U_BOOT_CMD_MKENT(rom, 2, 0, do_emsdp_rom, "", ""), 113 }; 114 115 static int do_emsdp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 116 { 117 cmd_tbl_t *c; 118 119 c = find_cmd_tbl(argv[1], cmd_emsdp, ARRAY_SIZE(cmd_emsdp)); 120 121 /* Strip off leading 'emsdp' command */ 122 argc--; 123 argv++; 124 125 if (c == NULL || argc > c->maxargs) 126 return CMD_RET_USAGE; 127 128 return c->cmd(cmdtp, flag, argc, argv); 129 } 130 131 U_BOOT_CMD( 132 emsdp, CONFIG_SYS_MAXARGS, 0, do_emsdp, 133 "Synopsys EMSDP specific commands", 134 "rom unlock - Unlock non-volatile memory for writing\n" 135 "emsdp rom lock - Lock non-volatile memory to prevent writing\n" 136 ); 137 138 int checkboard(void) 139 { 140 int version = readl(CREG_IP_VERSION); 141 142 printf("Board: ARC EM Software Development Platform v%d.%d\n", 143 (version >> 16) & 0xff, version & 0xff); 144 return 0; 145 }; 146