blob: d9d6e4fd962365420d4a3bb89ef9e2e629e47077 [file] [log] [blame]
Scott Woodb991b982015-03-20 19:28:12 -07001/*
Mingkai Hu9f3183d2015-10-26 19:47:50 +08002 * Copyright 2014-2015 Freescale Semiconductor
Scott Woodb991b982015-03-20 19:28:12 -07003 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
Ashish Kumar63b23162017-08-11 11:09:14 +05308#include <fsl_immap.h>
Scott Woodb991b982015-03-20 19:28:12 -07009#include <fsl_ifc.h>
Tang Yuantian989c5f02015-12-09 15:32:18 +080010#include <ahci.h>
11#include <scsi.h>
Hou Zhiqiangb392a6d2016-08-02 19:03:27 +080012#include <asm/arch/fsl_serdes.h>
Mingkai Hu9f3183d2015-10-26 19:47:50 +080013#include <asm/arch/soc.h>
Scott Woodd746fef2015-03-20 19:28:13 -070014#include <asm/io.h>
Scott Woodb2d5ac52015-03-24 13:25:02 -070015#include <asm/global_data.h>
Prabhakar Kushwahab40173642015-11-05 12:00:14 +053016#include <asm/arch-fsl-layerscape/config.h>
Hou Zhiqiangb392a6d2016-08-02 19:03:27 +080017#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
Hou Zhiqiang341238f2016-08-02 19:03:23 +080018#include <fsl_csu.h>
Hou Zhiqiangb392a6d2016-08-02 19:03:27 +080019#endif
Prabhakar Kushwahab7f2bbf2016-06-03 18:41:31 +053020#ifdef CONFIG_SYS_FSL_DDR
Shengzhou Liu074596c2016-04-07 16:22:21 +080021#include <fsl_ddr_sdram.h>
22#include <fsl_ddr.h>
Prabhakar Kushwahab7f2bbf2016-06-03 18:41:31 +053023#endif
Aneesh Bansald0412882016-01-22 16:37:26 +053024#ifdef CONFIG_CHAIN_OF_TRUST
25#include <fsl_validate.h>
26#endif
Ashish Kumar6d9b82d2017-08-31 16:12:53 +053027#include <fsl_immap.h>
Scott Woodb2d5ac52015-03-24 13:25:02 -070028
29DECLARE_GLOBAL_DATA_PTR;
Scott Woodd746fef2015-03-20 19:28:13 -070030
York Sun3c1d2182016-04-04 11:41:26 -070031bool soc_has_dp_ddr(void)
32{
33 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
34 u32 svr = gur_in32(&gur->svr);
35
Priyanka Jain9ae836c2016-11-17 12:29:55 +053036 /* LS2085A, LS2088A, LS2048A has DP_DDR */
37 if ((SVR_SOC_VER(svr) == SVR_LS2085A) ||
38 (SVR_SOC_VER(svr) == SVR_LS2088A) ||
39 (SVR_SOC_VER(svr) == SVR_LS2048A))
York Sun3c1d2182016-04-04 11:41:26 -070040 return true;
41
42 return false;
43}
44
45bool soc_has_aiop(void)
46{
47 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
48 u32 svr = gur_in32(&gur->svr);
49
50 /* LS2085A has AIOP */
Prabhakar Kushwaha49cdce12016-06-24 13:48:13 +053051 if (SVR_SOC_VER(svr) == SVR_LS2085A)
York Sun3c1d2182016-04-04 11:41:26 -070052 return true;
53
54 return false;
55}
56
Ran Wang2ab15532017-09-04 18:46:48 +080057static inline void set_usb_txvreftune(u32 __iomem *scfg, u32 offset)
58{
59 scfg_clrsetbits32(scfg + offset / 4,
60 0xF << 6,
61 SCFG_USB_TXVREFTUNE << 6);
62}
63
64static void erratum_a009008(void)
65{
66#ifdef CONFIG_SYS_FSL_ERRATUM_A009008
67 u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
Ran Wang2a8a3532017-09-04 18:46:49 +080068
Ran Wang2ab15532017-09-04 18:46:48 +080069#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
70 set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB1);
71 set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB2);
72 set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB3);
73#elif defined(CONFIG_ARCH_LS2080A)
74 set_usb_txvreftune(scfg, SCFG_USB3PRM1CR);
75#endif
76#endif /* CONFIG_SYS_FSL_ERRATUM_A009008 */
77}
78
Ran Wang2a8a3532017-09-04 18:46:49 +080079static inline void set_usb_sqrxtune(u32 __iomem *scfg, u32 offset)
80{
81 scfg_clrbits32(scfg + offset / 4,
82 SCFG_USB_SQRXTUNE_MASK << 23);
83}
84
85static void erratum_a009798(void)
86{
87#ifdef CONFIG_SYS_FSL_ERRATUM_A009798
88 u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
89
90#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
91 set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB1);
92 set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB2);
93 set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB3);
94#elif defined(CONFIG_ARCH_LS2080A)
95 set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR);
96#endif
97#endif /* CONFIG_SYS_FSL_ERRATUM_A009798 */
98}
99
Shengzhou Liu40836e22016-11-11 18:11:05 +0800100#if defined(CONFIG_FSL_LSCH3)
Yao Yuan000f4e72015-12-05 14:59:14 +0800101/*
102 * This erratum requires setting a value to eddrtqcr1 to
103 * optimal the DDR performance.
104 */
105static void erratum_a008336(void)
106{
Shengzhou Liu40836e22016-11-11 18:11:05 +0800107#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
Yao Yuan000f4e72015-12-05 14:59:14 +0800108 u32 *eddrtqcr1;
109
Yao Yuan000f4e72015-12-05 14:59:14 +0800110#ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR
111 eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
Shengzhou Liu1a87c242016-08-26 18:30:38 +0800112 if (fsl_ddr_get_version(0) == 0x50200)
113 out_le32(eddrtqcr1, 0x63b30002);
Yao Yuan000f4e72015-12-05 14:59:14 +0800114#endif
115#ifdef CONFIG_SYS_FSL_DCSR_DDR2_ADDR
116 eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
Shengzhou Liu1a87c242016-08-26 18:30:38 +0800117 if (fsl_ddr_get_version(0) == 0x50200)
118 out_le32(eddrtqcr1, 0x63b30002);
Yao Yuan000f4e72015-12-05 14:59:14 +0800119#endif
120#endif
121}
122
123/*
124 * This erratum requires a register write before being Memory
125 * controller 3 being enabled.
126 */
127static void erratum_a008514(void)
128{
Shengzhou Liu40836e22016-11-11 18:11:05 +0800129#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
Yao Yuan000f4e72015-12-05 14:59:14 +0800130 u32 *eddrtqcr1;
131
Yao Yuan000f4e72015-12-05 14:59:14 +0800132#ifdef CONFIG_SYS_FSL_DCSR_DDR3_ADDR
133 eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
134 out_le32(eddrtqcr1, 0x63b20002);
135#endif
136#endif
137}
Prabhakar Kushwahab40173642015-11-05 12:00:14 +0530138#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
139#define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val"
140
141static unsigned long get_internval_val_mhz(void)
142{
Simon Glass00caae62017-08-03 12:22:12 -0600143 char *interval = env_get(PLATFORM_CYCLE_ENV_VAR);
Prabhakar Kushwahab40173642015-11-05 12:00:14 +0530144 /*
145 * interval is the number of platform cycles(MHz) between
146 * wake up events generated by EPU.
147 */
148 ulong interval_mhz = get_bus_freq(0) / (1000 * 1000);
149
150 if (interval)
151 interval_mhz = simple_strtoul(interval, NULL, 10);
152
153 return interval_mhz;
154}
155
156void erratum_a009635(void)
157{
158 u32 val;
159 unsigned long interval_mhz = get_internval_val_mhz();
160
161 if (!interval_mhz)
162 return;
163
164 val = in_le32(DCSR_CGACRE5);
165 writel(val | 0x00000200, DCSR_CGACRE5);
166
167 val = in_le32(EPU_EPCMPR5);
168 writel(interval_mhz, EPU_EPCMPR5);
169 val = in_le32(EPU_EPCCR5);
170 writel(val | 0x82820000, EPU_EPCCR5);
171 val = in_le32(EPU_EPSMCR5);
172 writel(val | 0x002f0000, EPU_EPSMCR5);
173 val = in_le32(EPU_EPECR5);
174 writel(val | 0x20000000, EPU_EPECR5);
175 val = in_le32(EPU_EPGCR);
176 writel(val | 0x80000000, EPU_EPGCR);
177}
178#endif /* CONFIG_SYS_FSL_ERRATUM_A009635 */
179
Scott Woodb2d5ac52015-03-24 13:25:02 -0700180static void erratum_rcw_src(void)
181{
Santan Kumarfaed6bd2017-05-05 15:42:28 +0530182#if defined(CONFIG_SPL) && defined(CONFIG_NAND_BOOT)
Scott Woodb2d5ac52015-03-24 13:25:02 -0700183 u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
184 u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
185 u32 val;
186
187 val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
188 val &= ~DCFG_PORSR1_RCW_SRC;
189 val |= DCFG_PORSR1_RCW_SRC_NOR;
190 out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val);
191#endif
192}
193
York Sunab10d732015-03-23 10:41:35 -0700194#define I2C_DEBUG_REG 0x6
195#define I2C_GLITCH_EN 0x8
196/*
197 * This erratum requires setting glitch_en bit to enable
198 * digital glitch filter to improve clock stability.
199 */
Ashish kumardd48f0b2017-02-23 16:03:57 +0530200#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
York Sunab10d732015-03-23 10:41:35 -0700201static void erratum_a009203(void)
202{
203 u8 __iomem *ptr;
204#ifdef CONFIG_SYS_I2C
205#ifdef I2C1_BASE_ADDR
206 ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
207
208 writeb(I2C_GLITCH_EN, ptr);
209#endif
210#ifdef I2C2_BASE_ADDR
211 ptr = (u8 __iomem *)(I2C2_BASE_ADDR + I2C_DEBUG_REG);
212
213 writeb(I2C_GLITCH_EN, ptr);
214#endif
215#ifdef I2C3_BASE_ADDR
216 ptr = (u8 __iomem *)(I2C3_BASE_ADDR + I2C_DEBUG_REG);
217
218 writeb(I2C_GLITCH_EN, ptr);
219#endif
220#ifdef I2C4_BASE_ADDR
221 ptr = (u8 __iomem *)(I2C4_BASE_ADDR + I2C_DEBUG_REG);
222
223 writeb(I2C_GLITCH_EN, ptr);
224#endif
225#endif
226}
Ashish kumardd48f0b2017-02-23 16:03:57 +0530227#endif
Shengzhou Liu40836e22016-11-11 18:11:05 +0800228
Saksham Jain4a97a0c2016-03-23 16:24:40 +0530229void bypass_smmu(void)
230{
231 u32 val;
232 val = (in_le32(SMMU_SCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
233 out_le32(SMMU_SCR0, val);
234 val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK);
235 out_le32(SMMU_NSCR0, val);
236}
Scott Woodb991b982015-03-20 19:28:12 -0700237void fsl_lsch3_early_init_f(void)
238{
Scott Woodb2d5ac52015-03-24 13:25:02 -0700239 erratum_rcw_src();
Scott Woodb991b982015-03-20 19:28:12 -0700240 init_early_memctl_regs(); /* tighten IFC timing */
Ashish kumardd48f0b2017-02-23 16:03:57 +0530241#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
York Sunab10d732015-03-23 10:41:35 -0700242 erratum_a009203();
Ashish kumardd48f0b2017-02-23 16:03:57 +0530243#endif
Yao Yuan000f4e72015-12-05 14:59:14 +0800244 erratum_a008514();
245 erratum_a008336();
Ran Wang2ab15532017-09-04 18:46:48 +0800246 erratum_a009008();
Ran Wang2a8a3532017-09-04 18:46:49 +0800247 erratum_a009798();
Saksham Jain4a97a0c2016-03-23 16:24:40 +0530248#ifdef CONFIG_CHAIN_OF_TRUST
249 /* In case of Secure Boot, the IBR configures the SMMU
250 * to allow only Secure transactions.
251 * SMMU must be reset in bypass mode.
252 * Set the ClientPD bit and Clear the USFCFG Bit
253 */
254 if (fsl_check_boot_mode_secure() == 1)
255 bypass_smmu();
256#endif
Scott Woodb991b982015-03-20 19:28:12 -0700257}
Mingkai Hu8281c582015-10-26 19:47:51 +0800258
Tang Yuantian989c5f02015-12-09 15:32:18 +0800259#ifdef CONFIG_SCSI_AHCI_PLAT
260int sata_init(void)
261{
262 struct ccsr_ahci __iomem *ccsr_ahci;
263
264 ccsr_ahci = (void *)CONFIG_SYS_SATA2;
265 out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
266 out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
Tang Yuantian435cca12016-12-01 17:06:58 +0800267 out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800268
269 ccsr_ahci = (void *)CONFIG_SYS_SATA1;
270 out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
271 out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
Tang Yuantian435cca12016-12-01 17:06:58 +0800272 out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800273
274 ahci_init((void __iomem *)CONFIG_SYS_SATA1);
Simon Glass8eab1a52017-06-14 21:28:41 -0600275 scsi_scan(false);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800276
277 return 0;
278}
279#endif
280
Prabhakar Kushwaha22a44d02016-06-03 18:41:27 +0530281#elif defined(CONFIG_FSL_LSCH2)
Tang Yuantian989c5f02015-12-09 15:32:18 +0800282#ifdef CONFIG_SCSI_AHCI_PLAT
283int sata_init(void)
284{
285 struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA;
286
Shaohui Xie1b2b4062016-09-07 17:56:12 +0800287 /* Disable SATA ECC */
288 out_le32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + 0x520, 0x80000000);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800289 out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800290 out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
Tang Yuantian4de6ce12016-08-08 15:07:20 +0800291 out_le32(&ccsr_ahci->axicc, AHCI_PORT_AXICC_CFG);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800292
293 ahci_init((void __iomem *)CONFIG_SYS_SATA);
Simon Glass8eab1a52017-06-14 21:28:41 -0600294 scsi_scan(false);
Tang Yuantian989c5f02015-12-09 15:32:18 +0800295
296 return 0;
297}
298#endif
299
Mingkai Hu0d6faf22015-12-07 16:58:54 +0800300static void erratum_a009929(void)
301{
302#ifdef CONFIG_SYS_FSL_ERRATUM_A009929
303 struct ccsr_gur *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
304 u32 __iomem *dcsr_cop_ccp = (void *)CONFIG_SYS_DCSR_COP_CCP_ADDR;
305 u32 rstrqmr1 = gur_in32(&gur->rstrqmr1);
306
307 rstrqmr1 |= 0x00000400;
308 gur_out32(&gur->rstrqmr1, rstrqmr1);
309 writel(0x01000000, dcsr_cop_ccp);
310#endif
311}
312
Mingkai Hubbc8e052016-02-02 11:28:03 +0800313/*
314 * This erratum requires setting a value to eddrtqcr1 to optimal
315 * the DDR performance. The eddrtqcr1 register is in SCFG space
316 * of LS1043A and the offset is 0x157_020c.
317 */
318#if defined(CONFIG_SYS_FSL_ERRATUM_A009660) \
319 && defined(CONFIG_SYS_FSL_ERRATUM_A008514)
320#error A009660 and A008514 can not be both enabled.
321#endif
322
323static void erratum_a009660(void)
324{
325#ifdef CONFIG_SYS_FSL_ERRATUM_A009660
326 u32 *eddrtqcr1 = (void *)CONFIG_SYS_FSL_SCFG_ADDR + 0x20c;
327 out_be32(eddrtqcr1, 0x63b20042);
328#endif
329}
330
Shengzhou Liu074596c2016-04-07 16:22:21 +0800331static void erratum_a008850_early(void)
332{
333#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
334 /* part 1 of 2 */
Ashish Kumar63b23162017-08-11 11:09:14 +0530335 struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
336 CONFIG_SYS_CCI400_OFFSET);
Shengzhou Liu074596c2016-04-07 16:22:21 +0800337 struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
338
York Sun399e2bb2017-05-15 08:51:59 -0700339 /* Skip if running at lower exception level */
340 if (current_el() < 3)
341 return;
342
Shengzhou Liu074596c2016-04-07 16:22:21 +0800343 /* disables propagation of barrier transactions to DDRC from CCI400 */
344 out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
345
346 /* disable the re-ordering in DDRC */
347 ddr_out32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
348#endif
349}
350
351void erratum_a008850_post(void)
352{
353#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
354 /* part 2 of 2 */
Ashish Kumar63b23162017-08-11 11:09:14 +0530355 struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
356 CONFIG_SYS_CCI400_OFFSET);
Shengzhou Liu074596c2016-04-07 16:22:21 +0800357 struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
358 u32 tmp;
359
York Sun399e2bb2017-05-15 08:51:59 -0700360 /* Skip if running at lower exception level */
361 if (current_el() < 3)
362 return;
363
Shengzhou Liu074596c2016-04-07 16:22:21 +0800364 /* enable propagation of barrier transactions to DDRC from CCI400 */
365 out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
366
367 /* enable the re-ordering in DDRC */
368 tmp = ddr_in32(&ddr->eor);
369 tmp &= ~(DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
370 ddr_out32(&ddr->eor, tmp);
371#endif
372}
373
Hou Zhiqiangb392a6d2016-08-02 19:03:27 +0800374#ifdef CONFIG_SYS_FSL_ERRATUM_A010315
375void erratum_a010315(void)
376{
377 int i;
378
379 for (i = PCIE1; i <= PCIE4; i++)
380 if (!is_serdes_configured(i)) {
381 debug("PCIe%d: disabled all R/W permission!\n", i);
382 set_pcie_ns_access(i, 0);
383 }
384}
385#endif
386
Hou Zhiqiang0ea36712016-09-29 12:42:44 +0800387static void erratum_a010539(void)
388{
389#if defined(CONFIG_SYS_FSL_ERRATUM_A010539) && defined(CONFIG_QSPI_BOOT)
390 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
391 u32 porsr1;
392
393 porsr1 = in_be32(&gur->porsr1);
394 porsr1 &= ~FSL_CHASSIS2_CCSR_PORSR1_RCW_MASK;
395 out_be32((void *)(CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_PORCR1),
396 porsr1);
397#endif
398}
399
Hou Zhiqiang031acdb2016-12-09 16:09:00 +0800400/* Get VDD in the unit mV from voltage ID */
401int get_core_volt_from_fuse(void)
402{
403 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
404 int vdd;
405 u32 fusesr;
406 u8 vid;
407
408 fusesr = in_be32(&gur->dcfg_fusesr);
409 debug("%s: fusesr = 0x%x\n", __func__, fusesr);
410 vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
411 FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
412 if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
413 vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
414 FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
415 }
416 debug("%s: VID = 0x%x\n", __func__, vid);
417 switch (vid) {
418 case 0x00: /* VID isn't supported */
419 vdd = -EINVAL;
420 debug("%s: The VID feature is not supported\n", __func__);
421 break;
422 case 0x08: /* 0.9V silicon */
423 vdd = 900;
424 break;
425 case 0x10: /* 1.0V silicon */
426 vdd = 1000;
427 break;
428 default: /* Other core voltage */
429 vdd = -EINVAL;
430 printf("%s: The VID(%x) isn't supported\n", __func__, vid);
431 break;
432 }
433 debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
434
435 return vdd;
436}
437
438__weak int board_switch_core_volt(u32 vdd)
439{
440 return 0;
441}
442
443static int setup_core_volt(u32 vdd)
444{
445 return board_setup_core_volt(vdd);
446}
447
448#ifdef CONFIG_SYS_FSL_DDR
449static void ddr_enable_0v9_volt(bool en)
450{
451 struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
452 u32 tmp;
453
454 tmp = ddr_in32(&ddr->ddr_cdr1);
455
456 if (en)
457 tmp |= DDR_CDR1_V0PT9_EN;
458 else
459 tmp &= ~DDR_CDR1_V0PT9_EN;
460
461 ddr_out32(&ddr->ddr_cdr1, tmp);
462}
463#endif
464
465int setup_chip_volt(void)
466{
467 int vdd;
468
469 vdd = get_core_volt_from_fuse();
470 /* Nothing to do for silicons doesn't support VID */
471 if (vdd < 0)
472 return vdd;
473
474 if (setup_core_volt(vdd))
475 printf("%s: Switch core VDD to %dmV failed\n", __func__, vdd);
476#ifdef CONFIG_SYS_HAS_SERDES
477 if (setup_serdes_volt(vdd))
478 printf("%s: Switch SVDD to %dmV failed\n", __func__, vdd);
479#endif
480
481#ifdef CONFIG_SYS_FSL_DDR
482 if (vdd == 900)
483 ddr_enable_0v9_volt(true);
484#endif
485
486 return 0;
487}
488
Mingkai Hu8281c582015-10-26 19:47:51 +0800489void fsl_lsch2_early_init_f(void)
490{
Ashish Kumar63b23162017-08-11 11:09:14 +0530491 struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
492 CONFIG_SYS_CCI400_OFFSET);
Aneesh Bansal70f959c2015-12-08 13:54:27 +0530493 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
Mingkai Hu8281c582015-10-26 19:47:51 +0800494
Hou Zhiqiang341238f2016-08-02 19:03:23 +0800495#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
496 enable_layerscape_ns_access();
497#endif
498
Mingkai Hu8281c582015-10-26 19:47:51 +0800499#ifdef CONFIG_FSL_IFC
500 init_early_memctl_regs(); /* tighten IFC timing */
501#endif
502
Qianyu Gong258b8c92016-03-16 18:01:52 +0800503#if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT)
Gong Qianyu166ef1e2016-01-25 15:16:06 +0800504 out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
505#endif
Aneesh Bansal70f959c2015-12-08 13:54:27 +0530506 /* Make SEC reads and writes snoopable */
507 setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
Tang Yuantian4de6ce12016-08-08 15:07:20 +0800508 SCFG_SNPCNFGCR_SECWRSNP |
509 SCFG_SNPCNFGCR_SATARDSNP |
510 SCFG_SNPCNFGCR_SATAWRSNP);
Aneesh Bansal70f959c2015-12-08 13:54:27 +0530511
Mingkai Hu8281c582015-10-26 19:47:51 +0800512 /*
513 * Enable snoop requests and DVM message requests for
514 * Slave insterface S4 (A53 core cluster)
515 */
York Sun399e2bb2017-05-15 08:51:59 -0700516 if (current_el() == 3) {
517 out_le32(&cci->slave[4].snoop_ctrl,
518 CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
519 }
Mingkai Hu0d6faf22015-12-07 16:58:54 +0800520
521 /* Erratum */
Shengzhou Liu074596c2016-04-07 16:22:21 +0800522 erratum_a008850_early(); /* part 1 of 2 */
Mingkai Hu0d6faf22015-12-07 16:58:54 +0800523 erratum_a009929();
Mingkai Hubbc8e052016-02-02 11:28:03 +0800524 erratum_a009660();
Hou Zhiqiang0ea36712016-09-29 12:42:44 +0800525 erratum_a010539();
Ran Wang2ab15532017-09-04 18:46:48 +0800526 erratum_a009008();
Ran Wang2a8a3532017-09-04 18:46:49 +0800527 erratum_a009798();
Mingkai Hu8281c582015-10-26 19:47:51 +0800528}
Mingkai Hu9f3183d2015-10-26 19:47:50 +0800529#endif
Scott Woodb2d5ac52015-03-24 13:25:02 -0700530
Yuan Yaodd2ad2f2016-12-01 10:13:52 +0800531#ifdef CONFIG_QSPI_AHB_INIT
532/* Enable 4bytes address support and fast read */
533int qspi_ahb_init(void)
534{
535 u32 *qspi_lut, lut_key, *qspi_key;
536
537 qspi_key = (void *)SYS_FSL_QSPI_ADDR + 0x300;
538 qspi_lut = (void *)SYS_FSL_QSPI_ADDR + 0x310;
539
540 lut_key = in_be32(qspi_key);
541
542 if (lut_key == 0x5af05af0) {
543 /* That means the register is BE */
544 out_be32(qspi_key, 0x5af05af0);
545 /* Unlock the lut table */
546 out_be32(qspi_key + 1, 0x00000002);
547 out_be32(qspi_lut, 0x0820040c);
548 out_be32(qspi_lut + 1, 0x1c080c08);
549 out_be32(qspi_lut + 2, 0x00002400);
550 /* Lock the lut table */
551 out_be32(qspi_key, 0x5af05af0);
552 out_be32(qspi_key + 1, 0x00000001);
553 } else {
554 /* That means the register is LE */
555 out_le32(qspi_key, 0x5af05af0);
556 /* Unlock the lut table */
557 out_le32(qspi_key + 1, 0x00000002);
558 out_le32(qspi_lut, 0x0820040c);
559 out_le32(qspi_lut + 1, 0x1c080c08);
560 out_le32(qspi_lut + 2, 0x00002400);
561 /* Lock the lut table */
562 out_le32(qspi_key, 0x5af05af0);
563 out_le32(qspi_key + 1, 0x00000001);
564 }
565
566 return 0;
567}
568#endif
569
Mingkai Hu9f3183d2015-10-26 19:47:50 +0800570#ifdef CONFIG_BOARD_LATE_INIT
571int board_late_init(void)
Scott Woodb2d5ac52015-03-24 13:25:02 -0700572{
Tang Yuantian989c5f02015-12-09 15:32:18 +0800573#ifdef CONFIG_SCSI_AHCI_PLAT
574 sata_init();
575#endif
Aneesh Bansald0412882016-01-22 16:37:26 +0530576#ifdef CONFIG_CHAIN_OF_TRUST
577 fsl_setenv_chain_of_trust();
578#endif
Yuan Yaodd2ad2f2016-12-01 10:13:52 +0800579#ifdef CONFIG_QSPI_AHB_INIT
580 qspi_ahb_init();
581#endif
Tang Yuantian989c5f02015-12-09 15:32:18 +0800582
Mingkai Hu9f3183d2015-10-26 19:47:50 +0800583 return 0;
Scott Woodb2d5ac52015-03-24 13:25:02 -0700584}
585#endif