1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Synopsys, Inc. All rights reserved.
4  */
5 
6 #include <command.h>
7 #include <cpu_func.h>
8 #include <dwmmc.h>
9 #include <init.h>
10 #include <malloc.h>
11 #include <asm/global_data.h>
12 #include <linux/bitops.h>
13 
14 #include <asm/arcregs.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 #define ARC_PERIPHERAL_BASE		0xF0000000
19 
20 #define CGU_ARC_FMEAS_ARC		(void *)(ARC_PERIPHERAL_BASE + 0x84)
21 #define CGU_ARC_FMEAS_ARC_START		BIT(31)
22 #define CGU_ARC_FMEAS_ARC_DONE		BIT(30)
23 #define CGU_ARC_FMEAS_ARC_CNT_MASK	GENMASK(14, 0)
24 #define CGU_ARC_FMEAS_ARC_RCNT_OFFSET	0
25 #define CGU_ARC_FMEAS_ARC_FCNT_OFFSET	15
26 
27 #define SDIO_BASE			(void *)(ARC_PERIPHERAL_BASE + 0x10000)
28 
mach_cpu_init(void)29 int mach_cpu_init(void)
30 {
31 	int rcnt, fcnt;
32 	u32 data;
33 
34 	/* Start frequency measurement */
35 	writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
36 
37 	/* Poll DONE bit */
38 	do {
39 		data = readl(CGU_ARC_FMEAS_ARC);
40 	} while (!(data & CGU_ARC_FMEAS_ARC_DONE));
41 
42 	/* Amount of reference 100 MHz clocks */
43 	rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
44 	       CGU_ARC_FMEAS_ARC_CNT_MASK);
45 
46 	/* Amount of CPU clocks */
47 	fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
48 	       CGU_ARC_FMEAS_ARC_CNT_MASK);
49 
50 	gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
51 
52 	return 0;
53 }
54 
board_early_init_r(void)55 int board_early_init_r(void)
56 {
57 #define EMSDP_PSRAM_BASE		0xf2001000
58 #define PSRAM_FLASH_CONFIG_REG_0	(void *)(EMSDP_PSRAM_BASE + 0x10)
59 #define PSRAM_FLASH_CONFIG_REG_1	(void *)(EMSDP_PSRAM_BASE + 0x14)
60 #define CRE_ENABLE			BIT(31)
61 #define CRE_DRIVE_CMD			BIT(6)
62 
63 #define PSRAM_RCR_DPD			BIT(1)
64 #define PSRAM_RCR_PAGE_MODE		BIT(7)
65 
66 /*
67  * PSRAM_FLASH_CONFIG_REG_x[30:15] to the address lines[16:1] of flash,
68  * thus "<< 1".
69  */
70 #define PSRAM_RCR_SETUP		((PSRAM_RCR_DPD | PSRAM_RCR_PAGE_MODE) << 1)
71 
72 	// Switch PSRAM controller to command mode
73 	writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_0);
74 	// Program Refresh Configuration Register (RCR) for BANK0
75 	writew(0, (void *)(0x10000000 + PSRAM_RCR_SETUP));
76 	// Switch PSRAM controller back to memory mode
77 	writel(0, PSRAM_FLASH_CONFIG_REG_0);
78 
79 	// Switch PSRAM controller to command mode
80 	writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_1);
81 	// Program Refresh Configuration Register (RCR) for BANK1
82 	writew(0, (void *)(0x10800000 + PSRAM_RCR_SETUP));
83 	// Switch PSRAM controller back to memory mode
84 	writel(0, PSRAM_FLASH_CONFIG_REG_1);
85 
86 	printf("PSRAM initialized.\n");
87 
88 	return 0;
89 }
90 
91 #define CREG_BASE		0xF0001000
92 #define CREG_BOOT		(void *)(CREG_BASE + 0x0FF0)
93 #define CREG_IP_SW_RESET	(void *)(CREG_BASE + 0x0FF0)
94 #define CREG_IP_VERSION		(void *)(CREG_BASE + 0x0FF8)
95 
96 /* Bits in CREG_BOOT register */
97 #define CREG_BOOT_WP_BIT	BIT(8)
98 
reset_cpu(void)99 void reset_cpu(void)
100 {
101 	writel(1, CREG_IP_SW_RESET);
102 	while (1)
103 		; /* loop forever till reset */
104 }
105 
do_emsdp_rom(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])106 static int do_emsdp_rom(struct cmd_tbl *cmdtp, int flag, int argc,
107 			char *const argv[])
108 {
109 	u32 creg_boot = readl(CREG_BOOT);
110 
111 	if (!strcmp(argv[1], "unlock"))
112 		creg_boot &= ~CREG_BOOT_WP_BIT;
113 	else if (!strcmp(argv[1], "lock"))
114 		creg_boot |= CREG_BOOT_WP_BIT;
115 	else
116 		return CMD_RET_USAGE;
117 
118 	writel(creg_boot, CREG_BOOT);
119 
120 	return CMD_RET_SUCCESS;
121 }
122 
123 struct cmd_tbl cmd_emsdp[] = {
124 	U_BOOT_CMD_MKENT(rom, 2, 0, do_emsdp_rom, "", ""),
125 };
126 
do_emsdp(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])127 static int do_emsdp(struct cmd_tbl *cmdtp, int flag, int argc,
128 		    char *const argv[])
129 {
130 	struct cmd_tbl *c;
131 
132 	c = find_cmd_tbl(argv[1], cmd_emsdp, ARRAY_SIZE(cmd_emsdp));
133 
134 	/* Strip off leading 'emsdp' command */
135 	argc--;
136 	argv++;
137 
138 	if (c == NULL || argc > c->maxargs)
139 		return CMD_RET_USAGE;
140 
141 	return c->cmd(cmdtp, flag, argc, argv);
142 }
143 
144 U_BOOT_CMD(
145 	emsdp, CONFIG_SYS_MAXARGS, 0, do_emsdp,
146 	"Synopsys EMSDP specific commands",
147 	"rom unlock - Unlock non-volatile memory for writing\n"
148 	"emsdp rom lock - Lock non-volatile memory to prevent writing\n"
149 );
150 
checkboard(void)151 int checkboard(void)
152 {
153 	int version = readl(CREG_IP_VERSION);
154 
155 	printf("Board: ARC EM Software Development Platform v%d.%d\n",
156 	       (version >> 16) & 0xff, version & 0xff);
157 	return 0;
158 };
159