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