133b1d3f4SDaniel Gorsulowski /* 233b1d3f4SDaniel Gorsulowski * (C) Copyright 2007-2008 333b1d3f4SDaniel Gorsulowski * Stelian Pop <stelian.pop@leadtechdesign.com> 433b1d3f4SDaniel Gorsulowski * Lead Tech Design <www.leadtechdesign.com> 533b1d3f4SDaniel Gorsulowski * 633b1d3f4SDaniel Gorsulowski * (C) Copyright 2009 733b1d3f4SDaniel Gorsulowski * Daniel Gorsulowski <daniel.gorsulowski@esd.eu> 833b1d3f4SDaniel Gorsulowski * esd electronic system design gmbh <www.esd.eu> 933b1d3f4SDaniel Gorsulowski * 1033b1d3f4SDaniel Gorsulowski * See file CREDITS for list of people who contributed to this 1133b1d3f4SDaniel Gorsulowski * project. 1233b1d3f4SDaniel Gorsulowski * 1333b1d3f4SDaniel Gorsulowski * This program is free software; you can redistribute it and/or 1433b1d3f4SDaniel Gorsulowski * modify it under the terms of the GNU General Public License as 1533b1d3f4SDaniel Gorsulowski * published by the Free Software Foundation; either version 2 of 1633b1d3f4SDaniel Gorsulowski * the License, or (at your option) any later version. 1733b1d3f4SDaniel Gorsulowski * 1833b1d3f4SDaniel Gorsulowski * This program is distributed in the hope that it will be useful, 1933b1d3f4SDaniel Gorsulowski * but WITHOUT ANY WARRANTY; without even the implied warranty of 2033b1d3f4SDaniel Gorsulowski * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2133b1d3f4SDaniel Gorsulowski * GNU General Public License for more details. 2233b1d3f4SDaniel Gorsulowski * 2333b1d3f4SDaniel Gorsulowski * You should have received a copy of the GNU General Public License 2433b1d3f4SDaniel Gorsulowski * along with this program; if not, write to the Free Software 2533b1d3f4SDaniel Gorsulowski * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 2633b1d3f4SDaniel Gorsulowski * MA 02111-1307 USA 2733b1d3f4SDaniel Gorsulowski */ 2833b1d3f4SDaniel Gorsulowski 2933b1d3f4SDaniel Gorsulowski #include <common.h> 3033b1d3f4SDaniel Gorsulowski #include <asm/arch/at91sam9263.h> 3133b1d3f4SDaniel Gorsulowski #include <asm/arch/at91sam9_matrix.h> 3233b1d3f4SDaniel Gorsulowski #include <asm/arch/at91sam9_smc.h> 3333b1d3f4SDaniel Gorsulowski #include <asm/arch/at91_common.h> 3433b1d3f4SDaniel Gorsulowski #include <asm/arch/at91_pmc.h> 3533b1d3f4SDaniel Gorsulowski #include <asm/arch/at91_rstc.h> 3633b1d3f4SDaniel Gorsulowski #include <asm/arch/clk.h> 3733b1d3f4SDaniel Gorsulowski #include <asm/arch/gpio.h> 3833b1d3f4SDaniel Gorsulowski #include <asm/arch/hardware.h> 3933b1d3f4SDaniel Gorsulowski #include <asm/arch/io.h> 4033b1d3f4SDaniel Gorsulowski #include <netdev.h> 4133b1d3f4SDaniel Gorsulowski 4233b1d3f4SDaniel Gorsulowski DECLARE_GLOBAL_DATA_PTR; 4333b1d3f4SDaniel Gorsulowski 4433b1d3f4SDaniel Gorsulowski /* 4533b1d3f4SDaniel Gorsulowski * Miscelaneous platform dependent initialisations 4633b1d3f4SDaniel Gorsulowski */ 4733b1d3f4SDaniel Gorsulowski 4833b1d3f4SDaniel Gorsulowski static int hw_rev = -1; /* hardware revision */ 4933b1d3f4SDaniel Gorsulowski 5033b1d3f4SDaniel Gorsulowski int get_hw_rev(void) 5133b1d3f4SDaniel Gorsulowski { 5233b1d3f4SDaniel Gorsulowski if (hw_rev >= 0) 5333b1d3f4SDaniel Gorsulowski return hw_rev; 5433b1d3f4SDaniel Gorsulowski 5533b1d3f4SDaniel Gorsulowski hw_rev = at91_get_gpio_value(AT91_PIN_PB19); 5633b1d3f4SDaniel Gorsulowski hw_rev |= at91_get_gpio_value(AT91_PIN_PB20) << 1; 5733b1d3f4SDaniel Gorsulowski hw_rev |= at91_get_gpio_value(AT91_PIN_PB21) << 2; 5833b1d3f4SDaniel Gorsulowski hw_rev |= at91_get_gpio_value(AT91_PIN_PB22) << 3; 5933b1d3f4SDaniel Gorsulowski 6033b1d3f4SDaniel Gorsulowski if (hw_rev == 15) 6133b1d3f4SDaniel Gorsulowski hw_rev = 0; 6233b1d3f4SDaniel Gorsulowski 6333b1d3f4SDaniel Gorsulowski return hw_rev; 6433b1d3f4SDaniel Gorsulowski } 6533b1d3f4SDaniel Gorsulowski 6633b1d3f4SDaniel Gorsulowski #ifdef CONFIG_CMD_NAND 6733b1d3f4SDaniel Gorsulowski static void meesc_nand_hw_init(void) 6833b1d3f4SDaniel Gorsulowski { 6933b1d3f4SDaniel Gorsulowski unsigned long csa; 7033b1d3f4SDaniel Gorsulowski 7133b1d3f4SDaniel Gorsulowski /* Enable CS3 */ 7233b1d3f4SDaniel Gorsulowski csa = at91_sys_read(AT91_MATRIX_EBI0CSA); 7333b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_MATRIX_EBI0CSA, 7433b1d3f4SDaniel Gorsulowski csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); 7533b1d3f4SDaniel Gorsulowski 7633b1d3f4SDaniel Gorsulowski /* Configure SMC CS3 for NAND/SmartMedia */ 7733b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC_SETUP(3), 7833b1d3f4SDaniel Gorsulowski AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) | 7933b1d3f4SDaniel Gorsulowski AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0)); 8033b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC_PULSE(3), 8133b1d3f4SDaniel Gorsulowski AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | 8233b1d3f4SDaniel Gorsulowski AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); 8333b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC_CYCLE(3), 8433b1d3f4SDaniel Gorsulowski AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); 8533b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC_MODE(3), 8633b1d3f4SDaniel Gorsulowski AT91_SMC_READMODE | AT91_SMC_WRITEMODE | 8733b1d3f4SDaniel Gorsulowski AT91_SMC_EXNWMODE_DISABLE | 8833b1d3f4SDaniel Gorsulowski #ifdef CONFIG_SYS_NAND_DBW_16 8933b1d3f4SDaniel Gorsulowski AT91_SMC_DBW_16 | 9033b1d3f4SDaniel Gorsulowski #else /* CONFIG_SYS_NAND_DBW_8 */ 9133b1d3f4SDaniel Gorsulowski AT91_SMC_DBW_8 | 9233b1d3f4SDaniel Gorsulowski #endif 9333b1d3f4SDaniel Gorsulowski AT91_SMC_TDF_(2)); 9433b1d3f4SDaniel Gorsulowski 9533b1d3f4SDaniel Gorsulowski /* Configure RDY/BSY */ 9633b1d3f4SDaniel Gorsulowski at91_set_gpio_input(CONFIG_SYS_NAND_READY_PIN, 1); 9733b1d3f4SDaniel Gorsulowski 9833b1d3f4SDaniel Gorsulowski /* Enable NandFlash */ 9933b1d3f4SDaniel Gorsulowski at91_set_gpio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1); 10033b1d3f4SDaniel Gorsulowski } 10133b1d3f4SDaniel Gorsulowski #endif /* CONFIG_CMD_NAND */ 10233b1d3f4SDaniel Gorsulowski 10333b1d3f4SDaniel Gorsulowski #ifdef CONFIG_MACB 10433b1d3f4SDaniel Gorsulowski static void meesc_macb_hw_init(void) 10533b1d3f4SDaniel Gorsulowski { 10633b1d3f4SDaniel Gorsulowski /* Enable clock */ 10733b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_EMAC); 10833b1d3f4SDaniel Gorsulowski at91_macb_hw_init(); 10933b1d3f4SDaniel Gorsulowski } 11033b1d3f4SDaniel Gorsulowski #endif 11133b1d3f4SDaniel Gorsulowski 11233b1d3f4SDaniel Gorsulowski /* 11333b1d3f4SDaniel Gorsulowski * Static memory controller initialization to enable Beckhoff ET1100 EtherCAT 11433b1d3f4SDaniel Gorsulowski * controller debugging 11533b1d3f4SDaniel Gorsulowski * The ET1100 is located at physical address 0x70000000 11633b1d3f4SDaniel Gorsulowski * Its process memory is located at physical address 0x70001000 11733b1d3f4SDaniel Gorsulowski */ 11833b1d3f4SDaniel Gorsulowski static void meesc_ethercat_hw_init(void) 11933b1d3f4SDaniel Gorsulowski { 12033b1d3f4SDaniel Gorsulowski /* Configure SMC EBI1_CS0 for EtherCAT */ 12133b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC1_SETUP(0), 12233b1d3f4SDaniel Gorsulowski AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | 12333b1d3f4SDaniel Gorsulowski AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); 12433b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC1_PULSE(0), 12533b1d3f4SDaniel Gorsulowski AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(9) | 12633b1d3f4SDaniel Gorsulowski AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(9)); 12733b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC1_CYCLE(0), 12833b1d3f4SDaniel Gorsulowski AT91_SMC_NWECYCLE_(10) | AT91_SMC_NRDCYCLE_(5)); 129a380279bSDaniel Gorsulowski /* 130a380279bSDaniel Gorsulowski * Configure behavior at external wait signal, byte-select mode, 16 bit 131a380279bSDaniel Gorsulowski * data bus width, none data float wait states and TDF optimization 132a380279bSDaniel Gorsulowski */ 13333b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_SMC1_MODE(0), 13433b1d3f4SDaniel Gorsulowski AT91_SMC_READMODE | AT91_SMC_EXNWMODE_READY | 13533b1d3f4SDaniel Gorsulowski AT91_SMC_BAT_SELECT | AT91_SMC_DBW_16 | AT91_SMC_TDF_(0) | 13633b1d3f4SDaniel Gorsulowski AT91_SMC_TDFMODE); 13733b1d3f4SDaniel Gorsulowski 13833b1d3f4SDaniel Gorsulowski /* Configure RDY/BSY */ 13933b1d3f4SDaniel Gorsulowski at91_set_B_periph(AT91_PIN_PE20, 0); /* EBI1_NWAIT */ 14033b1d3f4SDaniel Gorsulowski } 14133b1d3f4SDaniel Gorsulowski 14233b1d3f4SDaniel Gorsulowski int dram_init(void) 14333b1d3f4SDaniel Gorsulowski { 14433b1d3f4SDaniel Gorsulowski gd->bd->bi_dram[0].start = PHYS_SDRAM; 14533b1d3f4SDaniel Gorsulowski gd->bd->bi_dram[0].size = get_ram_size((long *) PHYS_SDRAM, (1 << 27)); 14633b1d3f4SDaniel Gorsulowski return 0; 14733b1d3f4SDaniel Gorsulowski } 14833b1d3f4SDaniel Gorsulowski 14933b1d3f4SDaniel Gorsulowski int board_eth_init(bd_t *bis) 15033b1d3f4SDaniel Gorsulowski { 15133b1d3f4SDaniel Gorsulowski int rc = 0; 15233b1d3f4SDaniel Gorsulowski #ifdef CONFIG_MACB 15333b1d3f4SDaniel Gorsulowski rc = macb_eth_initialize(0, (void *)AT91SAM9263_BASE_EMAC, 0x00); 15433b1d3f4SDaniel Gorsulowski #endif 15533b1d3f4SDaniel Gorsulowski return rc; 15633b1d3f4SDaniel Gorsulowski } 15733b1d3f4SDaniel Gorsulowski 15833b1d3f4SDaniel Gorsulowski int checkboard(void) 15933b1d3f4SDaniel Gorsulowski { 16033b1d3f4SDaniel Gorsulowski char str[32]; 161a380279bSDaniel Gorsulowski u_char hw_type; /* hardware type */ 16233b1d3f4SDaniel Gorsulowski 163a380279bSDaniel Gorsulowski /* read the "Type" register of the ET1100 controller */ 164a380279bSDaniel Gorsulowski hw_type = readb(CONFIG_ET1100_BASE); 165a380279bSDaniel Gorsulowski 166a380279bSDaniel Gorsulowski switch (hw_type) { 167a380279bSDaniel Gorsulowski case 0x11: 168a380279bSDaniel Gorsulowski case 0x3F: 169a380279bSDaniel Gorsulowski /* ET1100 present, arch number of MEESC-Board */ 170a380279bSDaniel Gorsulowski gd->bd->bi_arch_number = MACH_TYPE_MEESC; 171a380279bSDaniel Gorsulowski puts("Board: CAN-EtherCAT Gateway"); 172a380279bSDaniel Gorsulowski break; 173a380279bSDaniel Gorsulowski case 0xFF: 174a380279bSDaniel Gorsulowski /* no ET1100 present, arch number of EtherCAN/2-Board */ 175a380279bSDaniel Gorsulowski gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2; 176a380279bSDaniel Gorsulowski puts("Board: EtherCAN/2 Gateway"); 177a380279bSDaniel Gorsulowski /* switch on LED1D */ 178a380279bSDaniel Gorsulowski at91_set_gpio_output(AT91_PIN_PB12, 1); 179a380279bSDaniel Gorsulowski break; 180a380279bSDaniel Gorsulowski default: 181a380279bSDaniel Gorsulowski /* assume, no ET1100 present, arch number of EtherCAN/2-Board */ 182a380279bSDaniel Gorsulowski gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2; 183a380279bSDaniel Gorsulowski printf("ERROR! Read invalid hw_type: %02X\n", hw_type); 184a380279bSDaniel Gorsulowski puts("Board: EtherCAN/2 Gateway"); 185a380279bSDaniel Gorsulowski break; 186a380279bSDaniel Gorsulowski } 187*cdb74977SWolfgang Denk if (getenv_f("serial#", str, sizeof(str)) > 0) { 18833b1d3f4SDaniel Gorsulowski puts(", serial# "); 18933b1d3f4SDaniel Gorsulowski puts(str); 19033b1d3f4SDaniel Gorsulowski } 19133b1d3f4SDaniel Gorsulowski printf("\nHardware-revision: 1.%d\n", get_hw_rev()); 19233b1d3f4SDaniel Gorsulowski printf("Mach-type: %lu\n", gd->bd->bi_arch_number); 19333b1d3f4SDaniel Gorsulowski return 0; 19433b1d3f4SDaniel Gorsulowski } 19533b1d3f4SDaniel Gorsulowski 196a380279bSDaniel Gorsulowski #ifdef CONFIG_SERIAL_TAG 197a380279bSDaniel Gorsulowski void get_board_serial(struct tag_serialnr *serialnr) 198a380279bSDaniel Gorsulowski { 199a380279bSDaniel Gorsulowski char *str; 200a380279bSDaniel Gorsulowski 201a380279bSDaniel Gorsulowski char *serial = getenv("serial#"); 202a380279bSDaniel Gorsulowski if (serial) { 203a380279bSDaniel Gorsulowski str = strchr(serial, '_'); 204a380279bSDaniel Gorsulowski if (str && (strlen(str) >= 4)) { 205a380279bSDaniel Gorsulowski serialnr->high = (*(str + 1) << 8) | *(str + 2); 206a380279bSDaniel Gorsulowski serialnr->low = simple_strtoul(str + 3, NULL, 16); 207a380279bSDaniel Gorsulowski } 208a380279bSDaniel Gorsulowski } else { 209a380279bSDaniel Gorsulowski serialnr->high = 0; 210a380279bSDaniel Gorsulowski serialnr->low = 0; 211a380279bSDaniel Gorsulowski } 212a380279bSDaniel Gorsulowski } 213a380279bSDaniel Gorsulowski #endif 214a380279bSDaniel Gorsulowski 215a380279bSDaniel Gorsulowski #ifdef CONFIG_REVISION_TAG 216a380279bSDaniel Gorsulowski u32 get_board_rev(void) 217a380279bSDaniel Gorsulowski { 218a380279bSDaniel Gorsulowski return hw_rev | 0x100; 219a380279bSDaniel Gorsulowski } 220a380279bSDaniel Gorsulowski #endif 221a380279bSDaniel Gorsulowski 222a3f3897bSDaniel Gorsulowski #ifdef CONFIG_MISC_INIT_R 223a3f3897bSDaniel Gorsulowski int misc_init_r(void) 224a3f3897bSDaniel Gorsulowski { 225a3f3897bSDaniel Gorsulowski char *str; 226a3f3897bSDaniel Gorsulowski char buf[32]; 227a3f3897bSDaniel Gorsulowski 228a3f3897bSDaniel Gorsulowski /* 229a3f3897bSDaniel Gorsulowski * Normally the processor clock has a divisor of 2. 230a3f3897bSDaniel Gorsulowski * In some cases this this needs to be set to 4. 231a3f3897bSDaniel Gorsulowski * Check the user has set environment mdiv to 4 to change the divisor. 232a3f3897bSDaniel Gorsulowski */ 233a3f3897bSDaniel Gorsulowski if ((str = getenv("mdiv")) && (strcmp(str, "4") == 0)) { 234a3f3897bSDaniel Gorsulowski at91_sys_write(AT91_PMC_MCKR, 235a3f3897bSDaniel Gorsulowski (at91_sys_read(AT91_PMC_MCKR) & ~AT91_PMC_MDIV) | 236a3f3897bSDaniel Gorsulowski AT91SAM9_PMC_MDIV_4); 237a3f3897bSDaniel Gorsulowski at91_clock_init(0); 238a3f3897bSDaniel Gorsulowski serial_setbrg(); 239a3f3897bSDaniel Gorsulowski /* Notify the user that the clock is not default */ 240a3f3897bSDaniel Gorsulowski printf("Setting master clock to %s MHz\n", 241a3f3897bSDaniel Gorsulowski strmhz(buf, get_mck_clk_rate())); 242a3f3897bSDaniel Gorsulowski } 243a3f3897bSDaniel Gorsulowski 244a3f3897bSDaniel Gorsulowski return 0; 245a3f3897bSDaniel Gorsulowski } 246a3f3897bSDaniel Gorsulowski #endif /* CONFIG_MISC_INIT_R */ 247a3f3897bSDaniel Gorsulowski 24833b1d3f4SDaniel Gorsulowski int board_init(void) 24933b1d3f4SDaniel Gorsulowski { 25033b1d3f4SDaniel Gorsulowski /* Peripheral Clock Enable Register */ 25133b1d3f4SDaniel Gorsulowski at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_PIOA | 25233b1d3f4SDaniel Gorsulowski 1 << AT91SAM9263_ID_PIOB | 25333b1d3f4SDaniel Gorsulowski 1 << AT91SAM9263_ID_PIOCDE); 25433b1d3f4SDaniel Gorsulowski 255a380279bSDaniel Gorsulowski /* initialize ET1100 Controller */ 256a380279bSDaniel Gorsulowski meesc_ethercat_hw_init(); 25733b1d3f4SDaniel Gorsulowski 25833b1d3f4SDaniel Gorsulowski /* adress of boot parameters */ 25933b1d3f4SDaniel Gorsulowski gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; 26033b1d3f4SDaniel Gorsulowski 26133b1d3f4SDaniel Gorsulowski at91_serial_hw_init(); 26233b1d3f4SDaniel Gorsulowski #ifdef CONFIG_CMD_NAND 26333b1d3f4SDaniel Gorsulowski meesc_nand_hw_init(); 26433b1d3f4SDaniel Gorsulowski #endif 26533b1d3f4SDaniel Gorsulowski #ifdef CONFIG_HAS_DATAFLASH 26633b1d3f4SDaniel Gorsulowski at91_spi0_hw_init(1 << 0); 26733b1d3f4SDaniel Gorsulowski #endif 26833b1d3f4SDaniel Gorsulowski #ifdef CONFIG_MACB 26933b1d3f4SDaniel Gorsulowski meesc_macb_hw_init(); 27033b1d3f4SDaniel Gorsulowski #endif 27133b1d3f4SDaniel Gorsulowski #ifdef CONFIG_AT91_CAN 27233b1d3f4SDaniel Gorsulowski at91_can_hw_init(); 27333b1d3f4SDaniel Gorsulowski #endif 27433b1d3f4SDaniel Gorsulowski return 0; 27533b1d3f4SDaniel Gorsulowski } 276