blob: a0de4becd1a33cbfec318bf65d6eccca7ceb8a75 [file] [log] [blame]
Scott Woodf64c98c2015-03-20 19:28:12 -07001/*
Mingkai Hu0e58b512015-10-26 19:47:50 +08002 * Copyright 2014-2015 Freescale Semiconductor
Scott Woodf64c98c2015-03-20 19:28:12 -07003 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <fsl_ifc.h>
Mingkai Hu0e58b512015-10-26 19:47:50 +08009#include <asm/arch/soc.h>
Scott Woodae1df322015-03-20 19:28:13 -070010#include <asm/io.h>
Scott Wood8e728cd2015-03-24 13:25:02 -070011#include <asm/global_data.h>
Prabhakar Kushwaha22cfe962015-11-05 12:00:14 +053012#include <asm/arch-fsl-layerscape/config.h>
Scott Wood8e728cd2015-03-24 13:25:02 -070013
14DECLARE_GLOBAL_DATA_PTR;
Scott Woodae1df322015-03-20 19:28:13 -070015
Prabhakar Kushwaha77f7ded2015-11-09 16:42:20 +053016#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
Yao Yuanfae88052015-12-05 14:59:14 +080017/*
18 * This erratum requires setting a value to eddrtqcr1 to
19 * optimal the DDR performance.
20 */
21static void erratum_a008336(void)
22{
23 u32 *eddrtqcr1;
24
25#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
26#ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR
27 eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
28 out_le32(eddrtqcr1, 0x63b30002);
29#endif
30#ifdef CONFIG_SYS_FSL_DCSR_DDR2_ADDR
31 eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
32 out_le32(eddrtqcr1, 0x63b30002);
33#endif
34#endif
35}
36
37/*
38 * This erratum requires a register write before being Memory
39 * controller 3 being enabled.
40 */
41static void erratum_a008514(void)
42{
43 u32 *eddrtqcr1;
44
45#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
46#ifdef CONFIG_SYS_FSL_DCSR_DDR3_ADDR
47 eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
48 out_le32(eddrtqcr1, 0x63b20002);
49#endif
50#endif
51}
Prabhakar Kushwaha22cfe962015-11-05 12:00:14 +053052#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
53#define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val"
54
55static unsigned long get_internval_val_mhz(void)
56{
57 char *interval = getenv(PLATFORM_CYCLE_ENV_VAR);
58 /*
59 * interval is the number of platform cycles(MHz) between
60 * wake up events generated by EPU.
61 */
62 ulong interval_mhz = get_bus_freq(0) / (1000 * 1000);
63
64 if (interval)
65 interval_mhz = simple_strtoul(interval, NULL, 10);
66
67 return interval_mhz;
68}
69
70void erratum_a009635(void)
71{
72 u32 val;
73 unsigned long interval_mhz = get_internval_val_mhz();
74
75 if (!interval_mhz)
76 return;
77
78 val = in_le32(DCSR_CGACRE5);
79 writel(val | 0x00000200, DCSR_CGACRE5);
80
81 val = in_le32(EPU_EPCMPR5);
82 writel(interval_mhz, EPU_EPCMPR5);
83 val = in_le32(EPU_EPCCR5);
84 writel(val | 0x82820000, EPU_EPCCR5);
85 val = in_le32(EPU_EPSMCR5);
86 writel(val | 0x002f0000, EPU_EPSMCR5);
87 val = in_le32(EPU_EPECR5);
88 writel(val | 0x20000000, EPU_EPECR5);
89 val = in_le32(EPU_EPGCR);
90 writel(val | 0x80000000, EPU_EPGCR);
91}
92#endif /* CONFIG_SYS_FSL_ERRATUM_A009635 */
93
Scott Woodae1df322015-03-20 19:28:13 -070094static void erratum_a008751(void)
95{
96#ifdef CONFIG_SYS_FSL_ERRATUM_A008751
97 u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
98
99 writel(0x27672b2a, scfg + SCFG_USB3PRM1CR / 4);
100#endif
101}
Scott Woodf64c98c2015-03-20 19:28:12 -0700102
Scott Wood8e728cd2015-03-24 13:25:02 -0700103static void erratum_rcw_src(void)
104{
105#if defined(CONFIG_SPL)
106 u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
107 u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
108 u32 val;
109
110 val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
111 val &= ~DCFG_PORSR1_RCW_SRC;
112 val |= DCFG_PORSR1_RCW_SRC_NOR;
113 out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val);
114#endif
115}
116
York Sun0404a392015-03-23 10:41:35 -0700117#define I2C_DEBUG_REG 0x6
118#define I2C_GLITCH_EN 0x8
119/*
120 * This erratum requires setting glitch_en bit to enable
121 * digital glitch filter to improve clock stability.
122 */
123static void erratum_a009203(void)
124{
125 u8 __iomem *ptr;
126#ifdef CONFIG_SYS_I2C
127#ifdef I2C1_BASE_ADDR
128 ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
129
130 writeb(I2C_GLITCH_EN, ptr);
131#endif
132#ifdef I2C2_BASE_ADDR
133 ptr = (u8 __iomem *)(I2C2_BASE_ADDR + I2C_DEBUG_REG);
134
135 writeb(I2C_GLITCH_EN, ptr);
136#endif
137#ifdef I2C3_BASE_ADDR
138 ptr = (u8 __iomem *)(I2C3_BASE_ADDR + I2C_DEBUG_REG);
139
140 writeb(I2C_GLITCH_EN, ptr);
141#endif
142#ifdef I2C4_BASE_ADDR
143 ptr = (u8 __iomem *)(I2C4_BASE_ADDR + I2C_DEBUG_REG);
144
145 writeb(I2C_GLITCH_EN, ptr);
146#endif
147#endif
148}
149
Scott Woodf64c98c2015-03-20 19:28:12 -0700150void fsl_lsch3_early_init_f(void)
151{
Scott Woodae1df322015-03-20 19:28:13 -0700152 erratum_a008751();
Scott Wood8e728cd2015-03-24 13:25:02 -0700153 erratum_rcw_src();
Scott Woodf64c98c2015-03-20 19:28:12 -0700154 init_early_memctl_regs(); /* tighten IFC timing */
York Sun0404a392015-03-23 10:41:35 -0700155 erratum_a009203();
Yao Yuanfae88052015-12-05 14:59:14 +0800156 erratum_a008514();
157 erratum_a008336();
Scott Woodf64c98c2015-03-20 19:28:12 -0700158}
Mingkai Hue4e93ea2015-10-26 19:47:51 +0800159
160#elif defined(CONFIG_LS1043A)
161void fsl_lsch2_early_init_f(void)
162{
163 struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
164
165#ifdef CONFIG_FSL_IFC
166 init_early_memctl_regs(); /* tighten IFC timing */
167#endif
168
169 /*
170 * Enable snoop requests and DVM message requests for
171 * Slave insterface S4 (A53 core cluster)
172 */
173 out_le32(&cci->slave[4].snoop_ctrl,
174 CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
175}
Mingkai Hu0e58b512015-10-26 19:47:50 +0800176#endif
Scott Wood8e728cd2015-03-24 13:25:02 -0700177
Mingkai Hu0e58b512015-10-26 19:47:50 +0800178#ifdef CONFIG_BOARD_LATE_INIT
179int board_late_init(void)
Scott Wood8e728cd2015-03-24 13:25:02 -0700180{
Mingkai Hu0e58b512015-10-26 19:47:50 +0800181 return 0;
Scott Wood8e728cd2015-03-24 13:25:02 -0700182}
183#endif