xref: /openbmc/u-boot/board/synopsys/emsdp/emsdp.c (revision ecab65e4)
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