blob: 221048a91f1865b6c111e4a88cf2b06b7ce06e08 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +02002/*
3 * (C) Copyright 2007-2008
Stelian Pop5ee0c7f2011-11-01 00:00:39 +01004 * Stelian Pop <stelian@popies.net>
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +02005 * Lead Tech Design <www.leadtechdesign.com>
6 *
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +01007 * (C) Copyright 2009-2015
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +02008 * Daniel Gorsulowski <daniel.gorsulowski@esd.eu>
9 * esd electronic system design gmbh <www.esd.eu>
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020010 */
11
12#include <common.h>
Simon Glassdb229612019-08-01 09:46:42 -060013#include <env.h>
Simon Glassf5c208d2019-11-14 12:57:20 -070014#include <vsprintf.h>
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +000015#include <asm/io.h>
Andreas Bießmanna4c24d32013-11-29 12:13:45 +010016#include <asm/gpio.h>
Simon Glass0ffb9d62017-05-31 19:47:48 -060017#include <asm/mach-types.h>
Simon Glassd9a766f2017-05-17 08:23:00 -060018#include <asm/setup.h>
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020019#include <asm/arch/at91sam9_smc.h>
20#include <asm/arch/at91_common.h>
21#include <asm/arch/at91_pmc.h>
22#include <asm/arch/at91_rstc.h>
Daniel Gorsulowskifba24942010-08-09 11:17:14 +020023#include <asm/arch/at91_matrix.h>
24#include <asm/arch/at91_pio.h>
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020025#include <asm/arch/clk.h>
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020026#include <netdev.h>
27
28DECLARE_GLOBAL_DATA_PTR;
29
30/*
31 * Miscelaneous platform dependent initialisations
32 */
33
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +010034#ifdef CONFIG_REVISION_TAG
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020035static int hw_rev = -1; /* hardware revision */
36
37int get_hw_rev(void)
38{
39 if (hw_rev >= 0)
40 return hw_rev;
41
Daniel Gorsulowskifba24942010-08-09 11:17:14 +020042 hw_rev = at91_get_pio_value(AT91_PIO_PORTB, 19);
43 hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 20) << 1;
44 hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 21) << 2;
45 hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 22) << 3;
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020046
47 if (hw_rev == 15)
48 hw_rev = 0;
49
50 return hw_rev;
51}
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +010052#endif /* CONFIG_REVISION_TAG */
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020053
54#ifdef CONFIG_CMD_NAND
55static void meesc_nand_hw_init(void)
56{
57 unsigned long csa;
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +000058 at91_smc_t *smc = (at91_smc_t *) ATMEL_BASE_SMC0;
59 at91_matrix_t *matrix = (at91_matrix_t *) ATMEL_BASE_MATRIX;
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020060
61 /* Enable CS3 */
Daniel Gorsulowskifba24942010-08-09 11:17:14 +020062 csa = readl(&matrix->csa[0]) | AT91_MATRIX_CSA_EBI_CS3A;
63 writel(csa, &matrix->csa[0]);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020064
65 /* Configure SMC CS3 for NAND/SmartMedia */
Daniel Gorsulowski879fbe82012-01-25 03:19:49 +000066 writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) |
67 AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(2),
Daniel Gorsulowskifba24942010-08-09 11:17:14 +020068 &smc->cs[3].setup);
69
70 writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(3) |
71 AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(3),
72 &smc->cs[3].pulse);
73
Daniel Gorsulowski879fbe82012-01-25 03:19:49 +000074 writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(6),
Daniel Gorsulowskifba24942010-08-09 11:17:14 +020075 &smc->cs[3].cycle);
76 writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
77 AT91_SMC_MODE_EXNW_DISABLE |
78 AT91_SMC_MODE_DBW_8 |
Daniel Gorsulowski879fbe82012-01-25 03:19:49 +000079 AT91_SMC_MODE_TDF_CYCLE(12),
Daniel Gorsulowskifba24942010-08-09 11:17:14 +020080 &smc->cs[3].mode);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020081
82 /* Configure RDY/BSY */
Andreas Bießmanna4c24d32013-11-29 12:13:45 +010083 gpio_direction_input(CONFIG_SYS_NAND_READY_PIN);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020084
85 /* Enable NandFlash */
Andreas Bießmanna4c24d32013-11-29 12:13:45 +010086 gpio_direction_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020087}
88#endif /* CONFIG_CMD_NAND */
89
90#ifdef CONFIG_MACB
91static void meesc_macb_hw_init(void)
92{
Wenyou Yang78f89762016-02-03 10:16:50 +080093 at91_periph_clk_enable(ATMEL_ID_EMAC);
94
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +020095 at91_macb_hw_init();
96}
97#endif
98
99/*
100 * Static memory controller initialization to enable Beckhoff ET1100 EtherCAT
101 * controller debugging
102 * The ET1100 is located at physical address 0x70000000
103 * Its process memory is located at physical address 0x70001000
104 */
105static void meesc_ethercat_hw_init(void)
106{
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +0000107 at91_smc_t *smc1 = (at91_smc_t *) ATMEL_BASE_SMC1;
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200108
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200109 /* Configure SMC EBI1_CS0 for EtherCAT */
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200110 writel(AT91_SMC_SETUP_NWE(0) | AT91_SMC_SETUP_NCS_WR(0) |
111 AT91_SMC_SETUP_NRD(0) | AT91_SMC_SETUP_NCS_RD(0),
112 &smc1->cs[0].setup);
113 writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(9) |
114 AT91_SMC_PULSE_NRD(5) | AT91_SMC_PULSE_NCS_RD(9),
115 &smc1->cs[0].pulse);
116 writel(AT91_SMC_CYCLE_NWE(10) | AT91_SMC_CYCLE_NRD(6),
117 &smc1->cs[0].cycle);
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200118 /*
119 * Configure behavior at external wait signal, byte-select mode, 16 bit
120 * data bus width, none data float wait states and TDF optimization
121 */
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200122 writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_EXNW_READY |
123 AT91_SMC_MODE_DBW_16 | AT91_SMC_MODE_TDF_CYCLE(0) |
124 AT91_SMC_MODE_TDF, &smc1->cs[0].mode);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200125
126 /* Configure RDY/BSY */
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200127 at91_set_b_periph(AT91_PIO_PORTE, 20, 0); /* EBI1_NWAIT */
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200128}
129
130int dram_init(void)
131{
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100132 /* dram_init must store complete ramsize in gd->ram_size */
133 gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
134 PHYS_SDRAM_SIZE);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200135 return 0;
136}
137
Simon Glass2f949c32017-03-31 08:40:32 -0600138int dram_init_banksize(void)
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100139{
140 gd->bd->bi_dram[0].start = PHYS_SDRAM;
141 gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
Simon Glass2f949c32017-03-31 08:40:32 -0600142
143 return 0;
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100144}
145
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200146int board_eth_init(bd_t *bis)
147{
148 int rc = 0;
149#ifdef CONFIG_MACB
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +0000150 rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200151#endif
152 return rc;
153}
154
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100155#ifdef CONFIG_DISPLAY_BOARDINFO
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200156int checkboard(void)
157{
158 char str[32];
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200159 u_char hw_type; /* hardware type */
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200160
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200161 /* read the "Type" register of the ET1100 controller */
162 hw_type = readb(CONFIG_ET1100_BASE);
163
164 switch (hw_type) {
165 case 0x11:
166 case 0x3F:
167 /* ET1100 present, arch number of MEESC-Board */
168 gd->bd->bi_arch_number = MACH_TYPE_MEESC;
169 puts("Board: CAN-EtherCAT Gateway");
170 break;
171 case 0xFF:
172 /* no ET1100 present, arch number of EtherCAN/2-Board */
173 gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2;
174 puts("Board: EtherCAN/2 Gateway");
175 /* switch on LED1D */
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200176 at91_set_pio_output(AT91_PIO_PORTB, 12, 1);
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200177 break;
178 default:
179 /* assume, no ET1100 present, arch number of EtherCAN/2-Board */
180 gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2;
181 printf("ERROR! Read invalid hw_type: %02X\n", hw_type);
182 puts("Board: EtherCAN/2 Gateway");
183 break;
184 }
Simon Glass64b723f2017-08-03 12:22:12 -0600185 if (env_get_f("serial#", str, sizeof(str)) > 0) {
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200186 puts(", serial# ");
187 puts(str);
188 }
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100189#ifdef CONFIG_REVISION_TAG
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200190 printf("\nHardware-revision: 1.%d\n", get_hw_rev());
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100191#endif
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200192 printf("Mach-type: %lu\n", gd->bd->bi_arch_number);
193 return 0;
194}
Daniel Gorsulowski2acb23b2015-11-02 07:59:49 +0100195#endif /* CONFIG_DISPLAY_BOARDINFO */
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200196
197#ifdef CONFIG_SERIAL_TAG
198void get_board_serial(struct tag_serialnr *serialnr)
199{
200 char *str;
201
Simon Glass64b723f2017-08-03 12:22:12 -0600202 char *serial = env_get("serial#");
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200203 if (serial) {
204 str = strchr(serial, '_');
205 if (str && (strlen(str) >= 4)) {
206 serialnr->high = (*(str + 1) << 8) | *(str + 2);
207 serialnr->low = simple_strtoul(str + 3, NULL, 16);
208 }
209 } else {
210 serialnr->high = 0;
211 serialnr->low = 0;
212 }
213}
214#endif
215
216#ifdef CONFIG_REVISION_TAG
217u32 get_board_rev(void)
218{
219 return hw_rev | 0x100;
220}
221#endif
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200222
Daniel Gorsulowski88e57172010-01-20 08:00:11 +0100223#ifdef CONFIG_MISC_INIT_R
224int misc_init_r(void)
225{
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200226 char *str;
227 char buf[32];
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +0000228 at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
Daniel Gorsulowski88e57172010-01-20 08:00:11 +0100229
230 /*
231 * Normally the processor clock has a divisor of 2.
232 * In some cases this this needs to be set to 4.
233 * Check the user has set environment mdiv to 4 to change the divisor.
234 */
Simon Glass64b723f2017-08-03 12:22:12 -0600235 str = env_get("mdiv");
236 if (str && (strcmp(str, "4") == 0)) {
Daniel Gorsulowskifba24942010-08-09 11:17:14 +0200237 writel((readl(&pmc->mckr) & ~AT91_PMC_MDIV) |
238 AT91SAM9_PMC_MDIV_4, &pmc->mckr);
239 at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
Daniel Gorsulowski88e57172010-01-20 08:00:11 +0100240 serial_setbrg();
241 /* Notify the user that the clock is not default */
242 printf("Setting master clock to %s MHz\n",
243 strmhz(buf, get_mck_clk_rate()));
244 }
245
246 return 0;
247}
248#endif /* CONFIG_MISC_INIT_R */
249
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +0000250int board_early_init_f(void)
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200251{
Wenyou Yang78f89762016-02-03 10:16:50 +0800252 at91_periph_clk_enable(ATMEL_ID_UHP);
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200253
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +0000254 return 0;
255}
256
257int board_init(void)
258{
Daniel Gorsulowski54b531a2009-09-29 08:03:12 +0200259 /* initialize ET1100 Controller */
260 meesc_ethercat_hw_init();
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200261
262 /* adress of boot parameters */
Matthias Fuchs2d56c2b2011-07-19 01:56:06 +0000263 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200264
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200265#ifdef CONFIG_CMD_NAND
266 meesc_nand_hw_init();
267#endif
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200268#ifdef CONFIG_MACB
269 meesc_macb_hw_init();
270#endif
271#ifdef CONFIG_AT91_CAN
272 at91_can_hw_init();
273#endif
Daniel Gorsulowskic7b769a2010-08-09 11:17:15 +0200274#ifdef CONFIG_USB_OHCI_NEW
275 at91_uhp_hw_init();
276#endif
Daniel Gorsulowski6f196d52009-06-30 21:03:37 +0200277 return 0;
278}