1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2009-2011 Freescale Semiconductor, Inc. 4 */ 5 6 #include <common.h> 7 #include <command.h> 8 #include <netdev.h> 9 #include <linux/compiler.h> 10 #include <asm/mmu.h> 11 #include <asm/processor.h> 12 #include <asm/cache.h> 13 #include <asm/immap_85xx.h> 14 #include <asm/fsl_law.h> 15 #include <asm/fsl_serdes.h> 16 #include <asm/fsl_liodn.h> 17 #include <fm_eth.h> 18 19 #include "../common/ngpixis.h" 20 #include "corenet_ds.h" 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 int checkboard (void) 25 { 26 u8 sw; 27 struct cpu_type *cpu = gd->arch.cpu; 28 #if defined(CONFIG_TARGET_P3041DS) || defined(CONFIG_TARGET_P5020DS) || \ 29 defined(CONFIG_TARGET_P5040DS) 30 unsigned int i; 31 #endif 32 static const char * const freq[] = {"100", "125", "156.25", "212.5" }; 33 34 printf("Board: %sDS, ", cpu->name); 35 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", 36 in_8(&pixis->id), in_8(&pixis->arch), in_8(&pixis->scver)); 37 38 sw = in_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH)); 39 sw = (sw & PIXIS_LBMAP_MASK) >> PIXIS_LBMAP_SHIFT; 40 41 if (sw < 0x8) 42 printf("vBank: %d\n", sw); 43 else if (sw == 0x8) 44 puts("Promjet\n"); 45 else if (sw == 0x9) 46 puts("NAND\n"); 47 else 48 printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH); 49 50 /* Display the actual SERDES reference clocks as configured by the 51 * dip switches on the board. Note that the SWx registers could 52 * technically be set to force the reference clocks to match the 53 * values that the SERDES expects (or vice versa). For now, however, 54 * we just display both values and hope the user notices when they 55 * don't match. 56 */ 57 puts("SERDES Reference Clocks: "); 58 #if defined(CONFIG_TARGET_P3041DS) || defined(CONFIG_TARGET_P5020DS) || \ 59 defined(CONFIG_TARGET_P5040DS) 60 sw = in_8(&PIXIS_SW(5)); 61 for (i = 0; i < 3; i++) { 62 unsigned int clock = (sw >> (6 - (2 * i))) & 3; 63 64 printf("Bank%u=%sMhz ", i+1, freq[clock]); 65 } 66 #ifdef CONFIG_TARGET_P5040DS 67 /* On P5040DS, SW11[7:8] determines the Bank 4 frequency */ 68 sw = in_8(&PIXIS_SW(9)); 69 printf("Bank4=%sMhz ", freq[sw & 3]); 70 #endif 71 puts("\n"); 72 #else 73 sw = in_8(&PIXIS_SW(3)); 74 /* SW3[2]: 0 = 100 Mhz, 1 = 125 MHz */ 75 /* SW3[3]: 0 = 125 Mhz, 1 = 156.25 MHz */ 76 /* SW3[4]: 0 = 125 Mhz, 1 = 156.25 MHz */ 77 printf("Bank1=%sMHz ", freq[!!(sw & 0x40)]); 78 printf("Bank2=%sMHz ", freq[1 + !!(sw & 0x20)]); 79 printf("Bank3=%sMHz\n", freq[1 + !!(sw & 0x10)]); 80 #endif 81 82 return 0; 83 } 84 85 int board_early_init_f(void) 86 { 87 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 88 89 /* 90 * P4080 DS board only uses the DDR1_MCK0/3 and DDR2_MCK0/3 91 * disable the DDR1_MCK1/2/4/5 and DDR2_MCK1/2/4/5 to reduce 92 * the noise introduced by these unterminated and unused clock pairs. 93 */ 94 setbits_be32(&gur->ddrclkdr, 0x001B001B); 95 96 return 0; 97 } 98 99 int board_early_init_r(void) 100 { 101 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; 102 int flash_esel = find_tlb_idx((void *)flashbase, 1); 103 104 /* 105 * Remap Boot flash + PROMJET region to caching-inhibited 106 * so that flash can be erased properly. 107 */ 108 109 /* Flush d-cache and invalidate i-cache of any FLASH data */ 110 flush_dcache(); 111 invalidate_icache(); 112 113 if (flash_esel == -1) { 114 /* very unlikely unless something is messed up */ 115 puts("Error: Could not find TLB for FLASH BASE\n"); 116 flash_esel = 2; /* give our best effort to continue */ 117 } else { 118 /* invalidate existing TLB entry for flash + promjet */ 119 disable_tlb(flash_esel); 120 } 121 122 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, /* tlb, epn, rpn */ 123 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, /* perms, wimge */ 124 0, flash_esel, BOOKE_PAGESZ_256M, 1); /* ts, esel, tsize, iprot */ 125 126 return 0; 127 } 128 129 #define NUM_SRDS_BANKS 3 130 131 int misc_init_r(void) 132 { 133 serdes_corenet_t *srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; 134 u32 actual[NUM_SRDS_BANKS]; 135 unsigned int i; 136 u8 sw; 137 138 #if defined(CONFIG_TARGET_P3041DS) || defined(CONFIG_TARGET_P5020DS) || \ 139 defined(CONFIG_TARGET_P5040DS) 140 sw = in_8(&PIXIS_SW(5)); 141 for (i = 0; i < 3; i++) { 142 unsigned int clock = (sw >> (6 - (2 * i))) & 3; 143 switch (clock) { 144 case 0: 145 actual[i] = SRDS_PLLCR0_RFCK_SEL_100; 146 break; 147 case 1: 148 actual[i] = SRDS_PLLCR0_RFCK_SEL_125; 149 break; 150 case 2: 151 actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25; 152 break; 153 default: 154 printf("Warning: SDREFCLK%u switch setting of '11' is " 155 "unsupported\n", i + 1); 156 break; 157 } 158 } 159 #else 160 /* Warn if the expected SERDES reference clocks don't match the 161 * actual reference clocks. This needs to be done after calling 162 * p4080_erratum_serdes8(), since that function may modify the clocks. 163 */ 164 sw = in_8(&PIXIS_SW(3)); 165 actual[0] = (sw & 0x40) ? 166 SRDS_PLLCR0_RFCK_SEL_125 : SRDS_PLLCR0_RFCK_SEL_100; 167 actual[1] = (sw & 0x20) ? 168 SRDS_PLLCR0_RFCK_SEL_156_25 : SRDS_PLLCR0_RFCK_SEL_125; 169 actual[2] = (sw & 0x10) ? 170 SRDS_PLLCR0_RFCK_SEL_156_25 : SRDS_PLLCR0_RFCK_SEL_125; 171 #endif 172 173 for (i = 0; i < NUM_SRDS_BANKS; i++) { 174 u32 expected = srds_regs->bank[i].pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK; 175 if (expected != actual[i]) { 176 printf("Warning: SERDES bank %u expects reference clock" 177 " %sMHz, but actual is %sMHz\n", i + 1, 178 serdes_clock_to_string(expected), 179 serdes_clock_to_string(actual[i])); 180 } 181 } 182 183 return 0; 184 } 185 186 int ft_board_setup(void *blob, bd_t *bd) 187 { 188 phys_addr_t base; 189 phys_size_t size; 190 191 ft_cpu_setup(blob, bd); 192 193 base = env_get_bootm_low(); 194 size = env_get_bootm_size(); 195 196 fdt_fixup_memory(blob, (u64)base, (u64)size); 197 198 #ifdef CONFIG_PCI 199 pci_of_setup(blob, bd); 200 #endif 201 202 fdt_fixup_liodn(blob); 203 fsl_fdt_fixup_dr_usb(blob, bd); 204 205 #ifdef CONFIG_SYS_DPAA_FMAN 206 fdt_fixup_fman_ethernet(blob); 207 fdt_fixup_board_enet(blob); 208 #endif 209 210 return 0; 211 } 212