arm: dts: hummingboard: add cubox/hummingboard DT (part 1 of 2)
[oweals/u-boot.git] / arch / arm / mach-kirkwood / cpu.c
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
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  */
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  */
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
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)
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
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)
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
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
279 int board_mmc_init(bd_t *bis)
280 {
281         mvebu_mmc_init(bis);
282         return 0;
283 }
284 #endif /* CONFIG_MVEBU_MMC */