1*35b9800fSLey Foon Tan /*
2*35b9800fSLey Foon Tan * Copyright (C) 2016-2017 Intel Corporation
3*35b9800fSLey Foon Tan *
4*35b9800fSLey Foon Tan * SPDX-License-Identifier: GPL-2.0
5*35b9800fSLey Foon Tan */
6*35b9800fSLey Foon Tan
7*35b9800fSLey Foon Tan #include <altera.h>
8*35b9800fSLey Foon Tan #include <common.h>
9*35b9800fSLey Foon Tan #include <errno.h>
10*35b9800fSLey Foon Tan #include <fdtdec.h>
11*35b9800fSLey Foon Tan #include <miiphy.h>
12*35b9800fSLey Foon Tan #include <netdev.h>
13*35b9800fSLey Foon Tan #include <ns16550.h>
14*35b9800fSLey Foon Tan #include <watchdog.h>
15*35b9800fSLey Foon Tan #include <asm/arch/misc.h>
16*35b9800fSLey Foon Tan #include <asm/arch/pinmux.h>
17*35b9800fSLey Foon Tan #include <asm/arch/reset_manager.h>
18*35b9800fSLey Foon Tan #include <asm/arch/sdram_arria10.h>
19*35b9800fSLey Foon Tan #include <asm/arch/system_manager.h>
20*35b9800fSLey Foon Tan #include <asm/arch/nic301.h>
21*35b9800fSLey Foon Tan #include <asm/io.h>
22*35b9800fSLey Foon Tan #include <asm/pl310.h>
23*35b9800fSLey Foon Tan
24*35b9800fSLey Foon Tan #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 0x08
25*35b9800fSLey Foon Tan #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 0x58
26*35b9800fSLey Foon Tan #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3 0x68
27*35b9800fSLey Foon Tan #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 0x18
28*35b9800fSLey Foon Tan #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 0x78
29*35b9800fSLey Foon Tan #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3 0x98
30*35b9800fSLey Foon Tan
31*35b9800fSLey Foon Tan DECLARE_GLOBAL_DATA_PTR;
32*35b9800fSLey Foon Tan
33*35b9800fSLey Foon Tan #if defined(CONFIG_SPL_BUILD)
34*35b9800fSLey Foon Tan static struct pl310_regs *const pl310 =
35*35b9800fSLey Foon Tan (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
36*35b9800fSLey Foon Tan static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base =
37*35b9800fSLey Foon Tan (void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS;
38*35b9800fSLey Foon Tan #endif
39*35b9800fSLey Foon Tan
40*35b9800fSLey Foon Tan static struct socfpga_system_manager *sysmgr_regs =
41*35b9800fSLey Foon Tan (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
42*35b9800fSLey Foon Tan
43*35b9800fSLey Foon Tan /*
44*35b9800fSLey Foon Tan * DesignWare Ethernet initialization
45*35b9800fSLey Foon Tan */
46*35b9800fSLey Foon Tan #ifdef CONFIG_ETH_DESIGNWARE
dwmac_deassert_reset(const unsigned int of_reset_id,const u32 phymode)47*35b9800fSLey Foon Tan void dwmac_deassert_reset(const unsigned int of_reset_id,
48*35b9800fSLey Foon Tan const u32 phymode)
49*35b9800fSLey Foon Tan {
50*35b9800fSLey Foon Tan u32 reset;
51*35b9800fSLey Foon Tan
52*35b9800fSLey Foon Tan if (of_reset_id == EMAC0_RESET) {
53*35b9800fSLey Foon Tan reset = SOCFPGA_RESET(EMAC0);
54*35b9800fSLey Foon Tan } else if (of_reset_id == EMAC1_RESET) {
55*35b9800fSLey Foon Tan reset = SOCFPGA_RESET(EMAC1);
56*35b9800fSLey Foon Tan } else if (of_reset_id == EMAC2_RESET) {
57*35b9800fSLey Foon Tan reset = SOCFPGA_RESET(EMAC2);
58*35b9800fSLey Foon Tan } else {
59*35b9800fSLey Foon Tan printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id);
60*35b9800fSLey Foon Tan return;
61*35b9800fSLey Foon Tan }
62*35b9800fSLey Foon Tan
63*35b9800fSLey Foon Tan clrsetbits_le32(&sysmgr_regs->emac[of_reset_id - EMAC0_RESET],
64*35b9800fSLey Foon Tan SYSMGR_EMACGRP_CTRL_PHYSEL_MASK,
65*35b9800fSLey Foon Tan phymode);
66*35b9800fSLey Foon Tan
67*35b9800fSLey Foon Tan /* Release the EMAC controller from reset */
68*35b9800fSLey Foon Tan socfpga_per_reset(reset, 0);
69*35b9800fSLey Foon Tan }
70*35b9800fSLey Foon Tan #endif
71*35b9800fSLey Foon Tan
72*35b9800fSLey Foon Tan #if defined(CONFIG_SPL_BUILD)
73*35b9800fSLey Foon Tan /*
74*35b9800fSLey Foon Tan + * This function initializes security policies to be consistent across
75*35b9800fSLey Foon Tan + * all logic units in the Arria 10.
76*35b9800fSLey Foon Tan + *
77*35b9800fSLey Foon Tan + * The idea is to set all security policies to be normal, nonsecure
78*35b9800fSLey Foon Tan + * for all units.
79*35b9800fSLey Foon Tan + */
initialize_security_policies(void)80*35b9800fSLey Foon Tan static void initialize_security_policies(void)
81*35b9800fSLey Foon Tan {
82*35b9800fSLey Foon Tan /* Put OCRAM in non-secure */
83*35b9800fSLey Foon Tan writel(0x003f0000, &noc_fw_ocram_base->region0);
84*35b9800fSLey Foon Tan writel(0x1, &noc_fw_ocram_base->enable);
85*35b9800fSLey Foon Tan }
86*35b9800fSLey Foon Tan
arch_early_init_r(void)87*35b9800fSLey Foon Tan int arch_early_init_r(void)
88*35b9800fSLey Foon Tan {
89*35b9800fSLey Foon Tan initialize_security_policies();
90*35b9800fSLey Foon Tan
91*35b9800fSLey Foon Tan /* Configure the L2 controller to make SDRAM start at 0 */
92*35b9800fSLey Foon Tan writel(0x1, &pl310->pl310_addr_filter_start);
93*35b9800fSLey Foon Tan
94*35b9800fSLey Foon Tan /* assert reset to all except L4WD0 and L4TIMER0 */
95*35b9800fSLey Foon Tan socfpga_per_reset_all();
96*35b9800fSLey Foon Tan
97*35b9800fSLey Foon Tan /* configuring the clock based on handoff */
98*35b9800fSLey Foon Tan /* TODO: Add call to cm_basic_init() */
99*35b9800fSLey Foon Tan
100*35b9800fSLey Foon Tan /* Add device descriptor to FPGA device table */
101*35b9800fSLey Foon Tan socfpga_fpga_add();
102*35b9800fSLey Foon Tan return 0;
103*35b9800fSLey Foon Tan }
104*35b9800fSLey Foon Tan #else
arch_early_init_r(void)105*35b9800fSLey Foon Tan int arch_early_init_r(void)
106*35b9800fSLey Foon Tan {
107*35b9800fSLey Foon Tan return 0;
108*35b9800fSLey Foon Tan }
109*35b9800fSLey Foon Tan #endif
110*35b9800fSLey Foon Tan
111*35b9800fSLey Foon Tan /*
112*35b9800fSLey Foon Tan * This function looking the 1st encounter UART peripheral,
113*35b9800fSLey Foon Tan * and then return its offset of the dedicated/shared IO pin
114*35b9800fSLey Foon Tan * mux. offset value (zero and above).
115*35b9800fSLey Foon Tan */
find_peripheral_uart(const void * blob,int child,const char * node_name)116*35b9800fSLey Foon Tan static int find_peripheral_uart(const void *blob,
117*35b9800fSLey Foon Tan int child, const char *node_name)
118*35b9800fSLey Foon Tan {
119*35b9800fSLey Foon Tan int len;
120*35b9800fSLey Foon Tan fdt_addr_t base_addr = 0;
121*35b9800fSLey Foon Tan fdt_size_t size;
122*35b9800fSLey Foon Tan const u32 *cell;
123*35b9800fSLey Foon Tan u32 value, offset = 0;
124*35b9800fSLey Foon Tan
125*35b9800fSLey Foon Tan base_addr = fdtdec_get_addr_size(blob, child, "reg", &size);
126*35b9800fSLey Foon Tan if (base_addr != FDT_ADDR_T_NONE) {
127*35b9800fSLey Foon Tan cell = fdt_getprop(blob, child, "pinctrl-single,pins",
128*35b9800fSLey Foon Tan &len);
129*35b9800fSLey Foon Tan if (cell != NULL) {
130*35b9800fSLey Foon Tan for (; len > 0; len -= (2 * sizeof(u32))) {
131*35b9800fSLey Foon Tan offset = fdt32_to_cpu(*cell++);
132*35b9800fSLey Foon Tan value = fdt32_to_cpu(*cell++);
133*35b9800fSLey Foon Tan /* Found UART peripheral. */
134*35b9800fSLey Foon Tan if (value == PINMUX_UART)
135*35b9800fSLey Foon Tan return offset;
136*35b9800fSLey Foon Tan }
137*35b9800fSLey Foon Tan }
138*35b9800fSLey Foon Tan }
139*35b9800fSLey Foon Tan return -EINVAL;
140*35b9800fSLey Foon Tan }
141*35b9800fSLey Foon Tan
142*35b9800fSLey Foon Tan /*
143*35b9800fSLey Foon Tan * This function looks up the 1st encounter UART peripheral,
144*35b9800fSLey Foon Tan * and then return its offset of the dedicated/shared IO pin
145*35b9800fSLey Foon Tan * mux. UART peripheral is found if the offset is not in negative
146*35b9800fSLey Foon Tan * value.
147*35b9800fSLey Foon Tan */
is_peripheral_uart_true(const void * blob,int node,const char * child_name)148*35b9800fSLey Foon Tan static int is_peripheral_uart_true(const void *blob,
149*35b9800fSLey Foon Tan int node, const char *child_name)
150*35b9800fSLey Foon Tan {
151*35b9800fSLey Foon Tan int child, len;
152*35b9800fSLey Foon Tan const char *node_name;
153*35b9800fSLey Foon Tan
154*35b9800fSLey Foon Tan child = fdt_first_subnode(blob, node);
155*35b9800fSLey Foon Tan
156*35b9800fSLey Foon Tan if (child < 0)
157*35b9800fSLey Foon Tan return -EINVAL;
158*35b9800fSLey Foon Tan
159*35b9800fSLey Foon Tan node_name = fdt_get_name(blob, child, &len);
160*35b9800fSLey Foon Tan
161*35b9800fSLey Foon Tan while (node_name) {
162*35b9800fSLey Foon Tan if (!strcmp(child_name, node_name))
163*35b9800fSLey Foon Tan return find_peripheral_uart(blob, child, node_name);
164*35b9800fSLey Foon Tan
165*35b9800fSLey Foon Tan child = fdt_next_subnode(blob, child);
166*35b9800fSLey Foon Tan if (child < 0)
167*35b9800fSLey Foon Tan break;
168*35b9800fSLey Foon Tan
169*35b9800fSLey Foon Tan node_name = fdt_get_name(blob, child, &len);
170*35b9800fSLey Foon Tan }
171*35b9800fSLey Foon Tan
172*35b9800fSLey Foon Tan return -1;
173*35b9800fSLey Foon Tan }
174*35b9800fSLey Foon Tan
175*35b9800fSLey Foon Tan /*
176*35b9800fSLey Foon Tan * This function looking the 1st encounter UART dedicated IO peripheral,
177*35b9800fSLey Foon Tan * and then return based address of the 1st encounter UART dedicated
178*35b9800fSLey Foon Tan * IO peripheral.
179*35b9800fSLey Foon Tan */
dedicated_uart_com_port(const void * blob)180*35b9800fSLey Foon Tan unsigned int dedicated_uart_com_port(const void *blob)
181*35b9800fSLey Foon Tan {
182*35b9800fSLey Foon Tan int node;
183*35b9800fSLey Foon Tan
184*35b9800fSLey Foon Tan node = fdtdec_next_compatible(blob, 0,
185*35b9800fSLey Foon Tan COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
186*35b9800fSLey Foon Tan if (node < 0)
187*35b9800fSLey Foon Tan return 0;
188*35b9800fSLey Foon Tan
189*35b9800fSLey Foon Tan if (is_peripheral_uart_true(blob, node, "dedicated") >= 0)
190*35b9800fSLey Foon Tan return SOCFPGA_UART1_ADDRESS;
191*35b9800fSLey Foon Tan
192*35b9800fSLey Foon Tan return 0;
193*35b9800fSLey Foon Tan }
194*35b9800fSLey Foon Tan
195*35b9800fSLey Foon Tan /*
196*35b9800fSLey Foon Tan * This function looking the 1st encounter UART shared IO peripheral, and then
197*35b9800fSLey Foon Tan * return based address of the 1st encounter UART shared IO peripheral.
198*35b9800fSLey Foon Tan */
shared_uart_com_port(const void * blob)199*35b9800fSLey Foon Tan unsigned int shared_uart_com_port(const void *blob)
200*35b9800fSLey Foon Tan {
201*35b9800fSLey Foon Tan int node, ret;
202*35b9800fSLey Foon Tan
203*35b9800fSLey Foon Tan node = fdtdec_next_compatible(blob, 0,
204*35b9800fSLey Foon Tan COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
205*35b9800fSLey Foon Tan if (node < 0)
206*35b9800fSLey Foon Tan return 0;
207*35b9800fSLey Foon Tan
208*35b9800fSLey Foon Tan ret = is_peripheral_uart_true(blob, node, "shared");
209*35b9800fSLey Foon Tan
210*35b9800fSLey Foon Tan if (ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 ||
211*35b9800fSLey Foon Tan ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 ||
212*35b9800fSLey Foon Tan ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3)
213*35b9800fSLey Foon Tan return SOCFPGA_UART0_ADDRESS;
214*35b9800fSLey Foon Tan else if (ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 ||
215*35b9800fSLey Foon Tan ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 ||
216*35b9800fSLey Foon Tan ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3)
217*35b9800fSLey Foon Tan return SOCFPGA_UART1_ADDRESS;
218*35b9800fSLey Foon Tan
219*35b9800fSLey Foon Tan return 0;
220*35b9800fSLey Foon Tan }
221*35b9800fSLey Foon Tan
222*35b9800fSLey Foon Tan /*
223*35b9800fSLey Foon Tan * This function looking the 1st encounter UART peripheral, and then return
224*35b9800fSLey Foon Tan * base address of the 1st encounter UART peripheral.
225*35b9800fSLey Foon Tan */
uart_com_port(const void * blob)226*35b9800fSLey Foon Tan unsigned int uart_com_port(const void *blob)
227*35b9800fSLey Foon Tan {
228*35b9800fSLey Foon Tan unsigned int ret;
229*35b9800fSLey Foon Tan
230*35b9800fSLey Foon Tan ret = dedicated_uart_com_port(blob);
231*35b9800fSLey Foon Tan
232*35b9800fSLey Foon Tan if (ret)
233*35b9800fSLey Foon Tan return ret;
234*35b9800fSLey Foon Tan
235*35b9800fSLey Foon Tan return shared_uart_com_port(blob);
236*35b9800fSLey Foon Tan }
237*35b9800fSLey Foon Tan
238*35b9800fSLey Foon Tan /*
239*35b9800fSLey Foon Tan * Print CPU information
240*35b9800fSLey Foon Tan */
241*35b9800fSLey Foon Tan #if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo(void)242*35b9800fSLey Foon Tan int print_cpuinfo(void)
243*35b9800fSLey Foon Tan {
244*35b9800fSLey Foon Tan const u32 bsel =
245*35b9800fSLey Foon Tan SYSMGR_GET_BOOTINFO_BSEL(readl(&sysmgr_regs->bootinfo));
246*35b9800fSLey Foon Tan
247*35b9800fSLey Foon Tan puts("CPU: Altera SoCFPGA Arria 10\n");
248*35b9800fSLey Foon Tan
249*35b9800fSLey Foon Tan printf("BOOT: %s\n", bsel_str[bsel].name);
250*35b9800fSLey Foon Tan return 0;
251*35b9800fSLey Foon Tan }
252*35b9800fSLey Foon Tan #endif
253*35b9800fSLey Foon Tan
254*35b9800fSLey Foon Tan #ifdef CONFIG_ARCH_MISC_INIT
arch_misc_init(void)255*35b9800fSLey Foon Tan int arch_misc_init(void)
256*35b9800fSLey Foon Tan {
257*35b9800fSLey Foon Tan return 0;
258*35b9800fSLey Foon Tan }
259*35b9800fSLey Foon Tan #endif
260