1 /* 2 * Copyright 2014-2015 Freescale Semiconductor 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <fsl_ifc.h> 9 #include <asm/arch/soc.h> 10 #include <asm/io.h> 11 #include <asm/global_data.h> 12 #include <asm/arch-fsl-layerscape/config.h> 13 14 DECLARE_GLOBAL_DATA_PTR; 15 16 #if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) 17 /* 18 * This erratum requires setting a value to eddrtqcr1 to 19 * optimal the DDR performance. 20 */ 21 static 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 */ 41 static 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 } 52 #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 53 #define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val" 54 55 static 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 70 void 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 94 static 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 } 102 103 static 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 117 #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 */ 123 static 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 150 void fsl_lsch3_early_init_f(void) 151 { 152 erratum_a008751(); 153 erratum_rcw_src(); 154 init_early_memctl_regs(); /* tighten IFC timing */ 155 erratum_a009203(); 156 erratum_a008514(); 157 erratum_a008336(); 158 } 159 160 #elif defined(CONFIG_LS1043A) 161 void fsl_lsch2_early_init_f(void) 162 { 163 struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; 164 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; 165 166 #ifdef CONFIG_FSL_IFC 167 init_early_memctl_regs(); /* tighten IFC timing */ 168 #endif 169 170 /* Make SEC reads and writes snoopable */ 171 setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | 172 SCFG_SNPCNFGCR_SECWRSNP); 173 174 /* 175 * Enable snoop requests and DVM message requests for 176 * Slave insterface S4 (A53 core cluster) 177 */ 178 out_le32(&cci->slave[4].snoop_ctrl, 179 CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); 180 } 181 #endif 182 183 #ifdef CONFIG_BOARD_LATE_INIT 184 int board_late_init(void) 185 { 186 return 0; 187 } 188 #endif 189