]>
Commit | Line | Data |
---|---|---|
33b1d3f4 DG |
1 | /* |
2 | * (C) Copyright 2007-2008 | |
c9e798d3 | 3 | * Stelian Pop <[email protected]> |
33b1d3f4 DG |
4 | * Lead Tech Design <www.leadtechdesign.com> |
5 | * | |
83bf0057 | 6 | * (C) Copyright 2009-2015 |
33b1d3f4 DG |
7 | * Daniel Gorsulowski <[email protected]> |
8 | * esd electronic system design gmbh <www.esd.eu> | |
9 | * | |
1a459660 | 10 | * SPDX-License-Identifier: GPL-2.0+ |
33b1d3f4 DG |
11 | */ |
12 | ||
13 | #include <common.h> | |
0cb77bfa | 14 | #include <asm/io.h> |
ac45bb16 | 15 | #include <asm/gpio.h> |
c62db35d | 16 | #include <asm/mach-types.h> |
5d982856 | 17 | #include <asm/setup.h> |
33b1d3f4 DG |
18 | #include <asm/arch/at91sam9_smc.h> |
19 | #include <asm/arch/at91_common.h> | |
20 | #include <asm/arch/at91_pmc.h> | |
21 | #include <asm/arch/at91_rstc.h> | |
d4562e09 DG |
22 | #include <asm/arch/at91_matrix.h> |
23 | #include <asm/arch/at91_pio.h> | |
33b1d3f4 | 24 | #include <asm/arch/clk.h> |
33b1d3f4 DG |
25 | #include <netdev.h> |
26 | ||
27 | DECLARE_GLOBAL_DATA_PTR; | |
28 | ||
29 | /* | |
30 | * Miscelaneous platform dependent initialisations | |
31 | */ | |
32 | ||
83bf0057 | 33 | #ifdef CONFIG_REVISION_TAG |
33b1d3f4 DG |
34 | static int hw_rev = -1; /* hardware revision */ |
35 | ||
36 | int get_hw_rev(void) | |
37 | { | |
38 | if (hw_rev >= 0) | |
39 | return hw_rev; | |
40 | ||
d4562e09 DG |
41 | hw_rev = at91_get_pio_value(AT91_PIO_PORTB, 19); |
42 | hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 20) << 1; | |
43 | hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 21) << 2; | |
44 | hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 22) << 3; | |
33b1d3f4 DG |
45 | |
46 | if (hw_rev == 15) | |
47 | hw_rev = 0; | |
48 | ||
49 | return hw_rev; | |
50 | } | |
83bf0057 | 51 | #endif /* CONFIG_REVISION_TAG */ |
33b1d3f4 DG |
52 | |
53 | #ifdef CONFIG_CMD_NAND | |
54 | static void meesc_nand_hw_init(void) | |
55 | { | |
56 | unsigned long csa; | |
0cb77bfa MF |
57 | at91_smc_t *smc = (at91_smc_t *) ATMEL_BASE_SMC0; |
58 | at91_matrix_t *matrix = (at91_matrix_t *) ATMEL_BASE_MATRIX; | |
33b1d3f4 DG |
59 | |
60 | /* Enable CS3 */ | |
d4562e09 DG |
61 | csa = readl(&matrix->csa[0]) | AT91_MATRIX_CSA_EBI_CS3A; |
62 | writel(csa, &matrix->csa[0]); | |
33b1d3f4 DG |
63 | |
64 | /* Configure SMC CS3 for NAND/SmartMedia */ | |
dd80264d DG |
65 | writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) | |
66 | AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(2), | |
d4562e09 DG |
67 | &smc->cs[3].setup); |
68 | ||
69 | writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(3) | | |
70 | AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(3), | |
71 | &smc->cs[3].pulse); | |
72 | ||
dd80264d | 73 | writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(6), |
d4562e09 DG |
74 | &smc->cs[3].cycle); |
75 | writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE | | |
76 | AT91_SMC_MODE_EXNW_DISABLE | | |
77 | AT91_SMC_MODE_DBW_8 | | |
dd80264d | 78 | AT91_SMC_MODE_TDF_CYCLE(12), |
d4562e09 | 79 | &smc->cs[3].mode); |
33b1d3f4 DG |
80 | |
81 | /* Configure RDY/BSY */ | |
ac45bb16 | 82 | gpio_direction_input(CONFIG_SYS_NAND_READY_PIN); |
33b1d3f4 DG |
83 | |
84 | /* Enable NandFlash */ | |
ac45bb16 | 85 | gpio_direction_output(CONFIG_SYS_NAND_ENABLE_PIN, 1); |
33b1d3f4 DG |
86 | } |
87 | #endif /* CONFIG_CMD_NAND */ | |
88 | ||
89 | #ifdef CONFIG_MACB | |
90 | static void meesc_macb_hw_init(void) | |
91 | { | |
70341e2e WY |
92 | at91_periph_clk_enable(ATMEL_ID_EMAC); |
93 | ||
33b1d3f4 DG |
94 | at91_macb_hw_init(); |
95 | } | |
96 | #endif | |
97 | ||
98 | /* | |
99 | * Static memory controller initialization to enable Beckhoff ET1100 EtherCAT | |
100 | * controller debugging | |
101 | * The ET1100 is located at physical address 0x70000000 | |
102 | * Its process memory is located at physical address 0x70001000 | |
103 | */ | |
104 | static void meesc_ethercat_hw_init(void) | |
105 | { | |
0cb77bfa | 106 | at91_smc_t *smc1 = (at91_smc_t *) ATMEL_BASE_SMC1; |
d4562e09 | 107 | |
33b1d3f4 | 108 | /* Configure SMC EBI1_CS0 for EtherCAT */ |
d4562e09 DG |
109 | writel(AT91_SMC_SETUP_NWE(0) | AT91_SMC_SETUP_NCS_WR(0) | |
110 | AT91_SMC_SETUP_NRD(0) | AT91_SMC_SETUP_NCS_RD(0), | |
111 | &smc1->cs[0].setup); | |
112 | writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(9) | | |
113 | AT91_SMC_PULSE_NRD(5) | AT91_SMC_PULSE_NCS_RD(9), | |
114 | &smc1->cs[0].pulse); | |
115 | writel(AT91_SMC_CYCLE_NWE(10) | AT91_SMC_CYCLE_NRD(6), | |
116 | &smc1->cs[0].cycle); | |
a380279b DG |
117 | /* |
118 | * Configure behavior at external wait signal, byte-select mode, 16 bit | |
119 | * data bus width, none data float wait states and TDF optimization | |
120 | */ | |
d4562e09 DG |
121 | writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_EXNW_READY | |
122 | AT91_SMC_MODE_DBW_16 | AT91_SMC_MODE_TDF_CYCLE(0) | | |
123 | AT91_SMC_MODE_TDF, &smc1->cs[0].mode); | |
33b1d3f4 DG |
124 | |
125 | /* Configure RDY/BSY */ | |
d4562e09 | 126 | at91_set_b_periph(AT91_PIO_PORTE, 20, 0); /* EBI1_NWAIT */ |
33b1d3f4 DG |
127 | } |
128 | ||
129 | int dram_init(void) | |
130 | { | |
83bf0057 DG |
131 | /* dram_init must store complete ramsize in gd->ram_size */ |
132 | gd->ram_size = get_ram_size((void *)PHYS_SDRAM, | |
133 | PHYS_SDRAM_SIZE); | |
33b1d3f4 DG |
134 | return 0; |
135 | } | |
136 | ||
76b00aca | 137 | int dram_init_banksize(void) |
83bf0057 DG |
138 | { |
139 | gd->bd->bi_dram[0].start = PHYS_SDRAM; | |
140 | gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE; | |
76b00aca SG |
141 | |
142 | return 0; | |
83bf0057 DG |
143 | } |
144 | ||
33b1d3f4 DG |
145 | int board_eth_init(bd_t *bis) |
146 | { | |
147 | int rc = 0; | |
148 | #ifdef CONFIG_MACB | |
0cb77bfa | 149 | rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00); |
33b1d3f4 DG |
150 | #endif |
151 | return rc; | |
152 | } | |
153 | ||
83bf0057 | 154 | #ifdef CONFIG_DISPLAY_BOARDINFO |
33b1d3f4 DG |
155 | int checkboard(void) |
156 | { | |
157 | char str[32]; | |
a380279b DG |
158 | u_char hw_type; /* hardware type */ |
159 | ||
160 | /* read the "Type" register of the ET1100 controller */ | |
161 | hw_type = readb(CONFIG_ET1100_BASE); | |
162 | ||
163 | switch (hw_type) { | |
164 | case 0x11: | |
165 | case 0x3F: | |
166 | /* ET1100 present, arch number of MEESC-Board */ | |
167 | gd->bd->bi_arch_number = MACH_TYPE_MEESC; | |
168 | puts("Board: CAN-EtherCAT Gateway"); | |
169 | break; | |
170 | case 0xFF: | |
171 | /* no ET1100 present, arch number of EtherCAN/2-Board */ | |
172 | gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2; | |
173 | puts("Board: EtherCAN/2 Gateway"); | |
174 | /* switch on LED1D */ | |
d4562e09 | 175 | at91_set_pio_output(AT91_PIO_PORTB, 12, 1); |
a380279b DG |
176 | break; |
177 | default: | |
178 | /* assume, no ET1100 present, arch number of EtherCAN/2-Board */ | |
179 | gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2; | |
180 | printf("ERROR! Read invalid hw_type: %02X\n", hw_type); | |
181 | puts("Board: EtherCAN/2 Gateway"); | |
182 | break; | |
183 | } | |
00caae6d | 184 | if (env_get_f("serial#", str, sizeof(str)) > 0) { |
33b1d3f4 DG |
185 | puts(", serial# "); |
186 | puts(str); | |
187 | } | |
83bf0057 | 188 | #ifdef CONFIG_REVISION_TAG |
33b1d3f4 | 189 | printf("\nHardware-revision: 1.%d\n", get_hw_rev()); |
83bf0057 | 190 | #endif |
33b1d3f4 DG |
191 | printf("Mach-type: %lu\n", gd->bd->bi_arch_number); |
192 | return 0; | |
193 | } | |
83bf0057 | 194 | #endif /* CONFIG_DISPLAY_BOARDINFO */ |
33b1d3f4 | 195 | |
a380279b DG |
196 | #ifdef CONFIG_SERIAL_TAG |
197 | void get_board_serial(struct tag_serialnr *serialnr) | |
198 | { | |
199 | char *str; | |
200 | ||
00caae6d | 201 | char *serial = env_get("serial#"); |
a380279b DG |
202 | if (serial) { |
203 | str = strchr(serial, '_'); | |
204 | if (str && (strlen(str) >= 4)) { | |
205 | serialnr->high = (*(str + 1) << 8) | *(str + 2); | |
206 | serialnr->low = simple_strtoul(str + 3, NULL, 16); | |
207 | } | |
208 | } else { | |
209 | serialnr->high = 0; | |
210 | serialnr->low = 0; | |
211 | } | |
212 | } | |
213 | #endif | |
214 | ||
215 | #ifdef CONFIG_REVISION_TAG | |
216 | u32 get_board_rev(void) | |
217 | { | |
218 | return hw_rev | 0x100; | |
219 | } | |
220 | #endif | |
221 | ||
a3f3897b DG |
222 | #ifdef CONFIG_MISC_INIT_R |
223 | int misc_init_r(void) | |
224 | { | |
d4562e09 DG |
225 | char *str; |
226 | char buf[32]; | |
0cb77bfa | 227 | at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; |
a3f3897b DG |
228 | |
229 | /* | |
230 | * Normally the processor clock has a divisor of 2. | |
231 | * In some cases this this needs to be set to 4. | |
232 | * Check the user has set environment mdiv to 4 to change the divisor. | |
233 | */ | |
00caae6d SG |
234 | str = env_get("mdiv"); |
235 | if (str && (strcmp(str, "4") == 0)) { | |
d4562e09 DG |
236 | writel((readl(&pmc->mckr) & ~AT91_PMC_MDIV) | |
237 | AT91SAM9_PMC_MDIV_4, &pmc->mckr); | |
238 | at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK); | |
a3f3897b DG |
239 | serial_setbrg(); |
240 | /* Notify the user that the clock is not default */ | |
241 | printf("Setting master clock to %s MHz\n", | |
242 | strmhz(buf, get_mck_clk_rate())); | |
243 | } | |
244 | ||
245 | return 0; | |
246 | } | |
247 | #endif /* CONFIG_MISC_INIT_R */ | |
248 | ||
0cb77bfa | 249 | int board_early_init_f(void) |
33b1d3f4 | 250 | { |
70341e2e | 251 | at91_periph_clk_enable(ATMEL_ID_UHP); |
33b1d3f4 | 252 | |
0cb77bfa MF |
253 | return 0; |
254 | } | |
255 | ||
256 | int board_init(void) | |
257 | { | |
a380279b DG |
258 | /* initialize ET1100 Controller */ |
259 | meesc_ethercat_hw_init(); | |
33b1d3f4 DG |
260 | |
261 | /* adress of boot parameters */ | |
0cb77bfa | 262 | gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; |
33b1d3f4 | 263 | |
33b1d3f4 DG |
264 | #ifdef CONFIG_CMD_NAND |
265 | meesc_nand_hw_init(); | |
266 | #endif | |
33b1d3f4 DG |
267 | #ifdef CONFIG_MACB |
268 | meesc_macb_hw_init(); | |
269 | #endif | |
270 | #ifdef CONFIG_AT91_CAN | |
271 | at91_can_hw_init(); | |
64037fb4 DG |
272 | #endif |
273 | #ifdef CONFIG_USB_OHCI_NEW | |
274 | at91_uhp_hw_init(); | |
33b1d3f4 DG |
275 | #endif |
276 | return 0; | |
277 | } |