blob: 21afbc7f39aea27c405e2ca5b8d84be7a718396a [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Valentin Longchampc98bf292013-10-18 11:47:24 +02002/*
3 * (C) Copyright 2013 Keymile AG
4 * Valentin Longchamp <valentin.longchamp@keymile.com>
5 *
6 * Copyright 2011,2012 Freescale Semiconductor, Inc.
Valentin Longchampc98bf292013-10-18 11:47:24 +02007 */
8
9#include <common.h>
10#include <command.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060011#include <env.h>
Simon Glass3bbe70c2019-12-28 10:44:54 -070012#include <fdt_support.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060013#include <image.h>
Simon Glassa7b51302019-11-14 12:57:46 -070014#include <init.h>
Valentin Longchampc98bf292013-10-18 11:47:24 +020015#include <netdev.h>
16#include <linux/compiler.h>
17#include <asm/mmu.h>
18#include <asm/processor.h>
19#include <asm/cache.h>
20#include <asm/immap_85xx.h>
21#include <asm/fsl_law.h>
22#include <asm/fsl_serdes.h>
23#include <asm/fsl_portals.h>
24#include <asm/fsl_liodn.h>
25#include <fm_eth.h>
26
27#include "../common/common.h"
Holger Brunck95626872020-01-10 12:47:42 +010028#include "../common/qrio.h"
Valentin Longchampc98bf292013-10-18 11:47:24 +020029#include "kmp204x.h"
30
Valentin Longchamp14039f82015-02-10 17:10:15 +010031static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
32
Valentin Longchampc98bf292013-10-18 11:47:24 +020033int checkboard(void)
34{
Holger Brunckb3d5f192019-11-26 19:09:02 +010035 printf("Board: Keymile %s\n", CONFIG_SYS_CONFIG_NAME);
Valentin Longchampc98bf292013-10-18 11:47:24 +020036
37 return 0;
38}
39
Valentin Longchampc98bf292013-10-18 11:47:24 +020040#define ZL30158_RST 8
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +020041#define BFTIC4_RST 0
Boschung, Rainer59a31c92014-06-03 09:05:18 +020042#define RSTRQSR1_WDT_RR 0x00200000
43#define RSTRQSR1_SW_RR 0x00100000
Valentin Longchampc98bf292013-10-18 11:47:24 +020044
45int board_early_init_f(void)
46{
47 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
Boschung, Rainer59a31c92014-06-03 09:05:18 +020048 bool cpuwd_flag = false;
Valentin Longchampc98bf292013-10-18 11:47:24 +020049
Boschung, Rainer6e093fc2014-06-03 09:05:20 +020050 /* configure mode for uP reset request */
51 qrio_uprstreq(UPREQ_CORE_RST);
52
Valentin Longchampc98bf292013-10-18 11:47:24 +020053 /* board only uses the DDR_MCK0, so disable the DDR_MCK1/2/3 */
54 setbits_be32(&gur->ddrclkdr, 0x001f000f);
55
Boschung, Rainer59a31c92014-06-03 09:05:18 +020056 /* set reset reason according CPU register */
57 if ((gur->rstrqsr1 & (RSTRQSR1_WDT_RR | RSTRQSR1_SW_RR)) ==
58 RSTRQSR1_WDT_RR)
59 cpuwd_flag = true;
60
61 qrio_cpuwd_flag(cpuwd_flag);
62 /* clear CPU bits by writing 1 */
63 setbits_be32(&gur->rstrqsr1, RSTRQSR1_WDT_RR | RSTRQSR1_SW_RR);
64
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +020065 /* set the BFTIC's prstcfg to reset at power-up and unit reset only */
66 qrio_prstcfg(BFTIC4_RST, PRSTCFG_POWUP_UNIT_RST);
67 /* and enable WD on it */
68 qrio_wdmask(BFTIC4_RST, true);
Valentin Longchampc98bf292013-10-18 11:47:24 +020069
Valentin Longchamp2b293032014-08-19 15:40:04 +020070 /* set the ZL30138's prstcfg to reset at power-up only */
71 qrio_prstcfg(ZL30158_RST, PRSTCFG_POWUP_RST);
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +020072 /* and take it out of reset as soon as possible (needed for Hooper) */
73 qrio_prst(ZL30158_RST, false, false);
Valentin Longchampc98bf292013-10-18 11:47:24 +020074
75 return 0;
76}
77
78int board_early_init_r(void)
79{
Valentin Longchampdc146da2014-01-27 11:49:12 +010080 int ret = 0;
Valentin Longchampc98bf292013-10-18 11:47:24 +020081 /* Flush d-cache and invalidate i-cache of any FLASH data */
82 flush_dcache();
83 invalidate_icache();
84
85 set_liodns();
Ahmed Mansouraa270b42017-12-15 16:01:00 -050086 setup_qbman_portals();
Valentin Longchampc98bf292013-10-18 11:47:24 +020087
Valentin Longchampdc146da2014-01-27 11:49:12 +010088 ret = trigger_fpga_config();
89 if (ret)
90 printf("error triggering PCIe FPGA config\n");
91
Stefan Bigler8b6f6c32014-05-02 10:48:41 +020092 /* enable the Unit LED (red) & Boot LED (on) */
93 qrio_set_leds();
94
Stefan Biglerdafc72d2014-05-02 10:49:27 +020095 /* enable Application Buffer */
96 qrio_enable_app_buffer();
97
Holger Brunck67d16022020-01-10 12:47:41 +010098 return 0;
Valentin Longchampc98bf292013-10-18 11:47:24 +020099}
100
101unsigned long get_board_sys_clk(unsigned long dummy)
102{
103 return 66666666;
104}
105
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200106#define ETH_FRONT_PHY_RST 15
107#define QSFP2_RST 11
108#define QSFP1_RST 10
109#define ZL30343_RST 9
110
Rainer Boschung71a2e822014-02-03 08:45:40 +0100111int misc_init_f(void)
112{
113 /* configure QRIO pis for i2c deblocking */
114 i2c_deblock_gpio_cfg();
115
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200116 /* configure the front phy's prstcfg and take it out of reset */
117 qrio_prstcfg(ETH_FRONT_PHY_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
118 qrio_prst(ETH_FRONT_PHY_RST, false, false);
119
Valentin Longchamp2b293032014-08-19 15:40:04 +0200120 /* set the ZL30343 prstcfg to reset at power-up only */
121 qrio_prstcfg(ZL30343_RST, PRSTCFG_POWUP_RST);
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200122 /* and enable the WD on it */
123 qrio_wdmask(ZL30343_RST, true);
124
125 /* set the QSFPs' prstcfg to reset at power-up and unit rst only */
126 qrio_prstcfg(QSFP1_RST, PRSTCFG_POWUP_UNIT_RST);
127 qrio_prstcfg(QSFP2_RST, PRSTCFG_POWUP_UNIT_RST);
128
129 /* and enable the WD on them */
130 qrio_wdmask(QSFP1_RST, true);
131 qrio_wdmask(QSFP2_RST, true);
132
Rainer Boschung71a2e822014-02-03 08:45:40 +0100133 return 0;
134}
135
Valentin Longchampc98bf292013-10-18 11:47:24 +0200136#define NUM_SRDS_BANKS 2
Valentin Longchampc98bf292013-10-18 11:47:24 +0200137
138int misc_init_r(void)
139{
140 serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
141 u32 expected[NUM_SRDS_BANKS] = {SRDS_PLLCR0_RFCK_SEL_100,
142 SRDS_PLLCR0_RFCK_SEL_125};
143 unsigned int i;
144
145 /* check SERDES reference clocks */
146 for (i = 0; i < NUM_SRDS_BANKS; i++) {
147 u32 actual = in_be32(&regs->bank[i].pllcr0);
148 actual &= SRDS_PLLCR0_RFCK_SEL_MASK;
149 if (actual != expected[i]) {
150 printf("Warning: SERDES bank %u expects reference \
151 clock %sMHz, but actual is %sMHz\n", i + 1,
152 serdes_clock_to_string(expected[i]),
153 serdes_clock_to_string(actual));
154 }
155 }
156
Holger Brunck0340b6a2019-11-25 17:24:14 +0100157 ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN,
158 CONFIG_PIGGY_MAC_ADDRESS_OFFSET);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200159 return 0;
160}
161
162#if defined(CONFIG_HUSH_INIT_VAR)
163int hush_init_var(void)
164{
Valentin Longchamp14039f82015-02-10 17:10:15 +0100165 ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200166 return 0;
167}
168#endif
169
170#if defined(CONFIG_LAST_STAGE_INIT)
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200171
Valentin Longchampc98bf292013-10-18 11:47:24 +0200172int last_stage_init(void)
173{
Stefan Biglerdafc72d2014-05-02 10:49:27 +0200174#if defined(CONFIG_KMCOGE4)
175 /* on KMCOGE4, the BFTIC4 is on the LBAPP2 */
176 struct bfticu_iomap *bftic4 =
177 (struct bfticu_iomap *)CONFIG_SYS_LBAPP2_BASE;
178 u8 dip_switch = in_8((u8 *)&(bftic4->mswitch)) & BFTICU_DIPSWITCH_MASK;
179
180 if (dip_switch != 0) {
181 /* start bootloader */
182 puts("DIP: Enabled\n");
Simon Glass6a38e412017-08-03 12:22:09 -0600183 env_set("actual_bank", "0");
Stefan Biglerdafc72d2014-05-02 10:49:27 +0200184 }
185#endif
Valentin Longchampc98bf292013-10-18 11:47:24 +0200186 set_km_env();
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200187
Valentin Longchampc98bf292013-10-18 11:47:24 +0200188 return 0;
189}
190#endif
191
192#ifdef CONFIG_SYS_DPAA_FMAN
193void fdt_fixup_fman_mac_addresses(void *blob)
194{
195 int node, i, ret;
196 char *tmp, *end;
197 unsigned char mac_addr[6];
198
199 /* get the mac addr from env */
Simon Glass64b723f2017-08-03 12:22:12 -0600200 tmp = env_get("ethaddr");
Valentin Longchampc98bf292013-10-18 11:47:24 +0200201 if (!tmp) {
202 printf("ethaddr env variable not defined\n");
203 return;
204 }
205 for (i = 0; i < 6; i++) {
206 mac_addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
207 if (tmp)
208 tmp = (*end) ? end+1 : end;
209 }
210
211 /* find the correct fdt ethernet path and correct it */
212 node = fdt_path_offset(blob, "/soc/fman/ethernet@e8000");
213 if (node < 0) {
214 printf("no /soc/fman/ethernet path offset\n");
215 return;
216 }
217 ret = fdt_setprop(blob, node, "local-mac-address", &mac_addr, 6);
218 if (ret) {
219 printf("error setting local-mac-address property\n");
220 return;
221 }
222}
223#endif
224
Simon Glass2aec3cc2014-10-23 18:58:47 -0600225int ft_board_setup(void *blob, bd_t *bd)
Valentin Longchampc98bf292013-10-18 11:47:24 +0200226{
227 phys_addr_t base;
228 phys_size_t size;
229
230 ft_cpu_setup(blob, bd);
231
Simon Glassda1a1342017-08-03 12:22:15 -0600232 base = env_get_bootm_low();
233 size = env_get_bootm_size();
Valentin Longchampc98bf292013-10-18 11:47:24 +0200234
235 fdt_fixup_memory(blob, (u64)base, (u64)size);
236
237#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB)
Sriram Dash9fd465c2016-09-16 17:12:15 +0530238 fsl_fdt_fixup_dr_usb(blob, bd);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200239#endif
240
241#ifdef CONFIG_PCI
242 pci_of_setup(blob, bd);
243#endif
244
245 fdt_fixup_liodn(blob);
246#ifdef CONFIG_SYS_DPAA_FMAN
247 fdt_fixup_fman_ethernet(blob);
248 fdt_fixup_fman_mac_addresses(blob);
249#endif
Simon Glass2aec3cc2014-10-23 18:58:47 -0600250
251 return 0;
Valentin Longchampc98bf292013-10-18 11:47:24 +0200252}
Valentin Longchampec92cdb2014-04-30 15:01:44 +0200253
254#if defined(CONFIG_POST)
255
256/* DIC26_SELFTEST GPIO used to start factory test sw */
Holger Brunck95626872020-01-10 12:47:42 +0100257#define SELFTEST_PORT QRIO_GPIO_A
Valentin Longchampec92cdb2014-04-30 15:01:44 +0200258#define SELFTEST_PIN 31
259
260int post_hotkeys_pressed(void)
261{
262 qrio_gpio_direction_input(SELFTEST_PORT, SELFTEST_PIN);
263 return qrio_get_gpio(SELFTEST_PORT, SELFTEST_PIN);
264}
265#endif