• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2009
4  * Marvell Semiconductor <www.marvell.com>
5  * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
6  */
7 
8 #include <common.h>
9 #include <command.h>
10 #include <env.h>
11 #include <netdev.h>
12 #include <asm/cache.h>
13 #include <asm/io.h>
14 #include <asm/arch/cpu.h>
15 #include <asm/arch/soc.h>
16 #include <mvebu_mmc.h>
17 
reset_cpu(unsigned long ignored)18 void reset_cpu(unsigned long ignored)
19 {
20 	struct kwcpu_registers *cpureg =
21 	    (struct kwcpu_registers *)KW_CPU_REG_BASE;
22 
23 	writel(readl(&cpureg->rstoutn_mask) | (1 << 2),
24 		&cpureg->rstoutn_mask);
25 	writel(readl(&cpureg->sys_soft_rst) | 1,
26 		&cpureg->sys_soft_rst);
27 	while (1) ;
28 }
29 
30 /*
31  * Window Size
32  * Used with the Base register to set the address window size and location.
33  * Must be programmed from LSB to MSB as sequence of ones followed by
34  * sequence of zeros. The number of ones specifies the size of the window in
35  * 64 KByte granularity (e.g., a value of 0x00FF specifies 256 = 16 MByte).
36  * NOTE: A value of 0x0 specifies 64-KByte size.
37  */
kw_winctrl_calcsize(unsigned int sizeval)38 unsigned int kw_winctrl_calcsize(unsigned int sizeval)
39 {
40 	int i;
41 	unsigned int j = 0;
42 	u32 val = sizeval >> 1;
43 
44 	for (i = 0; val >= 0x10000; i++) {
45 		j |= (1 << i);
46 		val = val >> 1;
47 	}
48 	return (0x0000ffff & j);
49 }
50 
51 static struct mbus_win windows[] = {
52 	/* Window 0: PCIE MEM address space */
53 	{ KW_DEFADR_PCI_MEM, 1024 * 1024 * 256,
54 	  KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_MEM },
55 
56 	/* Window 1: PCIE IO address space */
57 	{ KW_DEFADR_PCI_IO, 1024 * 64,
58 	  KWCPU_TARGET_PCIE, KWCPU_ATTR_PCIE_IO },
59 
60 	/* Window 2: NAND Flash address space */
61 	{ KW_DEFADR_NANDF, 1024 * 1024 * 128,
62 	  KWCPU_TARGET_MEMORY, KWCPU_ATTR_NANDFLASH },
63 
64 	/* Window 3: SPI Flash address space */
65 	{ KW_DEFADR_SPIF, 1024 * 1024 * 128,
66 	  KWCPU_TARGET_MEMORY, KWCPU_ATTR_SPIFLASH },
67 
68 	/* Window 4: BOOT Memory address space */
69 	{ KW_DEFADR_BOOTROM, 1024 * 1024 * 128,
70 	  KWCPU_TARGET_MEMORY, KWCPU_ATTR_BOOTROM },
71 
72 	/* Window 5: Security SRAM address space */
73 	{ KW_DEFADR_SASRAM, 1024 * 64,
74 	  KWCPU_TARGET_SASRAM, KWCPU_ATTR_SASRAM },
75 };
76 
77 /*
78  * SYSRSTn Duration Counter Support
79  *
80  * Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
81  * When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
82  * The SYSRSTn duration counter is useful for implementing a manufacturer
83  * or factory reset. Upon a long reset assertion that is greater than a
84  * pre-configured environment variable value for sysrstdelay,
85  * The counter value is stored in the SYSRSTn Length Counter Register
86  * The counter is based on the 25-MHz reference clock (40ns)
87  * It is a 29-bit counter, yielding a maximum counting duration of
88  * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
89  * it remains at this value until counter reset is triggered by setting
90  * bit 31 of KW_REG_SYSRST_CNT
91  */
kw_sysrst_action(void)92 static void kw_sysrst_action(void)
93 {
94 	int ret;
95 	char *s = env_get("sysrstcmd");
96 
97 	if (!s) {
98 		debug("Error.. %s failed, check sysrstcmd\n",
99 			__FUNCTION__);
100 		return;
101 	}
102 
103 	debug("Starting %s process...\n", __FUNCTION__);
104 	ret = run_command(s, 0);
105 	if (ret != 0)
106 		debug("Error.. %s failed\n", __FUNCTION__);
107 	else
108 		debug("%s process finished\n", __FUNCTION__);
109 }
110 
kw_sysrst_check(void)111 static void kw_sysrst_check(void)
112 {
113 	u32 sysrst_cnt, sysrst_dly;
114 	char *s;
115 
116 	/*
117 	 * no action if sysrstdelay environment variable is not defined
118 	 */
119 	s = env_get("sysrstdelay");
120 	if (s == NULL)
121 		return;
122 
123 	/* read sysrstdelay value */
124 	sysrst_dly = (u32) simple_strtoul(s, NULL, 10);
125 
126 	/* read SysRst Length counter register (bits 28:0) */
127 	sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT));
128 	debug("H/w Rst hold time: %d.%d secs\n",
129 		sysrst_cnt / SYSRST_CNT_1SEC_VAL,
130 		sysrst_cnt % SYSRST_CNT_1SEC_VAL);
131 
132 	/* clear the counter for next valid read*/
133 	writel(1 << 31, KW_REG_SYSRST_CNT);
134 
135 	/*
136 	 * sysrst_action:
137 	 * if H/w Reset key is pressed and hold for time
138 	 * more than sysrst_dly in seconds
139 	 */
140 	if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly)
141 		kw_sysrst_action();
142 }
143 
144 #if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo(void)145 int print_cpuinfo(void)
146 {
147 	char *rev = "??";
148 	u16 devid = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff;
149 	u8 revid = readl(KW_REG_PCIE_REVID) & 0xff;
150 
151 	if ((readl(KW_REG_DEVICE_ID) & 0x03) > 2) {
152 		printf("Error.. %s:Unsupported Kirkwood SoC 88F%04x\n", __FUNCTION__, devid);
153 		return -1;
154 	}
155 
156 	switch (revid) {
157 	case 0:
158 		if (devid == 0x6281)
159 			rev = "Z0";
160 		else if (devid == 0x6282)
161 			rev = "A0";
162 		break;
163 	case 1:
164 		rev = "A1";
165 		break;
166 	case 2:
167 		rev = "A0";
168 		break;
169 	case 3:
170 		rev = "A1";
171 		break;
172 	default:
173 		break;
174 	}
175 
176 	printf("SoC:   Kirkwood 88F%04x_%s\n", devid, rev);
177 	return 0;
178 }
179 #endif /* CONFIG_DISPLAY_CPUINFO */
180 
181 #ifdef CONFIG_ARCH_CPU_INIT
arch_cpu_init(void)182 int arch_cpu_init(void)
183 {
184 	u32 reg;
185 	struct kwcpu_registers *cpureg =
186 		(struct kwcpu_registers *)KW_CPU_REG_BASE;
187 
188 	/* Linux expects the internal registers to be at 0xf1000000 */
189 	writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);
190 
191 	/* Enable and invalidate L2 cache in write through mode */
192 	writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg);
193 	invalidate_l2_cache();
194 
195 #ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
196 	/*
197 	 * Configures the I/O voltage of the pads connected to Egigabit
198 	 * Ethernet interface to 1.8V
199 	 * By default it is set to 3.3V
200 	 */
201 	reg = readl(KW_REG_MPP_OUT_DRV_REG);
202 	reg |= (1 << 7);
203 	writel(reg, KW_REG_MPP_OUT_DRV_REG);
204 #endif
205 #ifdef CONFIG_KIRKWOOD_EGIGA_INIT
206 	/*
207 	 * Set egiga port0/1 in normal functional mode
208 	 * This is required becasue on kirkwood by default ports are in reset mode
209 	 * OS egiga driver may not have provision to set them in normal mode
210 	 * and if u-boot is build without network support, network may fail at OS level
211 	 */
212 	reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(0));
213 	reg &= ~(1 << 4);	/* Clear PortReset Bit */
214 	writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(0)));
215 	reg = readl(KWGBE_PORT_SERIAL_CONTROL1_REG(1));
216 	reg &= ~(1 << 4);	/* Clear PortReset Bit */
217 	writel(reg, (KWGBE_PORT_SERIAL_CONTROL1_REG(1)));
218 #endif
219 #ifdef CONFIG_KIRKWOOD_PCIE_INIT
220 	/*
221 	 * Enable PCI Express Port0
222 	 */
223 	reg = readl(&cpureg->ctrl_stat);
224 	reg |= (1 << 0);	/* Set PEX0En Bit */
225 	writel(reg, &cpureg->ctrl_stat);
226 #endif
227 	return 0;
228 }
229 #endif /* CONFIG_ARCH_CPU_INIT */
230 
231 /*
232  * SOC specific misc init
233  */
234 #if defined(CONFIG_ARCH_MISC_INIT)
arch_misc_init(void)235 int arch_misc_init(void)
236 {
237 	volatile u32 temp;
238 
239 	/*CPU streaming & write allocate */
240 	temp = readfr_extra_feature_reg();
241 	temp &= ~(1 << 28);	/* disable wr alloc */
242 	writefr_extra_feature_reg(temp);
243 
244 	temp = readfr_extra_feature_reg();
245 	temp &= ~(1 << 29);	/* streaming disabled */
246 	writefr_extra_feature_reg(temp);
247 
248 	/* L2Cache settings */
249 	temp = readfr_extra_feature_reg();
250 	/* Disable L2C pre fetch - Set bit 24 */
251 	temp |= (1 << 24);
252 	/* enable L2C - Set bit 22 */
253 	temp |= (1 << 22);
254 	writefr_extra_feature_reg(temp);
255 
256 	/* Change reset vector to address 0x0 */
257 	temp = get_cr();
258 	set_cr(temp & ~CR_V);
259 
260 	/* Configure mbus windows */
261 	mvebu_mbus_probe(windows, ARRAY_SIZE(windows));
262 
263 	/* checks and execute resset to factory event */
264 	kw_sysrst_check();
265 
266 	return 0;
267 }
268 #endif /* CONFIG_ARCH_MISC_INIT */
269 
270 #ifdef CONFIG_MVGBE
cpu_eth_init(bd_t * bis)271 int cpu_eth_init(bd_t *bis)
272 {
273 	mvgbe_initialize(bis);
274 	return 0;
275 }
276 #endif
277 
278 #ifdef CONFIG_MVEBU_MMC
board_mmc_init(bd_t * bis)279 int board_mmc_init(bd_t *bis)
280 {
281 	mvebu_mmc_init(bis);
282 	return 0;
283 }
284 #endif /* CONFIG_MVEBU_MMC */
285