blob: faecb60992404560075a2040989f58332675a465 [file] [log] [blame]
Yuantian Tang92f18ff2019-04-10 16:43:34 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
Alison Wangd57211b2022-05-10 18:29:10 +08003 * Copyright 2019-2022 NXP
Yuantian Tang92f18ff2019-04-10 16:43:34 +08004 */
5
6#include <common.h>
Simon Glass1ab16922022-07-31 12:28:48 -06007#include <display_options.h>
Simon Glass97589732020-05-10 11:40:02 -06008#include <init.h>
Yuantian Tang92f18ff2019-04-10 16:43:34 +08009#include <malloc.h>
10#include <errno.h>
11#include <fsl_ddr.h>
Simon Glass274e0b02020-05-10 11:39:56 -060012#include <net.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060013#include <asm/global_data.h>
Yuantian Tang92f18ff2019-04-10 16:43:34 +080014#include <asm/io.h>
15#include <hwconfig.h>
16#include <fdt_support.h>
17#include <linux/libfdt.h>
Simon Glass9d1f6192019-08-02 09:44:25 -060018#include <env_internal.h>
Yuantian Tang92f18ff2019-04-10 16:43:34 +080019#include <asm/arch-fsl-layerscape/soc.h>
Laurentiu Tudor01dc5472019-07-30 17:29:59 +030020#include <asm/arch-fsl-layerscape/fsl_icid.h>
Yuantian Tang92f18ff2019-04-10 16:43:34 +080021#include <i2c.h>
22#include <asm/arch/soc.h>
23#ifdef CONFIG_FSL_LS_PPA
24#include <asm/arch/ppa.h>
25#endif
26#include <fsl_immap.h>
27#include <netdev.h>
28
29#include <fdtdec.h>
30#include <miiphy.h>
31#include "../common/qixis.h"
Alex Marginean805b8592019-12-10 16:55:39 +020032#include "../drivers/net/fsl_enetc.h"
Yuantian Tang92f18ff2019-04-10 16:43:34 +080033
34DECLARE_GLOBAL_DATA_PTR;
35
Yuantian Tang473bbc42019-04-10 16:43:35 +080036int config_board_mux(void)
37{
Yuantian Tangd46f65e2020-03-19 16:48:23 +080038#ifndef CONFIG_LPUART
Yuantian Tang473bbc42019-04-10 16:43:35 +080039#if defined(CONFIG_TARGET_LS1028AQDS) && defined(CONFIG_FSL_QIXIS)
40 u8 reg;
41
42 reg = QIXIS_READ(brdcfg[13]);
43 /* Field| Function
44 * 7-6 | Controls I2C3 routing (net CFG_MUX_I2C3):
45 * I2C3 | 10= Routes {SCL, SDA} to CAN1 transceiver as {TX, RX}.
46 * 5-4 | Controls I2C4 routing (net CFG_MUX_I2C4):
47 * I2C4 |11= Routes {SCL, SDA} to CAN2 transceiver as {TX, RX}.
48 */
49 reg &= ~(0xf0);
50 reg |= 0xb0;
51 QIXIS_WRITE(brdcfg[13], reg);
52
53 reg = QIXIS_READ(brdcfg[15]);
54 /* Field| Function
55 * 7 | Controls the CAN1 transceiver (net CFG_CAN1_STBY):
56 * CAN1 | 0= CAN #1 transceiver enabled
57 * 6 | Controls the CAN2 transceiver (net CFG_CAN2_STBY):
58 * CAN2 | 0= CAN #2 transceiver enabled
59 */
60 reg &= ~(0xc0);
61 QIXIS_WRITE(brdcfg[15], reg);
62#endif
Yuantian Tangd46f65e2020-03-19 16:48:23 +080063#endif
64
Yuantian Tang473bbc42019-04-10 16:43:35 +080065 return 0;
66}
Yuantian Tangd46f65e2020-03-19 16:48:23 +080067
68#ifdef CONFIG_LPUART
69u32 get_lpuart_clk(void)
70{
71 return gd->bus_clk / CONFIG_SYS_FSL_LPUART_CLK_DIV;
72}
73#endif
Yuantian Tang473bbc42019-04-10 16:43:35 +080074
Yuantian Tang92f18ff2019-04-10 16:43:34 +080075int board_init(void)
76{
Yuantian Tang92f18ff2019-04-10 16:43:34 +080077#ifdef CONFIG_FSL_LS_PPA
78 ppa_init();
79#endif
80
81#ifndef CONFIG_SYS_EARLY_PCI_INIT
82 pci_init();
83#endif
84
85#if defined(CONFIG_TARGET_LS1028ARDB)
86 u8 val = I2C_MUX_CH_DEFAULT;
87
Igor Opaniukf7c91762021-02-09 13:52:45 +020088#if !CONFIG_IS_ENABLED(DM_I2C)
Yuantian Tang92f18ff2019-04-10 16:43:34 +080089 i2c_write(I2C_MUX_PCA_ADDR_PRI, 0x0b, 1, &val, 1);
Chuanhua Haneaf4a7c2019-07-10 21:16:49 +080090#else
91 struct udevice *dev;
92
93 if (!i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev))
94 dm_i2c_write(dev, 0x0b, &val, 1);
95#endif
Wen He41e63db2019-11-18 13:26:09 +080096#endif
97
98#if defined(CONFIG_TARGET_LS1028ARDB)
99 u8 reg;
Chuanhua Haneaf4a7c2019-07-10 21:16:49 +0800100
Wen He41e63db2019-11-18 13:26:09 +0800101 reg = QIXIS_READ(brdcfg[4]);
102 /*
103 * Field | Function
104 * 3 | DisplayPort Power Enable (net DP_PWR_EN):
105 * DPPWR | 0= DP_PWR is enabled.
106 */
107 reg &= ~(DP_PWD_EN_DEFAULT_MASK);
108 QIXIS_WRITE(brdcfg[4], reg);
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800109#endif
110 return 0;
111}
112
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900113int board_eth_init(struct bd_info *bis)
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800114{
115 return pci_eth_init(bis);
116}
117
Alex Margineanf57e45a2020-01-11 01:05:39 +0200118#ifdef CONFIG_MISC_INIT_R
119int misc_init_r(void)
Yuantian Tang473bbc42019-04-10 16:43:35 +0800120{
121 config_board_mux();
122
123 return 0;
124}
125#endif
126
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800127int board_early_init_f(void)
128{
Yuantian Tangd46f65e2020-03-19 16:48:23 +0800129#ifdef CONFIG_LPUART
130 u8 uart;
131#endif
132
Tom Rini714482a2021-08-18 23:12:25 -0400133#if defined(CONFIG_SYS_I2C_EARLY_INIT) && defined(CONFIG_SPL_BUILD)
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800134 i2c_early_init_f();
135#endif
136
137 fsl_lsch3_early_init_f();
Yuantian Tangd46f65e2020-03-19 16:48:23 +0800138
139#ifdef CONFIG_LPUART
140 /*
141 * Field| Function
142 * --------------------------------------------------------------
143 * 7-6 | Controls I2C3 routing (net CFG_MUX_I2C3):
144 * I2C3 | 11= Routes {SCL, SDA} to LPUART1 header as {SOUT, SIN}.
145 * --------------------------------------------------------------
146 * 5-4 | Controls I2C4 routing (net CFG_MUX_I2C4):
147 * I2C4 |11= Routes {SCL, SDA} to LPUART1 header as {CTS_B, RTS_B}.
148 */
149 /* use lpuart0 as system console */
150 uart = QIXIS_READ(brdcfg[13]);
151 uart &= ~CFG_LPUART_MUX_MASK;
152 uart |= CFG_LPUART_EN;
153 QIXIS_WRITE(brdcfg[13], uart);
154#endif
155
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800156 return 0;
157}
158
159void detail_board_ddr_info(void)
160{
161 puts("\nDDR ");
162 print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
163 print_ddr_info(0);
164}
165
Yinbo Zhu96cd3d42020-04-14 17:24:48 +0800166int esdhc_status_fixup(void *blob, const char *compat)
167{
168 void __iomem *dcfg_ccsr = (void __iomem *)DCFG_BASE;
169 char esdhc1_path[] = "/soc/mmc@2140000";
170 char esdhc2_path[] = "/soc/mmc@2150000";
171 char dspi1_path[] = "/soc/spi@2100000";
172 char dspi2_path[] = "/soc/spi@2110000";
173 u32 mux_sdhc1, mux_sdhc2;
174 u32 io = 0;
175
176 /*
177 * The PMUX IO-expander for mux select is used to control
178 * the muxing of various onboard interfaces.
179 */
180
181 io = in_le32(dcfg_ccsr + DCFG_RCWSR12);
182 mux_sdhc1 = (io >> DCFG_RCWSR12_SDHC_SHIFT) & DCFG_RCWSR12_SDHC_MASK;
183
184 /* Disable esdhc1/dspi1 if not selected. */
185 if (mux_sdhc1 != 0)
186 do_fixup_by_path(blob, esdhc1_path, "status", "disabled",
187 sizeof("disabled"), 1);
188 if (mux_sdhc1 != 2)
189 do_fixup_by_path(blob, dspi1_path, "status", "disabled",
190 sizeof("disabled"), 1);
191
192 io = in_le32(dcfg_ccsr + DCFG_RCWSR13);
193 mux_sdhc2 = (io >> DCFG_RCWSR13_SDHC_SHIFT) & DCFG_RCWSR13_SDHC_MASK;
194
195 /* Disable esdhc2/dspi2 if not selected. */
196 if (mux_sdhc2 != 0)
197 do_fixup_by_path(blob, esdhc2_path, "status", "disabled",
198 sizeof("disabled"), 1);
199 if (mux_sdhc2 != 2)
200 do_fixup_by_path(blob, dspi2_path, "status", "disabled",
201 sizeof("disabled"), 1);
202
203 return 0;
204}
205
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800206#ifdef CONFIG_OF_BOARD_SETUP
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900207int ft_board_setup(void *blob, struct bd_info *bd)
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800208{
209 u64 base[CONFIG_NR_DRAM_BANKS];
210 u64 size[CONFIG_NR_DRAM_BANKS];
211
212 ft_cpu_setup(blob, bd);
213
214 /* fixup DT for the two GPP DDR banks */
215 base[0] = gd->bd->bi_dram[0].start;
216 size[0] = gd->bd->bi_dram[0].size;
217 base[1] = gd->bd->bi_dram[1].start;
218 size[1] = gd->bd->bi_dram[1].size;
219
220#ifdef CONFIG_RESV_RAM
221 /* reduce size if reserved memory is within this bank */
222 if (gd->arch.resv_ram >= base[0] &&
223 gd->arch.resv_ram < base[0] + size[0])
224 size[0] = gd->arch.resv_ram - base[0];
225 else if (gd->arch.resv_ram >= base[1] &&
226 gd->arch.resv_ram < base[1] + size[1])
227 size[1] = gd->arch.resv_ram - base[1];
228#endif
229
230 fdt_fixup_memory_banks(blob, base, size, 2);
231
Laurentiu Tudor01dc5472019-07-30 17:29:59 +0300232 fdt_fixup_icid(blob);
233
Alex Marginean805b8592019-12-10 16:55:39 +0200234#ifdef CONFIG_FSL_ENETC
235 fdt_fixup_enetc_mac(blob);
236#endif
237
Yuantian Tang92f18ff2019-04-10 16:43:34 +0800238 return 0;
239}
240#endif
241
242#ifdef CONFIG_FSL_QIXIS
243int checkboard(void)
244{
245#ifdef CONFIG_TFABOOT
246 enum boot_src src = get_boot_src();
247#endif
248 u8 sw;
249
250 int clock;
251 char *board;
252 char buf[64] = {0};
253 static const char *freq[6] = {"100.00", "125.00", "156.25",
254 "161.13", "322.26", "100.00 SS"};
255
256 cpu_name(buf);
257 /* find the board details */
258 sw = QIXIS_READ(id);
259
260 switch (sw) {
261 case 0x46:
262 board = "QDS";
263 break;
264 case 0x47:
265 board = "RDB";
266 break;
267 case 0x49:
268 board = "HSSI";
269 break;
270 default:
271 board = "unknown";
272 break;
273 }
274
275 sw = QIXIS_READ(arch);
276 printf("Board: %s-%s, Version: %c, boot from ",
277 buf, board, (sw & 0xf) + 'A' - 1);
278
279 sw = QIXIS_READ(brdcfg[0]);
280 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
281
282#ifdef CONFIG_TFABOOT
283 if (src == BOOT_SOURCE_SD_MMC) {
284 puts("SD\n");
285 } else if (src == BOOT_SOURCE_SD_MMC2) {
286 puts("eMMC\n");
287 } else {
288#endif
289#ifdef CONFIG_SD_BOOT
290 puts("SD\n");
291#elif defined(CONFIG_EMMC_BOOT)
292 puts("eMMC\n");
293#else
294 switch (sw) {
295 case 0:
296 case 4:
297 printf("NOR\n");
298 break;
299 case 1:
300 printf("NAND\n");
301 break;
302 default:
303 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
304 break;
305 }
306#endif
307#ifdef CONFIG_TFABOOT
308 }
309#endif
310
311 printf("FPGA: v%d (%s)\n", QIXIS_READ(scver), board);
312 puts("SERDES1 Reference : ");
313
314 sw = QIXIS_READ(brdcfg[2]);
315#ifdef CONFIG_TARGET_LS1028ARDB
316 clock = (sw >> 6) & 3;
317#else
318 clock = (sw >> 4) & 0xf;
319#endif
320
321 printf("Clock1 = %sMHz ", freq[clock]);
322#ifdef CONFIG_TARGET_LS1028ARDB
323 clock = (sw >> 4) & 3;
324#else
325 clock = sw & 0xf;
326#endif
327 printf("Clock2 = %sMHz\n", freq[clock]);
328
329 return 0;
330}
331#endif
Alison Wangd57211b2022-05-10 18:29:10 +0800332
333void *video_hw_init(void)
334{
335 return NULL;
336}