1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2007-2008 4 * Stelian Pop <stelian@popies.net> 5 * Lead Tech Design <www.leadtechdesign.com> 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <asm/io.h> 11 #include <asm/arch/at91sam9260_matrix.h> 12 #include <asm/arch/at91_common.h> 13 #include <asm/arch/at91sam9_sdramc.h> 14 #include <asm/arch/clk.h> 15 #include <asm/arch/gpio.h> 16 17 /* 18 * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all 19 * peripheral pins. Good to have if hardware is soldered optionally 20 * or in case of SPI no slave is selected. Avoid lines to float 21 * needlessly. Use a short local PUP define. 22 * 23 * Due to errata "TXD floats when CTS is inactive" pullups are always 24 * on for TXD pins. 25 */ 26 #ifdef CONFIG_AT91_GPIO_PULLUP 27 # define PUP CONFIG_AT91_GPIO_PULLUP 28 #else 29 # define PUP 0 30 #endif 31 32 void at91_serial0_hw_init(void) 33 { 34 at91_set_a_periph(AT91_PIO_PORTB, 4, 1); /* TXD0 */ 35 at91_set_a_periph(AT91_PIO_PORTB, 5, PUP); /* RXD0 */ 36 at91_periph_clk_enable(ATMEL_ID_USART0); 37 } 38 39 void at91_serial1_hw_init(void) 40 { 41 at91_set_a_periph(AT91_PIO_PORTB, 6, 1); /* TXD1 */ 42 at91_set_a_periph(AT91_PIO_PORTB, 7, PUP); /* RXD1 */ 43 at91_periph_clk_enable(ATMEL_ID_USART1); 44 } 45 46 void at91_serial2_hw_init(void) 47 { 48 at91_set_a_periph(AT91_PIO_PORTB, 8, 1); /* TXD2 */ 49 at91_set_a_periph(AT91_PIO_PORTB, 9, PUP); /* RXD2 */ 50 at91_periph_clk_enable(ATMEL_ID_USART2); 51 } 52 53 void at91_seriald_hw_init(void) 54 { 55 at91_set_a_periph(AT91_PIO_PORTB, 14, PUP); /* DRXD */ 56 at91_set_a_periph(AT91_PIO_PORTB, 15, 1); /* DTXD */ 57 at91_periph_clk_enable(ATMEL_ID_SYS); 58 } 59 60 #ifdef CONFIG_ATMEL_SPI 61 void at91_spi0_hw_init(unsigned long cs_mask) 62 { 63 at91_set_a_periph(AT91_PIO_PORTA, 0, PUP); /* SPI0_MISO */ 64 at91_set_a_periph(AT91_PIO_PORTA, 1, PUP); /* SPI0_MOSI */ 65 at91_set_a_periph(AT91_PIO_PORTA, 2, PUP); /* SPI0_SPCK */ 66 67 at91_periph_clk_enable(ATMEL_ID_SPI0); 68 69 if (cs_mask & (1 << 0)) { 70 at91_set_a_periph(AT91_PIO_PORTA, 3, 1); 71 } 72 if (cs_mask & (1 << 1)) { 73 at91_set_b_periph(AT91_PIO_PORTC, 11, 1); 74 } 75 if (cs_mask & (1 << 2)) { 76 at91_set_b_periph(AT91_PIO_PORTC, 16, 1); 77 } 78 if (cs_mask & (1 << 3)) { 79 at91_set_b_periph(AT91_PIO_PORTC, 17, 1); 80 } 81 if (cs_mask & (1 << 4)) { 82 at91_set_pio_output(AT91_PIO_PORTA, 3, 1); 83 } 84 if (cs_mask & (1 << 5)) { 85 at91_set_pio_output(AT91_PIO_PORTC, 11, 1); 86 } 87 if (cs_mask & (1 << 6)) { 88 at91_set_pio_output(AT91_PIO_PORTC, 16, 1); 89 } 90 if (cs_mask & (1 << 7)) { 91 at91_set_pio_output(AT91_PIO_PORTC, 17, 1); 92 } 93 } 94 95 void at91_spi1_hw_init(unsigned long cs_mask) 96 { 97 at91_set_a_periph(AT91_PIO_PORTB, 0, PUP); /* SPI1_MISO */ 98 at91_set_a_periph(AT91_PIO_PORTB, 1, PUP); /* SPI1_MOSI */ 99 at91_set_a_periph(AT91_PIO_PORTB, 2, PUP); /* SPI1_SPCK */ 100 101 at91_periph_clk_enable(ATMEL_ID_SPI1); 102 103 if (cs_mask & (1 << 0)) { 104 at91_set_a_periph(AT91_PIO_PORTB, 3, 1); 105 } 106 if (cs_mask & (1 << 1)) { 107 at91_set_b_periph(AT91_PIO_PORTC, 5, 1); 108 } 109 if (cs_mask & (1 << 2)) { 110 at91_set_b_periph(AT91_PIO_PORTC, 4, 1); 111 } 112 if (cs_mask & (1 << 3)) { 113 at91_set_b_periph(AT91_PIO_PORTC, 3, 1); 114 } 115 if (cs_mask & (1 << 4)) { 116 at91_set_pio_output(AT91_PIO_PORTB, 3, 1); 117 } 118 if (cs_mask & (1 << 5)) { 119 at91_set_pio_output(AT91_PIO_PORTC, 5, 1); 120 } 121 if (cs_mask & (1 << 6)) { 122 at91_set_pio_output(AT91_PIO_PORTC, 4, 1); 123 } 124 if (cs_mask & (1 << 7)) { 125 at91_set_pio_output(AT91_PIO_PORTC, 3, 1); 126 } 127 } 128 #endif 129 130 #ifdef CONFIG_MACB 131 void at91_macb_hw_init(void) 132 { 133 at91_periph_clk_enable(ATMEL_ID_EMAC0); 134 135 at91_set_a_periph(AT91_PIO_PORTA, 19, 0); /* ETXCK_EREFCK */ 136 at91_set_a_periph(AT91_PIO_PORTA, 17, 0); /* ERXDV */ 137 at91_set_a_periph(AT91_PIO_PORTA, 14, 0); /* ERX0 */ 138 at91_set_a_periph(AT91_PIO_PORTA, 15, 0); /* ERX1 */ 139 at91_set_a_periph(AT91_PIO_PORTA, 18, 0); /* ERXER */ 140 at91_set_a_periph(AT91_PIO_PORTA, 16, 0); /* ETXEN */ 141 at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* ETX0 */ 142 at91_set_a_periph(AT91_PIO_PORTA, 13, 0); /* ETX1 */ 143 at91_set_a_periph(AT91_PIO_PORTA, 21, 0); /* EMDIO */ 144 at91_set_a_periph(AT91_PIO_PORTA, 20, 0); /* EMDC */ 145 146 #ifndef CONFIG_RMII 147 at91_set_b_periph(AT91_PIO_PORTA, 28, 0); /* ECRS */ 148 at91_set_b_periph(AT91_PIO_PORTA, 29, 0); /* ECOL */ 149 at91_set_b_periph(AT91_PIO_PORTA, 25, 0); /* ERX2 */ 150 at91_set_b_periph(AT91_PIO_PORTA, 26, 0); /* ERX3 */ 151 at91_set_b_periph(AT91_PIO_PORTA, 27, 0); /* ERXCK */ 152 #if defined(CONFIG_AT91SAM9260EK) 153 /* 154 * use PA10, PA11 for ETX2, ETX3. 155 * PA23 and PA24 are for TWI EEPROM 156 */ 157 at91_set_b_periph(AT91_PIO_PORTA, 10, 0); /* ETX2 */ 158 at91_set_b_periph(AT91_PIO_PORTA, 11, 0); /* ETX3 */ 159 #else 160 at91_set_b_periph(AT91_PIO_PORTA, 23, 0); /* ETX2 */ 161 at91_set_b_periph(AT91_PIO_PORTA, 24, 0); /* ETX3 */ 162 #if defined(CONFIG_AT91SAM9G20) 163 /* 9G20 BOOT ROM initializes those pins to multi-drive, undo that */ 164 at91_set_pio_multi_drive(AT91_PIO_PORTA, 23, 0); 165 at91_set_pio_multi_drive(AT91_PIO_PORTA, 24, 0); 166 #endif 167 #endif 168 at91_set_b_periph(AT91_PIO_PORTA, 22, 0); /* ETXER */ 169 #endif 170 } 171 #endif 172 173 #if defined(CONFIG_GENERIC_ATMEL_MCI) 174 void at91_mci_hw_init(void) 175 { 176 at91_periph_clk_enable(ATMEL_ID_MCI); 177 178 at91_set_a_periph(AT91_PIO_PORTA, 8, 1); /* MCCK */ 179 #if defined(CONFIG_ATMEL_MCI_PORTB) 180 at91_set_b_periph(AT91_PIO_PORTA, 1, 1); /* MCCDB */ 181 at91_set_b_periph(AT91_PIO_PORTA, 0, 1); /* MCDB0 */ 182 at91_set_b_periph(AT91_PIO_PORTA, 5, 1); /* MCDB1 */ 183 at91_set_b_periph(AT91_PIO_PORTA, 4, 1); /* MCDB2 */ 184 at91_set_b_periph(AT91_PIO_PORTA, 3, 1); /* MCDB3 */ 185 #else 186 at91_set_a_periph(AT91_PIO_PORTA, 7, 1); /* MCCDA */ 187 at91_set_a_periph(AT91_PIO_PORTA, 6, 1); /* MCDA0 */ 188 at91_set_a_periph(AT91_PIO_PORTA, 9, 1); /* MCDA1 */ 189 at91_set_a_periph(AT91_PIO_PORTA, 10, 1); /* MCDA2 */ 190 at91_set_a_periph(AT91_PIO_PORTA, 11, 1); /* MCDA3 */ 191 #endif 192 } 193 #endif 194 195 void at91_sdram_hw_init(void) 196 { 197 at91_set_a_periph(AT91_PIO_PORTC, 16, 0); 198 at91_set_a_periph(AT91_PIO_PORTC, 17, 0); 199 at91_set_a_periph(AT91_PIO_PORTC, 18, 0); 200 at91_set_a_periph(AT91_PIO_PORTC, 19, 0); 201 at91_set_a_periph(AT91_PIO_PORTC, 20, 0); 202 at91_set_a_periph(AT91_PIO_PORTC, 21, 0); 203 at91_set_a_periph(AT91_PIO_PORTC, 22, 0); 204 at91_set_a_periph(AT91_PIO_PORTC, 23, 0); 205 at91_set_a_periph(AT91_PIO_PORTC, 24, 0); 206 at91_set_a_periph(AT91_PIO_PORTC, 25, 0); 207 at91_set_a_periph(AT91_PIO_PORTC, 26, 0); 208 at91_set_a_periph(AT91_PIO_PORTC, 27, 0); 209 at91_set_a_periph(AT91_PIO_PORTC, 28, 0); 210 at91_set_a_periph(AT91_PIO_PORTC, 29, 0); 211 at91_set_a_periph(AT91_PIO_PORTC, 30, 0); 212 at91_set_a_periph(AT91_PIO_PORTC, 31, 0); 213 } 214 215 /* Platform data for the GPIOs */ 216 static const struct at91_port_platdata at91sam9260_plat[] = { 217 { ATMEL_BASE_PIOA, "PA" }, 218 { ATMEL_BASE_PIOB, "PB" }, 219 { ATMEL_BASE_PIOC, "PC" }, 220 }; 221 222 U_BOOT_DEVICES(at91sam9260_gpios) = { 223 { "gpio_at91", &at91sam9260_plat[0] }, 224 { "gpio_at91", &at91sam9260_plat[1] }, 225 { "gpio_at91", &at91sam9260_plat[2] }, 226 }; 227