blob: a022da98277beddd6f52474831bef55fdcf1676a [file] [log] [blame]
Ashish Kumare84a3242017-08-31 16:12:54 +05301/*
2 * Copyright 2017 NXP
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6#include <common.h>
7#include <i2c.h>
8#include <malloc.h>
9#include <errno.h>
10#include <netdev.h>
11#include <fsl_ifc.h>
12#include <fsl_ddr.h>
13#include <fsl_sec.h>
14#include <asm/io.h>
15#include <fdt_support.h>
16#include <libfdt.h>
17#include <fsl-mc/fsl_mc.h>
18#include <environment.h>
19#include <asm/arch-fsl-layerscape/soc.h>
20#include <asm/arch/ppa.h>
21
22#include "../common/qixis.h"
23#include "ls1088a_qixis.h"
24
25DECLARE_GLOBAL_DATA_PTR;
26
27unsigned long long get_qixis_addr(void)
28{
29 unsigned long long addr;
30
31 if (gd->flags & GD_FLG_RELOC)
32 addr = QIXIS_BASE_PHYS;
33 else
34 addr = QIXIS_BASE_PHYS_EARLY;
35
36 /*
37 * IFC address under 256MB is mapped to 0x30000000, any address above
38 * is mapped to 0x5_10000000 up to 4GB.
39 */
40 addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000;
41
42 return addr;
43}
44
45int checkboard(void)
46{
47 char buf[64];
48 u8 sw;
49 static const char *const freq[] = {"100", "125", "156.25",
50 "100 separate SSCG"};
51 int clock;
52
53
54 printf("Board: LS1088A-RDB, ");
55
56 sw = QIXIS_READ(arch);
57 printf("Board Arch: V%d, ", sw >> 4);
58
59 printf("Board version: %c, boot from ", (sw & 0xf) + 'A');
60
61
62 memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
63
64 sw = QIXIS_READ(brdcfg[0]);
65 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
66
67#ifdef CONFIG_SD_BOOT
68 puts("SD card\n");
69#endif
70 switch (sw) {
71 case 0:
72
73 puts("QSPI:");
74 sw = QIXIS_READ(brdcfg[0]);
75 sw = (sw & QIXIS_QMAP_MASK) >> QIXIS_QMAP_SHIFT;
76 if (sw == 0 || sw == 4)
77 puts("0\n");
78 else if (sw == 1)
79 puts("1\n");
80 else
81 puts("EMU\n");
82 break;
83
84 default:
85 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
86 break;
87 }
88
89
90 printf("CPLD: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
91
92
93 /*
94 * Display the actual SERDES reference clocks as configured by the
95 * dip switches on the board. Note that the SWx registers could
96 * technically be set to force the reference clocks to match the
97 * values that the SERDES expects (or vice versa). For now, however,
98 * we just display both values and hope the user notices when they
99 * don't match.
100 */
101 puts("SERDES1 Reference : ");
102 sw = QIXIS_READ(brdcfg[2]);
103 clock = (sw >> 6) & 3;
104 printf("Clock1 = %sMHz ", freq[clock]);
105 clock = (sw >> 4) & 3;
106 printf("Clock2 = %sMHz", freq[clock]);
107
108 puts("\nSERDES2 Reference : ");
109 clock = (sw >> 2) & 3;
110 printf("Clock1 = %sMHz ", freq[clock]);
111 clock = (sw >> 0) & 3;
112 printf("Clock2 = %sMHz\n", freq[clock]);
113
114 return 0;
115}
116
117bool if_board_diff_clk(void)
118{
119 u8 diff_conf = QIXIS_READ(dutcfg[11]);
120 return diff_conf & 0x80;
121}
122
123unsigned long get_board_sys_clk(void)
124{
125 u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
126
127 switch (sysclk_conf & 0x0f) {
128 case QIXIS_SYSCLK_83:
129 return 83333333;
130 case QIXIS_SYSCLK_100:
131 return 100000000;
132 case QIXIS_SYSCLK_125:
133 return 125000000;
134 case QIXIS_SYSCLK_133:
135 return 133333333;
136 case QIXIS_SYSCLK_150:
137 return 150000000;
138 case QIXIS_SYSCLK_160:
139 return 160000000;
140 case QIXIS_SYSCLK_166:
141 return 166666666;
142 }
143
144 return 66666666;
145}
146
147unsigned long get_board_ddr_clk(void)
148{
149 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
150
151 if (if_board_diff_clk())
152 return get_board_sys_clk();
153 switch ((ddrclk_conf & 0x30) >> 4) {
154 case QIXIS_DDRCLK_100:
155 return 100000000;
156 case QIXIS_DDRCLK_125:
157 return 125000000;
158 case QIXIS_DDRCLK_133:
159 return 133333333;
160 }
161
162 return 66666666;
163}
164
165int select_i2c_ch_pca9547(u8 ch)
166{
167 int ret;
168
169 ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
170 if (ret) {
171 puts("PCA: failed to select proper channel\n");
172 return ret;
173 }
174
175 return 0;
176}
177
178void board_retimer_init(void)
179{
180 u8 reg;
181
182 /* Retimer is connected to I2C1_CH5 */
183 select_i2c_ch_pca9547(I2C_MUX_CH5);
184
185 /* Access to Control/Shared register */
186 reg = 0x0;
187 i2c_write(I2C_RETIMER_ADDR, 0xff, 1, &reg, 1);
188
189 /* Read device revision and ID */
190 i2c_read(I2C_RETIMER_ADDR, 1, 1, &reg, 1);
191 debug("Retimer version id = 0x%x\n", reg);
192
193 /* Enable Broadcast. All writes target all channel register sets */
194 reg = 0x0c;
195 i2c_write(I2C_RETIMER_ADDR, 0xff, 1, &reg, 1);
196
197 /* Reset Channel Registers */
198 i2c_read(I2C_RETIMER_ADDR, 0, 1, &reg, 1);
199 reg |= 0x4;
200 i2c_write(I2C_RETIMER_ADDR, 0, 1, &reg, 1);
201
202 /* Set data rate as 10.3125 Gbps */
203 reg = 0x90;
204 i2c_write(I2C_RETIMER_ADDR, 0x60, 1, &reg, 1);
205 reg = 0xb3;
206 i2c_write(I2C_RETIMER_ADDR, 0x61, 1, &reg, 1);
207 reg = 0x90;
208 i2c_write(I2C_RETIMER_ADDR, 0x62, 1, &reg, 1);
209 reg = 0xb3;
210 i2c_write(I2C_RETIMER_ADDR, 0x63, 1, &reg, 1);
211 reg = 0xcd;
212 i2c_write(I2C_RETIMER_ADDR, 0x64, 1, &reg, 1);
213
214 /* Select VCO Divider to full rate (000) */
215 i2c_read(I2C_RETIMER_ADDR, 0x2F, 1, &reg, 1);
216 reg &= 0x0f;
217 reg |= 0x70;
218 i2c_write(I2C_RETIMER_ADDR, 0x2F, 1, &reg, 1);
219
220
221 /*return the default channel*/
222 select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
223}
224
225int board_init(void)
226{
227 init_final_memctl_regs();
228#if defined(CONFIG_TARGET_LS1088ARDB) && defined(CONFIG_FSL_MC_ENET)
229 u32 __iomem *irq_ccsr = (u32 __iomem *)ISC_BASE;
230#endif
231
232 select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
233 board_retimer_init();
234
235#ifdef CONFIG_ENV_IS_NOWHERE
236 gd->env_addr = (ulong)&default_environment[0];
237#endif
238
239#if defined(CONFIG_TARGET_LS1088ARDB) && defined(CONFIG_FSL_MC_ENET)
240 /* invert AQR105 IRQ pins polarity */
241 out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR105_IRQ_MASK);
242#endif
243
244#ifdef CONFIG_FSL_LS_PPA
245 ppa_init();
246#endif
247 return 0;
248}
249
250int board_early_init_f(void)
251{
252 fsl_lsch3_early_init_f();
253 return 0;
254}
255
256void detail_board_ddr_info(void)
257{
258 puts("\nDDR ");
259 print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
260 print_ddr_info(0);
261}
262
263#if defined(CONFIG_ARCH_MISC_INIT)
264int arch_misc_init(void)
265{
266#ifdef CONFIG_FSL_CAAM
267 sec_init();
268#endif
269 return 0;
270}
271#endif
272
273#ifdef CONFIG_FSL_MC_ENET
274void fdt_fixup_board_enet(void *fdt)
275{
276 int offset;
277
278 offset = fdt_path_offset(fdt, "/fsl-mc");
279
280 if (offset < 0)
281 offset = fdt_path_offset(fdt, "/fsl,dprc@0");
282
283 if (offset < 0) {
284 printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
285 __func__, offset);
286 return;
287 }
288
289 if (get_mc_boot_status() == 0)
290 fdt_status_okay(fdt, offset);
291 else
292 fdt_status_fail(fdt, offset);
293}
294#endif
295
296#ifdef CONFIG_OF_BOARD_SETUP
297int ft_board_setup(void *blob, bd_t *bd)
298{
299 int err, i;
300 u64 base[CONFIG_NR_DRAM_BANKS];
301 u64 size[CONFIG_NR_DRAM_BANKS];
302
303 ft_cpu_setup(blob, bd);
304
305 /* fixup DT for the two GPP DDR banks */
306 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
307 base[i] = gd->bd->bi_dram[i].start;
308 size[i] = gd->bd->bi_dram[i].size;
309 }
310
311#ifdef CONFIG_RESV_RAM
312 /* reduce size if reserved memory is within this bank */
313 if (gd->arch.resv_ram >= base[0] &&
314 gd->arch.resv_ram < base[0] + size[0])
315 size[0] = gd->arch.resv_ram - base[0];
316 else if (gd->arch.resv_ram >= base[1] &&
317 gd->arch.resv_ram < base[1] + size[1])
318 size[1] = gd->arch.resv_ram - base[1];
319#endif
320
321 fdt_fixup_memory_banks(blob, base, size, CONFIG_NR_DRAM_BANKS);
322
323#ifdef CONFIG_FSL_MC_ENET
324 fdt_fixup_board_enet(blob);
325 err = fsl_mc_ldpaa_exit(bd);
326 if (err)
327 return err;
328#endif
329
330 return 0;
331}
332#endif