1 /*
2  * (C) Copyright 2007-2008
3  * Stelian Pop <stelian@popies.net>
4  * Lead Tech Design <www.leadtechdesign.com>
5  *
6  * (C) Copyright 2009-2011
7  * Daniel Gorsulowski <daniel.gorsulowski@esd.eu>
8  * esd electronic system design gmbh <www.esd.eu>
9  *
10  * SPDX-License-Identifier:	GPL-2.0+
11  */
12 
13 #include <common.h>
14 #include <asm/io.h>
15 #include <asm/arch/at91_common.h>
16 #include <asm/arch/clk.h>
17 #include <asm/arch/gpio.h>
18 
19 /*
20  * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all
21  * peripheral pins. Good to have if hardware is soldered optionally
22  * or in case of SPI no slave is selected. Avoid lines to float
23  * needlessly. Use a short local PUP define.
24  *
25  * Due to errata "TXD floats when CTS is inactive" pullups are always
26  * on for TXD pins.
27  */
28 #ifdef CONFIG_AT91_GPIO_PULLUP
29 # define PUP CONFIG_AT91_GPIO_PULLUP
30 #else
31 # define PUP 0
32 #endif
33 
34 void at91_serial0_hw_init(void)
35 {
36 	at91_set_a_periph(AT91_PIO_PORTA, 26, 1);		/* TXD0 */
37 	at91_set_a_periph(AT91_PIO_PORTA, 27, PUP);		/* RXD0 */
38 	at91_periph_clk_enable(ATMEL_ID_USART0);
39 }
40 
41 void at91_serial1_hw_init(void)
42 {
43 	at91_set_a_periph(AT91_PIO_PORTD, 0, 1);		/* TXD1 */
44 	at91_set_a_periph(AT91_PIO_PORTD, 1, PUP);		/* RXD1 */
45 	at91_periph_clk_enable(ATMEL_ID_USART1);
46 }
47 
48 void at91_serial2_hw_init(void)
49 {
50 	at91_set_a_periph(AT91_PIO_PORTD, 2, 1);		/* TXD2 */
51 	at91_set_a_periph(AT91_PIO_PORTD, 3, PUP);		/* RXD2 */
52 	at91_periph_clk_enable(ATMEL_ID_USART2);
53 }
54 
55 void at91_seriald_hw_init(void)
56 {
57 	at91_set_a_periph(AT91_PIO_PORTC, 30, PUP);		/* DRXD */
58 	at91_set_a_periph(AT91_PIO_PORTC, 31, 1);		/* DTXD */
59 	at91_periph_clk_enable(ATMEL_ID_SYS);
60 }
61 
62 #ifdef CONFIG_ATMEL_SPI
63 void at91_spi0_hw_init(unsigned long cs_mask)
64 {
65 	at91_set_b_periph(AT91_PIO_PORTA, 0, PUP);	/* SPI0_MISO */
66 	at91_set_b_periph(AT91_PIO_PORTA, 1, PUP);	/* SPI0_MOSI */
67 	at91_set_b_periph(AT91_PIO_PORTA, 2, PUP);	/* SPI0_SPCK */
68 
69 	at91_periph_clk_enable(ATMEL_ID_SPI0);
70 
71 	if (cs_mask & (1 << 0)) {
72 		at91_set_b_periph(AT91_PIO_PORTA, 5, 1);
73 	}
74 	if (cs_mask & (1 << 1)) {
75 		at91_set_b_periph(AT91_PIO_PORTA, 3, 1);
76 	}
77 	if (cs_mask & (1 << 2)) {
78 		at91_set_b_periph(AT91_PIO_PORTA, 4, 1);
79 	}
80 	if (cs_mask & (1 << 3)) {
81 		at91_set_b_periph(AT91_PIO_PORTB, 11, 1);
82 	}
83 	if (cs_mask & (1 << 4)) {
84 		at91_set_pio_output(AT91_PIO_PORTA, 5, 1);
85 	}
86 	if (cs_mask & (1 << 5)) {
87 		at91_set_pio_output(AT91_PIO_PORTA, 3, 1);
88 	}
89 	if (cs_mask & (1 << 6)) {
90 		at91_set_pio_output(AT91_PIO_PORTA, 4, 1);
91 	}
92 	if (cs_mask & (1 << 7)) {
93 		at91_set_pio_output(AT91_PIO_PORTB, 11, 1);
94 	}
95 }
96 
97 void at91_spi1_hw_init(unsigned long cs_mask)
98 {
99 	at91_set_a_periph(AT91_PIO_PORTB, 12, PUP);	/* SPI1_MISO */
100 	at91_set_a_periph(AT91_PIO_PORTB, 13, PUP);	/* SPI1_MOSI */
101 	at91_set_a_periph(AT91_PIO_PORTB, 14, PUP);	/* SPI1_SPCK */
102 
103 	at91_periph_clk_enable(ATMEL_ID_SPI1);
104 
105 	if (cs_mask & (1 << 0)) {
106 		at91_set_a_periph(AT91_PIO_PORTB, 15, 1);
107 	}
108 	if (cs_mask & (1 << 1)) {
109 		at91_set_a_periph(AT91_PIO_PORTB, 16, 1);
110 	}
111 	if (cs_mask & (1 << 2)) {
112 		at91_set_a_periph(AT91_PIO_PORTB, 17, 1);
113 	}
114 	if (cs_mask & (1 << 3)) {
115 		at91_set_a_periph(AT91_PIO_PORTB, 18, 1);
116 	}
117 	if (cs_mask & (1 << 4)) {
118 		at91_set_pio_output(AT91_PIO_PORTB, 15, 1);
119 	}
120 	if (cs_mask & (1 << 5)) {
121 		at91_set_pio_output(AT91_PIO_PORTB, 16, 1);
122 	}
123 	if (cs_mask & (1 << 6)) {
124 		at91_set_pio_output(AT91_PIO_PORTB, 17, 1);
125 	}
126 	if (cs_mask & (1 << 7)) {
127 		at91_set_pio_output(AT91_PIO_PORTB, 18, 1);
128 	}
129 }
130 #endif
131 
132 #if defined(CONFIG_GENERIC_ATMEL_MCI)
133 void at91_mci_hw_init(void)
134 {
135 	at91_periph_clk_enable(ATMEL_ID_MCI1);
136 
137 	at91_set_a_periph(AT91_PIO_PORTA, 6, PUP);	/* MCI1_CK */
138 
139 #if defined(CONFIG_ATMEL_MCI_PORTB)
140 	at91_set_a_periph(AT91_PIO_PORTA, 21, PUP);	/* MCI1_CDB */
141 	at91_set_a_periph(AT91_PIO_PORTA, 22, PUP);	/* MCI1_DB0 */
142 	at91_set_a_periph(AT91_PIO_PORTA, 23, PUP);	/* MCI1_DB1 */
143 	at91_set_a_periph(AT91_PIO_PORTA, 24, PUP);	/* MCI1_DB2 */
144 	at91_set_a_periph(AT91_PIO_PORTA, 25, PUP);	/* MCI1_DB3 */
145 #else
146 	at91_set_a_periph(AT91_PIO_PORTA, 7, PUP);	/* MCI1_CDA */
147 	at91_set_a_periph(AT91_PIO_PORTA, 8, PUP);	/* MCI1_DA0 */
148 	at91_set_a_periph(AT91_PIO_PORTA, 9, PUP);	/* MCI1_DA1 */
149 	at91_set_a_periph(AT91_PIO_PORTA, 10, PUP);	/* MCI1_DA2 */
150 	at91_set_a_periph(AT91_PIO_PORTA, 11, PUP);	/* MCI1_DA3 */
151 #endif
152 }
153 #endif
154 
155 #ifdef CONFIG_MACB
156 void at91_macb_hw_init(void)
157 {
158 	at91_set_a_periph(AT91_PIO_PORTE, 21, 0);	/* ETXCK_EREFCK */
159 	at91_set_b_periph(AT91_PIO_PORTC, 25, 0);	/* ERXDV */
160 	at91_set_a_periph(AT91_PIO_PORTE, 25, 0);	/* ERX0 */
161 	at91_set_a_periph(AT91_PIO_PORTE, 26, 0);	/* ERX1 */
162 	at91_set_a_periph(AT91_PIO_PORTE, 27, 0);	/* ERXER */
163 	at91_set_a_periph(AT91_PIO_PORTE, 28, 0);	/* ETXEN */
164 	at91_set_a_periph(AT91_PIO_PORTE, 23, 0);	/* ETX0 */
165 	at91_set_a_periph(AT91_PIO_PORTE, 24, 0);	/* ETX1 */
166 	at91_set_a_periph(AT91_PIO_PORTE, 30, 0);	/* EMDIO */
167 	at91_set_a_periph(AT91_PIO_PORTE, 29, 0);	/* EMDC */
168 
169 #ifndef CONFIG_RMII
170 	at91_set_a_periph(AT91_PIO_PORTE, 22, 0);	/* ECRS */
171 	at91_set_b_periph(AT91_PIO_PORTC, 26, 0);	/* ECOL */
172 	at91_set_b_periph(AT91_PIO_PORTC, 22, 0);	/* ERX2 */
173 	at91_set_b_periph(AT91_PIO_PORTC, 23, 0);	/* ERX3 */
174 	at91_set_b_periph(AT91_PIO_PORTC, 27, 0);	/* ERXCK */
175 	at91_set_b_periph(AT91_PIO_PORTC, 20, 0);	/* ETX2 */
176 	at91_set_b_periph(AT91_PIO_PORTC, 21, 0);	/* ETX3 */
177 	at91_set_b_periph(AT91_PIO_PORTC, 24, 0);	/* ETXER */
178 #endif
179 }
180 #endif
181 
182 #ifdef CONFIG_USB_OHCI_NEW
183 void at91_uhp_hw_init(void)
184 {
185 	/* Enable VBus on UHP ports */
186 	at91_set_pio_output(AT91_PIO_PORTA, 21, 0);
187 	at91_set_pio_output(AT91_PIO_PORTA, 24, 0);
188 }
189 #endif
190 
191 #ifdef CONFIG_AT91_CAN
192 void at91_can_hw_init(void)
193 {
194 	at91_set_a_periph(AT91_PIO_PORTA, 13, 0);	/* CAN_TX */
195 	at91_set_a_periph(AT91_PIO_PORTA, 14, 1);	/* CAN_RX */
196 
197 	at91_periph_clk_enable(ATMEL_ID_CAN);
198 }
199 #endif
200