1 /* 2 * Copyright 2015 Freescale Semiconductor 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 #include <common.h> 7 #include <malloc.h> 8 #include <errno.h> 9 #include <netdev.h> 10 #include <fsl_ifc.h> 11 #include <fsl_ddr.h> 12 #include <asm/io.h> 13 #include <fdt_support.h> 14 #include <linux/libfdt.h> 15 #include <fsl-mc/fsl_mc.h> 16 #include <environment.h> 17 #include <i2c.h> 18 #include <rtc.h> 19 #include <asm/arch/soc.h> 20 #include <hwconfig.h> 21 #include <fsl_sec.h> 22 #include <asm/arch/ppa.h> 23 24 25 #include "../common/qixis.h" 26 #include "ls2080aqds_qixis.h" 27 #include "../common/vid.h" 28 29 #define PIN_MUX_SEL_SDHC 0x00 30 #define PIN_MUX_SEL_DSPI 0x0a 31 #define SCFG_QSPICLKCTRL_DIV_20 (5 << 27) 32 33 #define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value) 34 35 DECLARE_GLOBAL_DATA_PTR; 36 37 enum { 38 MUX_TYPE_SDHC, 39 MUX_TYPE_DSPI, 40 }; 41 42 unsigned long long get_qixis_addr(void) 43 { 44 unsigned long long addr; 45 46 if (gd->flags & GD_FLG_RELOC) 47 addr = QIXIS_BASE_PHYS; 48 else 49 addr = QIXIS_BASE_PHYS_EARLY; 50 51 /* 52 * IFC address under 256MB is mapped to 0x30000000, any address above 53 * is mapped to 0x5_10000000 up to 4GB. 54 */ 55 addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000; 56 57 return addr; 58 } 59 60 int checkboard(void) 61 { 62 char buf[64]; 63 u8 sw; 64 static const char *const freq[] = {"100", "125", "156.25", 65 "100 separate SSCG"}; 66 int clock; 67 68 cpu_name(buf); 69 printf("Board: %s-QDS, ", buf); 70 71 sw = QIXIS_READ(arch); 72 printf("Board Arch: V%d, ", sw >> 4); 73 printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1); 74 75 memset((u8 *)buf, 0x00, ARRAY_SIZE(buf)); 76 77 sw = QIXIS_READ(brdcfg[0]); 78 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; 79 80 if (sw < 0x8) 81 printf("vBank: %d\n", sw); 82 else if (sw == 0x8) 83 puts("PromJet\n"); 84 else if (sw == 0x9) 85 puts("NAND\n"); 86 else if (sw == 0xf) 87 puts("QSPI\n"); 88 else if (sw == 0x15) 89 printf("IFCCard\n"); 90 else 91 printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH); 92 93 printf("FPGA: v%d (%s), build %d", 94 (int)QIXIS_READ(scver), qixis_read_tag(buf), 95 (int)qixis_read_minor()); 96 /* the timestamp string contains "\n" at the end */ 97 printf(" on %s", qixis_read_time(buf)); 98 99 /* 100 * Display the actual SERDES reference clocks as configured by the 101 * dip switches on the board. Note that the SWx registers could 102 * technically be set to force the reference clocks to match the 103 * values that the SERDES expects (or vice versa). For now, however, 104 * we just display both values and hope the user notices when they 105 * don't match. 106 */ 107 puts("SERDES1 Reference : "); 108 sw = QIXIS_READ(brdcfg[2]); 109 clock = (sw >> 6) & 3; 110 printf("Clock1 = %sMHz ", freq[clock]); 111 clock = (sw >> 4) & 3; 112 printf("Clock2 = %sMHz", freq[clock]); 113 114 puts("\nSERDES2 Reference : "); 115 clock = (sw >> 2) & 3; 116 printf("Clock1 = %sMHz ", freq[clock]); 117 clock = (sw >> 0) & 3; 118 printf("Clock2 = %sMHz\n", freq[clock]); 119 120 return 0; 121 } 122 123 unsigned 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 return 66666666; 144 } 145 146 unsigned long get_board_ddr_clk(void) 147 { 148 u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); 149 150 switch ((ddrclk_conf & 0x30) >> 4) { 151 case QIXIS_DDRCLK_100: 152 return 100000000; 153 case QIXIS_DDRCLK_125: 154 return 125000000; 155 case QIXIS_DDRCLK_133: 156 return 133333333; 157 } 158 return 66666666; 159 } 160 161 int select_i2c_ch_pca9547(u8 ch) 162 { 163 int ret; 164 165 ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); 166 if (ret) { 167 puts("PCA: failed to select proper channel\n"); 168 return ret; 169 } 170 171 return 0; 172 } 173 174 int config_board_mux(int ctrl_type) 175 { 176 u8 reg5; 177 178 reg5 = QIXIS_READ(brdcfg[5]); 179 180 switch (ctrl_type) { 181 case MUX_TYPE_SDHC: 182 reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC); 183 break; 184 case MUX_TYPE_DSPI: 185 reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI); 186 break; 187 default: 188 printf("Wrong mux interface type\n"); 189 return -1; 190 } 191 192 QIXIS_WRITE(brdcfg[5], reg5); 193 194 return 0; 195 } 196 197 int board_init(void) 198 { 199 char *env_hwconfig; 200 u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE; 201 u32 val; 202 203 init_final_memctl_regs(); 204 205 val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4); 206 207 env_hwconfig = env_get("hwconfig"); 208 209 if (hwconfig_f("dspi", env_hwconfig) && 210 DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8))) 211 config_board_mux(MUX_TYPE_DSPI); 212 else 213 config_board_mux(MUX_TYPE_SDHC); 214 215 #if defined(CONFIG_NAND) && defined(CONFIG_FSL_QSPI) 216 val = in_le32(dcfg_ccsr + DCFG_RCWSR15 / 4); 217 218 if (DCFG_RCWSR15_IFCGRPABASE_QSPI == (val & (u32)0x3)) 219 QIXIS_WRITE(brdcfg[9], 220 (QIXIS_READ(brdcfg[9]) & 0xf8) | 221 FSL_QIXIS_BRDCFG9_QSPI); 222 #endif 223 224 #ifdef CONFIG_ENV_IS_NOWHERE 225 gd->env_addr = (ulong)&default_environment[0]; 226 #endif 227 select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); 228 rtc_enable_32khz_output(); 229 #ifdef CONFIG_FSL_CAAM 230 sec_init(); 231 #endif 232 233 #ifdef CONFIG_FSL_LS_PPA 234 ppa_init(); 235 #endif 236 237 return 0; 238 } 239 240 int board_early_init_f(void) 241 { 242 #ifdef CONFIG_SYS_I2C_EARLY_INIT 243 i2c_early_init_f(); 244 #endif 245 fsl_lsch3_early_init_f(); 246 #ifdef CONFIG_FSL_QSPI 247 /* input clk: 1/2 platform clk, output: input/20 */ 248 out_le32(SCFG_BASE + SCFG_QSPICLKCTLR, SCFG_QSPICLKCTRL_DIV_20); 249 #endif 250 return 0; 251 } 252 253 int misc_init_r(void) 254 { 255 if (adjust_vdd(0)) 256 printf("Warning: Adjusting core voltage failed.\n"); 257 258 return 0; 259 } 260 261 void detail_board_ddr_info(void) 262 { 263 puts("\nDDR "); 264 print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, ""); 265 print_ddr_info(0); 266 #ifdef CONFIG_SYS_FSL_HAS_DP_DDR 267 if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) { 268 puts("\nDP-DDR "); 269 print_size(gd->bd->bi_dram[2].size, ""); 270 print_ddr_info(CONFIG_DP_DDR_CTRL); 271 } 272 #endif 273 } 274 275 #if defined(CONFIG_ARCH_MISC_INIT) 276 int arch_misc_init(void) 277 { 278 return 0; 279 } 280 #endif 281 282 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 283 void fdt_fixup_board_enet(void *fdt) 284 { 285 int offset; 286 287 offset = fdt_path_offset(fdt, "/soc/fsl-mc"); 288 289 if (offset < 0) 290 offset = fdt_path_offset(fdt, "/fsl-mc"); 291 292 if (offset < 0) { 293 printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", 294 __func__, offset); 295 return; 296 } 297 298 if ((get_mc_boot_status() == 0) && (get_dpl_apply_status() == 0)) 299 fdt_status_okay(fdt, offset); 300 else 301 fdt_status_fail(fdt, offset); 302 } 303 304 void board_quiesce_devices(void) 305 { 306 fsl_mc_ldpaa_exit(gd->bd); 307 } 308 #endif 309 310 #ifdef CONFIG_OF_BOARD_SETUP 311 int ft_board_setup(void *blob, bd_t *bd) 312 { 313 u64 base[CONFIG_NR_DRAM_BANKS]; 314 u64 size[CONFIG_NR_DRAM_BANKS]; 315 316 ft_cpu_setup(blob, bd); 317 318 /* fixup DT for the two GPP DDR banks */ 319 base[0] = gd->bd->bi_dram[0].start; 320 size[0] = gd->bd->bi_dram[0].size; 321 base[1] = gd->bd->bi_dram[1].start; 322 size[1] = gd->bd->bi_dram[1].size; 323 324 #ifdef CONFIG_RESV_RAM 325 /* reduce size if reserved memory is within this bank */ 326 if (gd->arch.resv_ram >= base[0] && 327 gd->arch.resv_ram < base[0] + size[0]) 328 size[0] = gd->arch.resv_ram - base[0]; 329 else if (gd->arch.resv_ram >= base[1] && 330 gd->arch.resv_ram < base[1] + size[1]) 331 size[1] = gd->arch.resv_ram - base[1]; 332 #endif 333 334 fdt_fixup_memory_banks(blob, base, size, 2); 335 336 fsl_fdt_fixup_dr_usb(blob, bd); 337 338 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 339 fdt_fixup_board_enet(blob); 340 #endif 341 342 return 0; 343 } 344 #endif 345 346 void qixis_dump_switch(void) 347 { 348 int i, nr_of_cfgsw; 349 350 QIXIS_WRITE(cms[0], 0x00); 351 nr_of_cfgsw = QIXIS_READ(cms[1]); 352 353 puts("DIP switch settings dump:\n"); 354 for (i = 1; i <= nr_of_cfgsw; i++) { 355 QIXIS_WRITE(cms[0], i); 356 printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1])); 357 } 358 } 359