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 <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 230 #ifdef CONFIG_FSL_LS_PPA 231 ppa_init(); 232 #endif 233 234 #ifdef CONFIG_FSL_CAAM 235 sec_init(); 236 #endif 237 238 return 0; 239 } 240 241 int board_early_init_f(void) 242 { 243 #ifdef CONFIG_SYS_I2C_EARLY_INIT 244 i2c_early_init_f(); 245 #endif 246 fsl_lsch3_early_init_f(); 247 #ifdef CONFIG_FSL_QSPI 248 /* input clk: 1/2 platform clk, output: input/20 */ 249 out_le32(SCFG_BASE + SCFG_QSPICLKCTLR, SCFG_QSPICLKCTRL_DIV_20); 250 #endif 251 return 0; 252 } 253 254 int misc_init_r(void) 255 { 256 if (adjust_vdd(0)) 257 printf("Warning: Adjusting core voltage failed.\n"); 258 259 return 0; 260 } 261 262 void detail_board_ddr_info(void) 263 { 264 puts("\nDDR "); 265 print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, ""); 266 print_ddr_info(0); 267 #ifdef CONFIG_SYS_FSL_HAS_DP_DDR 268 if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) { 269 puts("\nDP-DDR "); 270 print_size(gd->bd->bi_dram[2].size, ""); 271 print_ddr_info(CONFIG_DP_DDR_CTRL); 272 } 273 #endif 274 } 275 276 #if defined(CONFIG_ARCH_MISC_INIT) 277 int arch_misc_init(void) 278 { 279 return 0; 280 } 281 #endif 282 283 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 284 void fdt_fixup_board_enet(void *fdt) 285 { 286 int offset; 287 288 offset = fdt_path_offset(fdt, "/soc/fsl-mc"); 289 290 if (offset < 0) 291 offset = fdt_path_offset(fdt, "/fsl-mc"); 292 293 if (offset < 0) { 294 printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", 295 __func__, offset); 296 return; 297 } 298 299 if (get_mc_boot_status() == 0) 300 fdt_status_okay(fdt, offset); 301 else 302 fdt_status_fail(fdt, offset); 303 } 304 305 void board_quiesce_devices(void) 306 { 307 fsl_mc_ldpaa_exit(gd->bd); 308 } 309 #endif 310 311 #ifdef CONFIG_OF_BOARD_SETUP 312 int ft_board_setup(void *blob, bd_t *bd) 313 { 314 u64 base[CONFIG_NR_DRAM_BANKS]; 315 u64 size[CONFIG_NR_DRAM_BANKS]; 316 317 ft_cpu_setup(blob, bd); 318 319 /* fixup DT for the two GPP DDR banks */ 320 base[0] = gd->bd->bi_dram[0].start; 321 size[0] = gd->bd->bi_dram[0].size; 322 base[1] = gd->bd->bi_dram[1].start; 323 size[1] = gd->bd->bi_dram[1].size; 324 325 #ifdef CONFIG_RESV_RAM 326 /* reduce size if reserved memory is within this bank */ 327 if (gd->arch.resv_ram >= base[0] && 328 gd->arch.resv_ram < base[0] + size[0]) 329 size[0] = gd->arch.resv_ram - base[0]; 330 else if (gd->arch.resv_ram >= base[1] && 331 gd->arch.resv_ram < base[1] + size[1]) 332 size[1] = gd->arch.resv_ram - base[1]; 333 #endif 334 335 fdt_fixup_memory_banks(blob, base, size, 2); 336 337 fsl_fdt_fixup_dr_usb(blob, bd); 338 339 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD) 340 fdt_fixup_board_enet(blob); 341 #endif 342 343 return 0; 344 } 345 #endif 346 347 void qixis_dump_switch(void) 348 { 349 int i, nr_of_cfgsw; 350 351 QIXIS_WRITE(cms[0], 0x00); 352 nr_of_cfgsw = QIXIS_READ(cms[1]); 353 354 puts("DIP switch settings dump:\n"); 355 for (i = 1; i <= nr_of_cfgsw; i++) { 356 QIXIS_WRITE(cms[0], i); 357 printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1])); 358 } 359 } 360