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