1 /* 2 * Copyright 2011,2012 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <command.h> 9 #include <netdev.h> 10 #include <linux/compiler.h> 11 #include <asm/mmu.h> 12 #include <asm/processor.h> 13 #include <asm/cache.h> 14 #include <asm/immap_85xx.h> 15 #include <asm/fsl_law.h> 16 #include <asm/fsl_serdes.h> 17 #include <asm/fsl_portals.h> 18 #include <asm/fsl_liodn.h> 19 #include <fm_eth.h> 20 21 extern void pci_of_setup(void *blob, bd_t *bd); 22 23 #include "cpld.h" 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 int checkboard(void) 28 { 29 u8 sw; 30 struct cpu_type *cpu = gd->arch.cpu; 31 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; 32 unsigned int i; 33 34 printf("Board: %sRDB, ", cpu->name); 35 printf("CPLD version: %d.%d ", CPLD_READ(cpld_ver), 36 CPLD_READ(cpld_ver_sub)); 37 38 sw = CPLD_READ(fbank_sel); 39 printf("vBank: %d\n", sw & 0x1); 40 41 /* 42 * Display the RCW, so that no one gets confused as to what RCW 43 * we're actually using for this boot. 44 */ 45 puts("Reset Configuration Word (RCW):"); 46 for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { 47 u32 rcw = in_be32(&gur->rcwsr[i]); 48 49 if ((i % 4) == 0) 50 printf("\n %08x:", i * 4); 51 printf(" %08x", rcw); 52 } 53 puts("\n"); 54 55 /* 56 * Display the actual SERDES reference clocks as configured by the 57 * dip switches on the board. Note that the SWx registers could 58 * technically be set to force the reference clocks to match the 59 * values that the SERDES expects (or vice versa). For now, however, 60 * we just display both values and hope the user notices when they 61 * don't match. 62 */ 63 puts("SERDES Reference Clocks: "); 64 sw = in_8(&CPLD_SW(2)) >> 2; 65 for (i = 0; i < 2; i++) { 66 static const char * const freq[][3] = {{"0", "100", "125"}, 67 {"100", "156.25", "125"} 68 }; 69 unsigned int clock = (sw >> (2 * i)) & 3; 70 71 printf("Bank%u=%sMhz ", i+1, freq[i][clock]); 72 } 73 puts("\n"); 74 75 return 0; 76 } 77 78 int board_early_init_f(void) 79 { 80 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 81 82 /* board only uses the DDR_MCK0/1, so disable the DDR_MCK2/3 */ 83 setbits_be32(&gur->ddrclkdr, 0x000f000f); 84 85 return 0; 86 } 87 88 #define CPLD_LANE_A_SEL 0x1 89 #define CPLD_LANE_G_SEL 0x2 90 #define CPLD_LANE_C_SEL 0x4 91 #define CPLD_LANE_D_SEL 0x8 92 93 void board_config_lanes_mux(void) 94 { 95 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; 96 int srds_prtcl = (in_be32(&gur->rcwsr[4]) & 97 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; 98 99 u8 mux = 0; 100 switch (srds_prtcl) { 101 case 0x2: 102 case 0x5: 103 case 0x9: 104 case 0xa: 105 case 0xf: 106 break; 107 case 0x8: 108 mux |= CPLD_LANE_C_SEL | CPLD_LANE_D_SEL; 109 break; 110 case 0x14: 111 mux |= CPLD_LANE_A_SEL; 112 break; 113 case 0x17: 114 mux |= CPLD_LANE_G_SEL; 115 break; 116 case 0x16: 117 case 0x19: 118 case 0x1a: 119 mux |= CPLD_LANE_G_SEL | CPLD_LANE_C_SEL | CPLD_LANE_D_SEL; 120 break; 121 case 0x1c: 122 mux |= CPLD_LANE_G_SEL | CPLD_LANE_A_SEL; 123 break; 124 default: 125 printf("Fman:Unsupported SerDes Protocol 0x%02x\n", srds_prtcl); 126 break; 127 } 128 CPLD_WRITE(serdes_mux, mux); 129 } 130 131 int board_early_init_r(void) 132 { 133 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; 134 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); 135 136 /* 137 * Remap Boot flash + PROMJET region to caching-inhibited 138 * so that flash can be erased properly. 139 */ 140 141 /* Flush d-cache and invalidate i-cache of any FLASH data */ 142 flush_dcache(); 143 invalidate_icache(); 144 145 /* invalidate existing TLB entry for flash + promjet */ 146 disable_tlb(flash_esel); 147 148 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, 149 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 150 0, flash_esel, BOOKE_PAGESZ_256M, 1); 151 152 set_liodns(); 153 setup_portals(); 154 board_config_lanes_mux(); 155 156 return 0; 157 } 158 159 unsigned long get_board_sys_clk(unsigned long dummy) 160 { 161 u8 sysclk_conf = CPLD_READ(sysclk_sw1); 162 163 switch (sysclk_conf & 0x7) { 164 case CPLD_SYSCLK_83: 165 return 83333333; 166 case CPLD_SYSCLK_100: 167 return 100000000; 168 default: 169 return 66666666; 170 } 171 } 172 173 static const char *serdes_clock_to_string(u32 clock) 174 { 175 switch (clock) { 176 case SRDS_PLLCR0_RFCK_SEL_100: 177 return "100"; 178 case SRDS_PLLCR0_RFCK_SEL_125: 179 return "125"; 180 case SRDS_PLLCR0_RFCK_SEL_156_25: 181 return "156.25"; 182 default: 183 return "150"; 184 } 185 } 186 187 #define NUM_SRDS_BANKS 2 188 189 int misc_init_r(void) 190 { 191 serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; 192 u32 actual[NUM_SRDS_BANKS]; 193 unsigned int i; 194 u8 sw; 195 static const int freq[][3] = { 196 {0, SRDS_PLLCR0_RFCK_SEL_100, SRDS_PLLCR0_RFCK_SEL_125}, 197 {SRDS_PLLCR0_RFCK_SEL_100, SRDS_PLLCR0_RFCK_SEL_156_25, 198 SRDS_PLLCR0_RFCK_SEL_125} 199 }; 200 201 sw = in_8(&CPLD_SW(2)) >> 2; 202 for (i = 0; i < NUM_SRDS_BANKS; i++) { 203 unsigned int clock = (sw >> (2 * i)) & 3; 204 if (clock == 0x3) { 205 printf("Warning: SDREFCLK%u switch setting of '11' is " 206 "unsupported\n", i + 1); 207 break; 208 } 209 if (i == 0 && clock == 0) 210 puts("Warning: SDREFCLK1 switch setting of" 211 "'00' is unsupported\n"); 212 else 213 actual[i] = freq[i][clock]; 214 215 /* 216 * PC board uses a different CPLD with PB board, this CPLD 217 * has cpld_ver_sub = 1, and pcba_ver = 5. But CPLD on PB 218 * board has cpld_ver_sub = 0, and pcba_ver = 4. 219 */ 220 if ((i == 1) && (CPLD_READ(cpld_ver_sub) == 1) && 221 (CPLD_READ(pcba_ver) == 5)) { 222 /* PC board bank2 frequency */ 223 actual[i] = freq[i-1][clock]; 224 } 225 } 226 227 for (i = 0; i < NUM_SRDS_BANKS; i++) { 228 u32 expected = in_be32(®s->bank[i].pllcr0); 229 expected &= SRDS_PLLCR0_RFCK_SEL_MASK; 230 if (expected != actual[i]) { 231 printf("Warning: SERDES bank %u expects reference clock" 232 " %sMHz, but actual is %sMHz\n", i + 1, 233 serdes_clock_to_string(expected), 234 serdes_clock_to_string(actual[i])); 235 } 236 } 237 238 return 0; 239 } 240 241 void ft_board_setup(void *blob, bd_t *bd) 242 { 243 phys_addr_t base; 244 phys_size_t size; 245 246 ft_cpu_setup(blob, bd); 247 248 base = getenv_bootm_low(); 249 size = getenv_bootm_size(); 250 251 fdt_fixup_memory(blob, (u64)base, (u64)size); 252 253 #if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB) 254 fdt_fixup_dr_usb(blob, bd); 255 #endif 256 257 #ifdef CONFIG_PCI 258 pci_of_setup(blob, bd); 259 #endif 260 261 fdt_fixup_liodn(blob); 262 #ifdef CONFIG_SYS_DPAA_FMAN 263 fdt_fixup_fman_ethernet(blob); 264 #endif 265 } 266