xref: /openbmc/u-boot/board/keymile/kmp204x/kmp204x.c (revision c346e466)
1 /*
2  * (C) Copyright 2013 Keymile AG
3  * Valentin Longchamp <valentin.longchamp@keymile.com>
4  *
5  * Copyright 2011,2012 Freescale Semiconductor, Inc.
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <command.h>
12 #include <netdev.h>
13 #include <linux/compiler.h>
14 #include <asm/mmu.h>
15 #include <asm/processor.h>
16 #include <asm/cache.h>
17 #include <asm/immap_85xx.h>
18 #include <asm/fsl_law.h>
19 #include <asm/fsl_serdes.h>
20 #include <asm/fsl_portals.h>
21 #include <asm/fsl_liodn.h>
22 #include <fm_eth.h>
23 
24 #include "../common/common.h"
25 #include "kmp204x.h"
26 
27 DECLARE_GLOBAL_DATA_PTR;
28 
29 int checkboard(void)
30 {
31 	printf("Board: Keymile %s\n", CONFIG_KM_BOARD_NAME);
32 
33 	return 0;
34 }
35 
36 /* I2C deblocking uses the algorithm defined in board/keymile/common/common.c
37  * 2 dedicated QRIO GPIOs externally pull the SCL and SDA lines
38  * For I2C only the low state is activly driven and high state is pulled-up
39  * by a resistor. Therefore the deblock GPIOs are used
40  *  -> as an active output to drive a low state
41  *  -> as an open-drain input to have a pulled-up high state
42  */
43 
44 /* QRIO GPIOs used for deblocking */
45 #define DEBLOCK_PORT1	GPIO_A
46 #define DEBLOCK_SCL1	20
47 #define DEBLOCK_SDA1	21
48 
49 /* By default deblock GPIOs are floating */
50 static void i2c_deblock_gpio_cfg(void)
51 {
52 	/* set I2C bus 1 deblocking GPIOs input, but 0 value for open drain */
53 	qrio_gpio_direction_input(DEBLOCK_PORT1, DEBLOCK_SCL1);
54 	qrio_gpio_direction_input(DEBLOCK_PORT1, DEBLOCK_SDA1);
55 
56 	qrio_set_gpio(DEBLOCK_PORT1, DEBLOCK_SCL1, 0);
57 	qrio_set_gpio(DEBLOCK_PORT1, DEBLOCK_SDA1, 0);
58 }
59 
60 void set_sda(int state)
61 {
62 	qrio_set_opendrain_gpio(DEBLOCK_PORT1, DEBLOCK_SDA1, state);
63 }
64 
65 void set_scl(int state)
66 {
67 	qrio_set_opendrain_gpio(DEBLOCK_PORT1, DEBLOCK_SCL1, state);
68 }
69 
70 int get_sda(void)
71 {
72 	return qrio_get_gpio(DEBLOCK_PORT1, DEBLOCK_SDA1);
73 }
74 
75 int get_scl(void)
76 {
77 	return qrio_get_gpio(DEBLOCK_PORT1, DEBLOCK_SCL1);
78 }
79 
80 
81 #define ZL30158_RST	8
82 #define BFTIC4_RST	0
83 
84 int board_early_init_f(void)
85 {
86 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
87 
88 	/* board only uses the DDR_MCK0, so disable the DDR_MCK1/2/3 */
89 	setbits_be32(&gur->ddrclkdr, 0x001f000f);
90 
91 	/* set the BFTIC's prstcfg to reset at power-up and unit reset only */
92 	qrio_prstcfg(BFTIC4_RST, PRSTCFG_POWUP_UNIT_RST);
93 	/* and enable WD on it */
94 	qrio_wdmask(BFTIC4_RST, true);
95 
96 	/* set the ZL30138's prstcfg to reset at power-up and unit reset only */
97 	qrio_prstcfg(ZL30158_RST, PRSTCFG_POWUP_UNIT_RST);
98 	/* and take it out of reset as soon as possible (needed for Hooper) */
99 	qrio_prst(ZL30158_RST, false, false);
100 
101 	return 0;
102 }
103 
104 int board_early_init_r(void)
105 {
106 	int ret = 0;
107 	/* Flush d-cache and invalidate i-cache of any FLASH data */
108 	flush_dcache();
109 	invalidate_icache();
110 
111 	set_liodns();
112 	setup_portals();
113 
114 	ret = trigger_fpga_config();
115 	if (ret)
116 		printf("error triggering PCIe FPGA config\n");
117 
118 	/* enable the Unit LED (red) & Boot LED (on) */
119 	qrio_set_leds();
120 
121 	/* enable Application Buffer */
122 	qrio_enable_app_buffer();
123 
124 	return ret;
125 }
126 
127 unsigned long get_board_sys_clk(unsigned long dummy)
128 {
129 	return 66666666;
130 }
131 
132 #define ETH_FRONT_PHY_RST	15
133 #define QSFP2_RST		11
134 #define QSFP1_RST		10
135 #define ZL30343_RST		9
136 
137 int misc_init_f(void)
138 {
139 	/* configure QRIO pis for i2c deblocking */
140 	i2c_deblock_gpio_cfg();
141 
142 	/* configure the front phy's prstcfg and take it out of reset */
143 	qrio_prstcfg(ETH_FRONT_PHY_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
144 	qrio_prst(ETH_FRONT_PHY_RST, false, false);
145 
146 	/* set the ZL30343 prstcfg to reset at power-up and unit reset only */
147 	qrio_prstcfg(ZL30343_RST, PRSTCFG_POWUP_UNIT_RST);
148 	/* and enable the WD on it */
149 	qrio_wdmask(ZL30343_RST, true);
150 
151 	/* set the QSFPs' prstcfg to reset at power-up and unit rst only */
152 	qrio_prstcfg(QSFP1_RST, PRSTCFG_POWUP_UNIT_RST);
153 	qrio_prstcfg(QSFP2_RST, PRSTCFG_POWUP_UNIT_RST);
154 
155 	/* and enable the WD on them */
156 	qrio_wdmask(QSFP1_RST, true);
157 	qrio_wdmask(QSFP2_RST, true);
158 
159 	return 0;
160 }
161 
162 #define NUM_SRDS_BANKS	2
163 
164 int misc_init_r(void)
165 {
166 	serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
167 	u32 expected[NUM_SRDS_BANKS] = {SRDS_PLLCR0_RFCK_SEL_100,
168 		SRDS_PLLCR0_RFCK_SEL_125};
169 	unsigned int i;
170 
171 	/* check SERDES reference clocks */
172 	for (i = 0; i < NUM_SRDS_BANKS; i++) {
173 		u32 actual = in_be32(&regs->bank[i].pllcr0);
174 		actual &= SRDS_PLLCR0_RFCK_SEL_MASK;
175 		if (actual != expected[i]) {
176 			printf("Warning: SERDES bank %u expects reference \
177 			       clock %sMHz, but actual is %sMHz\n", i + 1,
178 			       serdes_clock_to_string(expected[i]),
179 			       serdes_clock_to_string(actual));
180 		}
181 	}
182 
183 	return 0;
184 }
185 
186 #if defined(CONFIG_HUSH_INIT_VAR)
187 int hush_init_var(void)
188 {
189 	ivm_read_eeprom();
190 	return 0;
191 }
192 #endif
193 
194 #if defined(CONFIG_LAST_STAGE_INIT)
195 
196 int last_stage_init(void)
197 {
198 #if defined(CONFIG_KMCOGE4)
199 	/* on KMCOGE4, the BFTIC4 is on the LBAPP2 */
200 	struct bfticu_iomap *bftic4 =
201 		(struct bfticu_iomap *)CONFIG_SYS_LBAPP2_BASE;
202 	u8 dip_switch = in_8((u8 *)&(bftic4->mswitch)) & BFTICU_DIPSWITCH_MASK;
203 
204 	if (dip_switch != 0) {
205 		/* start bootloader */
206 		puts("DIP:   Enabled\n");
207 		setenv("actual_bank", "0");
208 	}
209 #endif
210 	set_km_env();
211 
212 	return 0;
213 }
214 #endif
215 
216 #ifdef CONFIG_SYS_DPAA_FMAN
217 void fdt_fixup_fman_mac_addresses(void *blob)
218 {
219 	int node, i, ret;
220 	char *tmp, *end;
221 	unsigned char mac_addr[6];
222 
223 	/* get the mac addr from env */
224 	tmp = getenv("ethaddr");
225 	if (!tmp) {
226 		printf("ethaddr env variable not defined\n");
227 		return;
228 	}
229 	for (i = 0; i < 6; i++) {
230 		mac_addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
231 		if (tmp)
232 			tmp = (*end) ? end+1 : end;
233 	}
234 
235 	/* find the correct fdt ethernet path and correct it */
236 	node = fdt_path_offset(blob, "/soc/fman/ethernet@e8000");
237 	if (node < 0) {
238 		printf("no /soc/fman/ethernet path offset\n");
239 		return;
240 	}
241 	ret = fdt_setprop(blob, node, "local-mac-address", &mac_addr, 6);
242 	if (ret) {
243 		printf("error setting local-mac-address property\n");
244 		return;
245 	}
246 }
247 #endif
248 
249 void ft_board_setup(void *blob, bd_t *bd)
250 {
251 	phys_addr_t base;
252 	phys_size_t size;
253 
254 	ft_cpu_setup(blob, bd);
255 
256 	base = getenv_bootm_low();
257 	size = getenv_bootm_size();
258 
259 	fdt_fixup_memory(blob, (u64)base, (u64)size);
260 
261 #if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB)
262 	fdt_fixup_dr_usb(blob, bd);
263 #endif
264 
265 #ifdef CONFIG_PCI
266 	pci_of_setup(blob, bd);
267 #endif
268 
269 	fdt_fixup_liodn(blob);
270 #ifdef CONFIG_SYS_DPAA_FMAN
271 	fdt_fixup_fman_ethernet(blob);
272 	fdt_fixup_fman_mac_addresses(blob);
273 #endif
274 }
275 
276 #if defined(CONFIG_POST)
277 
278 /* DIC26_SELFTEST GPIO used to start factory test sw */
279 #define SELFTEST_PORT	GPIO_A
280 #define SELFTEST_PIN	31
281 
282 int post_hotkeys_pressed(void)
283 {
284 	qrio_gpio_direction_input(SELFTEST_PORT, SELFTEST_PIN);
285 	return qrio_get_gpio(SELFTEST_PORT, SELFTEST_PIN);
286 }
287 #endif
288