1b89ac72aSHeiko Schocher /* 2b89ac72aSHeiko Schocher * Board functions for Siemens CORVUS (AT91SAM9G45) based board 3b89ac72aSHeiko Schocher * (C) Copyright 2013 Siemens AG 4b89ac72aSHeiko Schocher * 5b89ac72aSHeiko Schocher * Based on: 6b89ac72aSHeiko Schocher * U-Boot file: board/atmel/at91sam9m10g45ek/at91sam9m10g45ek.c 7b89ac72aSHeiko Schocher * (C) Copyright 2007-2008 8b89ac72aSHeiko Schocher * Stelian Pop <stelian@popies.net> 9b89ac72aSHeiko Schocher * Lead Tech Design <www.leadtechdesign.com> 10b89ac72aSHeiko Schocher * 11b89ac72aSHeiko Schocher * SPDX-License-Identifier: GPL-2.0+ 12b89ac72aSHeiko Schocher */ 13b89ac72aSHeiko Schocher 14b89ac72aSHeiko Schocher 15b89ac72aSHeiko Schocher #include <common.h> 16b89ac72aSHeiko Schocher #include <asm/io.h> 17b89ac72aSHeiko Schocher #include <asm/arch/at91sam9g45_matrix.h> 18b89ac72aSHeiko Schocher #include <asm/arch/at91sam9_smc.h> 19b89ac72aSHeiko Schocher #include <asm/arch/at91_common.h> 20b89ac72aSHeiko Schocher #include <asm/arch/at91_pmc.h> 21b89ac72aSHeiko Schocher #include <asm/arch/at91_rstc.h> 22b89ac72aSHeiko Schocher #include <asm/arch/gpio.h> 23b89ac72aSHeiko Schocher #include <asm/arch/clk.h> 24b89ac72aSHeiko Schocher #include <lcd.h> 25b89ac72aSHeiko Schocher #include <atmel_lcdc.h> 26b89ac72aSHeiko Schocher #if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB) 27b89ac72aSHeiko Schocher #include <net.h> 28b89ac72aSHeiko Schocher #endif 29b89ac72aSHeiko Schocher #include <netdev.h> 30b89ac72aSHeiko Schocher #include <spi.h> 31b89ac72aSHeiko Schocher 32b89ac72aSHeiko Schocher DECLARE_GLOBAL_DATA_PTR; 33b89ac72aSHeiko Schocher 34b89ac72aSHeiko Schocher static void corvus_nand_hw_init(void) 35b89ac72aSHeiko Schocher { 36b89ac72aSHeiko Schocher struct at91_smc *smc = (struct at91_smc *)ATMEL_BASE_SMC; 37b89ac72aSHeiko Schocher struct at91_matrix *matrix = (struct at91_matrix *)ATMEL_BASE_MATRIX; 38b89ac72aSHeiko Schocher unsigned long csa; 39b89ac72aSHeiko Schocher 40b89ac72aSHeiko Schocher /* Enable CS3 */ 41b89ac72aSHeiko Schocher csa = readl(&matrix->ebicsa); 42b89ac72aSHeiko Schocher csa |= AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA; 43b89ac72aSHeiko Schocher writel(csa, &matrix->ebicsa); 44b89ac72aSHeiko Schocher 45b89ac72aSHeiko Schocher /* Configure SMC CS3 for NAND/SmartMedia */ 46a5f8ccaeSHeiko Schocher writel(AT91_SMC_SETUP_NWE(2) | AT91_SMC_SETUP_NCS_WR(0) | 47a5f8ccaeSHeiko Schocher AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(0), 48b89ac72aSHeiko Schocher &smc->cs[3].setup); 49a5f8ccaeSHeiko Schocher writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(4) | 50a5f8ccaeSHeiko Schocher AT91_SMC_PULSE_NRD(4) | AT91_SMC_PULSE_NCS_RD(4), 51b89ac72aSHeiko Schocher &smc->cs[3].pulse); 52a5f8ccaeSHeiko Schocher writel(AT91_SMC_CYCLE_NWE(7) | AT91_SMC_CYCLE_NRD(7), 53b89ac72aSHeiko Schocher &smc->cs[3].cycle); 54b89ac72aSHeiko Schocher writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE | 55b89ac72aSHeiko Schocher AT91_SMC_MODE_EXNW_DISABLE | 56b89ac72aSHeiko Schocher #ifdef CONFIG_SYS_NAND_DBW_16 57b89ac72aSHeiko Schocher AT91_SMC_MODE_DBW_16 | 58b89ac72aSHeiko Schocher #else /* CONFIG_SYS_NAND_DBW_8 */ 59b89ac72aSHeiko Schocher AT91_SMC_MODE_DBW_8 | 60b89ac72aSHeiko Schocher #endif 61b89ac72aSHeiko Schocher AT91_SMC_MODE_TDF_CYCLE(3), 62b89ac72aSHeiko Schocher &smc->cs[3].mode); 63b89ac72aSHeiko Schocher 645b15fd98SHeiko Schocher at91_periph_clk_enable(ATMEL_ID_PIOC); 65a5f8ccaeSHeiko Schocher at91_periph_clk_enable(ATMEL_ID_PIOA); 66b89ac72aSHeiko Schocher 67b89ac72aSHeiko Schocher /* Enable NandFlash */ 68b89ac72aSHeiko Schocher at91_set_gpio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1); 69a5f8ccaeSHeiko Schocher at91_set_gpio_input(CONFIG_SYS_NAND_READY_PIN, 1); 70b89ac72aSHeiko Schocher } 715b15fd98SHeiko Schocher 725b15fd98SHeiko Schocher #if defined(CONFIG_SPL_BUILD) 735b15fd98SHeiko Schocher #include <spl.h> 745b15fd98SHeiko Schocher #include <nand.h> 755b15fd98SHeiko Schocher 76*fd45a0d1SHeiko Schocher void spl_board_init(void) 775b15fd98SHeiko Schocher { 785b15fd98SHeiko Schocher /* 795b15fd98SHeiko Schocher * For on the sam9m10g45ek board, the chip wm9711 stay in the test 805b15fd98SHeiko Schocher * mode, so it need do some action to exit mode. 815b15fd98SHeiko Schocher */ 825b15fd98SHeiko Schocher at91_set_gpio_output(AT91_PIN_PD7, 0); 835b15fd98SHeiko Schocher at91_set_gpio_output(AT91_PIN_PD8, 0); 845b15fd98SHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTD, 7, 1); 855b15fd98SHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTD, 8, 1); 865b15fd98SHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 12, 1); 875b15fd98SHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 13, 1); 885b15fd98SHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 15, 1); 895b15fd98SHeiko Schocher 905b15fd98SHeiko Schocher corvus_nand_hw_init(); 915b15fd98SHeiko Schocher 925b15fd98SHeiko Schocher /* Configure recovery button PINs */ 935b15fd98SHeiko Schocher at91_set_gpio_input(AT91_PIN_PB7, 1); 945b15fd98SHeiko Schocher 955b15fd98SHeiko Schocher /* check if button is pressed */ 965b15fd98SHeiko Schocher if (at91_get_gpio_value(AT91_PIN_PB7) == 0) { 975b15fd98SHeiko Schocher u32 boot_device; 985b15fd98SHeiko Schocher 995b15fd98SHeiko Schocher debug("Recovery button pressed\n"); 1005b15fd98SHeiko Schocher boot_device = spl_boot_device(); 1015b15fd98SHeiko Schocher switch (boot_device) { 1025b15fd98SHeiko Schocher #ifdef CONFIG_SPL_NAND_SUPPORT 1035b15fd98SHeiko Schocher case BOOT_DEVICE_NAND: 1045b15fd98SHeiko Schocher nand_init(); 1055b15fd98SHeiko Schocher spl_nand_erase_one(0, 0); 1065b15fd98SHeiko Schocher break; 1075b15fd98SHeiko Schocher #endif 1085b15fd98SHeiko Schocher } 1095b15fd98SHeiko Schocher } 1105b15fd98SHeiko Schocher } 1115b15fd98SHeiko Schocher 1125b15fd98SHeiko Schocher #include <asm/arch/atmel_mpddrc.h> 1135b15fd98SHeiko Schocher static void ddr2_conf(struct atmel_mpddr *ddr2) 1145b15fd98SHeiko Schocher { 1155b15fd98SHeiko Schocher ddr2->md = (ATMEL_MPDDRC_MD_DBW_16_BITS | ATMEL_MPDDRC_MD_DDR2_SDRAM); 1165b15fd98SHeiko Schocher 1175b15fd98SHeiko Schocher ddr2->cr = (ATMEL_MPDDRC_CR_NC_COL_10 | 1185b15fd98SHeiko Schocher ATMEL_MPDDRC_CR_NR_ROW_14 | 1195b15fd98SHeiko Schocher ATMEL_MPDDRC_CR_DIC_DS | 1205b15fd98SHeiko Schocher ATMEL_MPDDRC_CR_DQMS_SHARED | 1215b15fd98SHeiko Schocher ATMEL_MPDDRC_CR_CAS_DDR_CAS3); 1225b15fd98SHeiko Schocher ddr2->rtr = 0x24b; 1235b15fd98SHeiko Schocher 1245b15fd98SHeiko Schocher ddr2->tpr0 = (6 << ATMEL_MPDDRC_TPR0_TRAS_OFFSET |/* 6*7.5 = 45 ns */ 1255b15fd98SHeiko Schocher 2 << ATMEL_MPDDRC_TPR0_TRCD_OFFSET |/* 2*7.5 = 15 ns */ 1265b15fd98SHeiko Schocher 2 << ATMEL_MPDDRC_TPR0_TWR_OFFSET | /* 2*7.5 = 15 ns */ 1275b15fd98SHeiko Schocher 8 << ATMEL_MPDDRC_TPR0_TRC_OFFSET | /* 8*7.5 = 75 ns */ 1285b15fd98SHeiko Schocher 2 << ATMEL_MPDDRC_TPR0_TRP_OFFSET | /* 2*7.5 = 15 ns */ 1295b15fd98SHeiko Schocher 1 << ATMEL_MPDDRC_TPR0_TRRD_OFFSET | /* 1*7.5= 7.5 ns*/ 1305b15fd98SHeiko Schocher 1 << ATMEL_MPDDRC_TPR0_TWTR_OFFSET | /* 1 clk cycle */ 1315b15fd98SHeiko Schocher 2 << ATMEL_MPDDRC_TPR0_TMRD_OFFSET); /* 2 clk cycles */ 1325b15fd98SHeiko Schocher 1335b15fd98SHeiko Schocher ddr2->tpr1 = (2 << ATMEL_MPDDRC_TPR1_TXP_OFFSET | /* 2*7.5 = 15 ns */ 1345b15fd98SHeiko Schocher 200 << ATMEL_MPDDRC_TPR1_TXSRD_OFFSET | 1355b15fd98SHeiko Schocher 16 << ATMEL_MPDDRC_TPR1_TXSNR_OFFSET | 1365b15fd98SHeiko Schocher 14 << ATMEL_MPDDRC_TPR1_TRFC_OFFSET); 1375b15fd98SHeiko Schocher 1385b15fd98SHeiko Schocher ddr2->tpr2 = (1 << ATMEL_MPDDRC_TPR2_TRTP_OFFSET | 1395b15fd98SHeiko Schocher 0 << ATMEL_MPDDRC_TPR2_TRPA_OFFSET | 1405b15fd98SHeiko Schocher 7 << ATMEL_MPDDRC_TPR2_TXARDS_OFFSET | 1415b15fd98SHeiko Schocher 2 << ATMEL_MPDDRC_TPR2_TXARD_OFFSET); 1425b15fd98SHeiko Schocher } 1435b15fd98SHeiko Schocher 1445b15fd98SHeiko Schocher void mem_init(void) 1455b15fd98SHeiko Schocher { 1465b15fd98SHeiko Schocher struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC; 1475b15fd98SHeiko Schocher struct atmel_mpddr ddr2; 1485b15fd98SHeiko Schocher 1495b15fd98SHeiko Schocher ddr2_conf(&ddr2); 1505b15fd98SHeiko Schocher 1515b15fd98SHeiko Schocher /* enable DDR2 clock */ 152c982f6b9SErik van Luijk writel(AT91_PMC_DDR, &pmc->scer); 1535b15fd98SHeiko Schocher 1545b15fd98SHeiko Schocher /* DDRAM2 Controller initialize */ 1550c01c3e8SErik van Luijk ddr2_init(ATMEL_BASE_DDRSDRC0, ATMEL_BASE_CS6, &ddr2); 1565b15fd98SHeiko Schocher } 157b89ac72aSHeiko Schocher #endif 158b89ac72aSHeiko Schocher 159b89ac72aSHeiko Schocher #ifdef CONFIG_CMD_USB 160b89ac72aSHeiko Schocher static void taurus_usb_hw_init(void) 161b89ac72aSHeiko Schocher { 1625b15fd98SHeiko Schocher at91_periph_clk_enable(ATMEL_ID_PIODE); 163b89ac72aSHeiko Schocher 164b89ac72aSHeiko Schocher at91_set_gpio_output(AT91_PIN_PD1, 0); 165b89ac72aSHeiko Schocher at91_set_gpio_output(AT91_PIN_PD3, 0); 166b89ac72aSHeiko Schocher } 167b89ac72aSHeiko Schocher #endif 168b89ac72aSHeiko Schocher 169b89ac72aSHeiko Schocher #ifdef CONFIG_MACB 170b89ac72aSHeiko Schocher static void corvus_macb_hw_init(void) 171b89ac72aSHeiko Schocher { 172b89ac72aSHeiko Schocher /* Enable clock */ 1735b15fd98SHeiko Schocher at91_periph_clk_enable(ATMEL_ID_EMAC); 174b89ac72aSHeiko Schocher 175b89ac72aSHeiko Schocher /* 176b89ac72aSHeiko Schocher * Disable pull-up on: 177b89ac72aSHeiko Schocher * RXDV (PA15) => PHY normal mode (not Test mode) 178b89ac72aSHeiko Schocher * ERX0 (PA12) => PHY ADDR0 179b89ac72aSHeiko Schocher * ERX1 (PA13) => PHY ADDR1 => PHYADDR = 0x0 180b89ac72aSHeiko Schocher * 181b89ac72aSHeiko Schocher * PHY has internal pull-down 182b89ac72aSHeiko Schocher */ 183b89ac72aSHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 15, 0); 184b89ac72aSHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 12, 0); 185b89ac72aSHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 13, 0); 186b89ac72aSHeiko Schocher 187b89ac72aSHeiko Schocher at91_phy_reset(); 188b89ac72aSHeiko Schocher 189b89ac72aSHeiko Schocher /* Re-enable pull-up */ 190b89ac72aSHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 15, 1); 191b89ac72aSHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 12, 1); 192b89ac72aSHeiko Schocher at91_set_pio_pullup(AT91_PIO_PORTA, 13, 1); 193b89ac72aSHeiko Schocher 194b89ac72aSHeiko Schocher /* And the pins. */ 195b89ac72aSHeiko Schocher at91_macb_hw_init(); 196b89ac72aSHeiko Schocher } 197b89ac72aSHeiko Schocher #endif 198b89ac72aSHeiko Schocher 199b89ac72aSHeiko Schocher int board_early_init_f(void) 200b89ac72aSHeiko Schocher { 201b89ac72aSHeiko Schocher at91_seriald_hw_init(); 202b89ac72aSHeiko Schocher return 0; 203b89ac72aSHeiko Schocher } 204b89ac72aSHeiko Schocher 205b89ac72aSHeiko Schocher int board_init(void) 206b89ac72aSHeiko Schocher { 207b89ac72aSHeiko Schocher /* address of boot parameters */ 208b89ac72aSHeiko Schocher gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 209b89ac72aSHeiko Schocher 210b89ac72aSHeiko Schocher #ifdef CONFIG_CMD_NAND 211b89ac72aSHeiko Schocher corvus_nand_hw_init(); 212b89ac72aSHeiko Schocher #endif 213b89ac72aSHeiko Schocher #ifdef CONFIG_ATMEL_SPI 214b89ac72aSHeiko Schocher at91_spi0_hw_init(1 << 4); 215b89ac72aSHeiko Schocher #endif 216b89ac72aSHeiko Schocher #ifdef CONFIG_HAS_DATAFLASH 217b89ac72aSHeiko Schocher at91_spi0_hw_init(1 << 0); 218b89ac72aSHeiko Schocher #endif 219b89ac72aSHeiko Schocher #ifdef CONFIG_MACB 220b89ac72aSHeiko Schocher corvus_macb_hw_init(); 221b89ac72aSHeiko Schocher #endif 222b89ac72aSHeiko Schocher #ifdef CONFIG_CMD_USB 223b89ac72aSHeiko Schocher taurus_usb_hw_init(); 224b89ac72aSHeiko Schocher #endif 225b89ac72aSHeiko Schocher return 0; 226b89ac72aSHeiko Schocher } 227b89ac72aSHeiko Schocher 228b89ac72aSHeiko Schocher int dram_init(void) 229b89ac72aSHeiko Schocher { 230b89ac72aSHeiko Schocher gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, 231b89ac72aSHeiko Schocher CONFIG_SYS_SDRAM_SIZE); 232b89ac72aSHeiko Schocher return 0; 233b89ac72aSHeiko Schocher } 234b89ac72aSHeiko Schocher 235b89ac72aSHeiko Schocher int board_eth_init(bd_t *bis) 236b89ac72aSHeiko Schocher { 237b89ac72aSHeiko Schocher int rc = 0; 238b89ac72aSHeiko Schocher #ifdef CONFIG_MACB 239b89ac72aSHeiko Schocher rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00); 240b89ac72aSHeiko Schocher #endif 241b89ac72aSHeiko Schocher return rc; 242b89ac72aSHeiko Schocher } 243b89ac72aSHeiko Schocher 244b89ac72aSHeiko Schocher /* SPI chip select control */ 245b89ac72aSHeiko Schocher int spi_cs_is_valid(unsigned int bus, unsigned int cs) 246b89ac72aSHeiko Schocher { 247b89ac72aSHeiko Schocher return bus == 0 && cs < 2; 248b89ac72aSHeiko Schocher } 249b89ac72aSHeiko Schocher 250b89ac72aSHeiko Schocher void spi_cs_activate(struct spi_slave *slave) 251b89ac72aSHeiko Schocher { 252b89ac72aSHeiko Schocher switch (slave->cs) { 253b89ac72aSHeiko Schocher case 1: 254b89ac72aSHeiko Schocher at91_set_gpio_output(AT91_PIN_PB18, 0); 255b89ac72aSHeiko Schocher break; 256b89ac72aSHeiko Schocher case 0: 257b89ac72aSHeiko Schocher default: 258b89ac72aSHeiko Schocher at91_set_gpio_output(AT91_PIN_PB3, 0); 259b89ac72aSHeiko Schocher break; 260b89ac72aSHeiko Schocher } 261b89ac72aSHeiko Schocher } 262b89ac72aSHeiko Schocher 263b89ac72aSHeiko Schocher void spi_cs_deactivate(struct spi_slave *slave) 264b89ac72aSHeiko Schocher { 265b89ac72aSHeiko Schocher switch (slave->cs) { 266b89ac72aSHeiko Schocher case 1: 267b89ac72aSHeiko Schocher at91_set_gpio_output(AT91_PIN_PB18, 1); 268b89ac72aSHeiko Schocher break; 269b89ac72aSHeiko Schocher case 0: 270b89ac72aSHeiko Schocher default: 271b89ac72aSHeiko Schocher at91_set_gpio_output(AT91_PIN_PB3, 1); 272b89ac72aSHeiko Schocher break; 273b89ac72aSHeiko Schocher } 274b89ac72aSHeiko Schocher } 275