1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2012 Atmel Corporation
4  */
5 
6 #include <common.h>
7 #include <asm/arch/at91_common.h>
8 #include <asm/arch/clk.h>
9 #include <asm/arch/gpio.h>
10 #include <asm/io.h>
11 
12 unsigned int get_chip_id(void)
13 {
14 	/* The 0x40 is the offset of cidr in DBGU */
15 	return readl(ATMEL_BASE_DBGU + 0x40) & ~ARCH_ID_VERSION_MASK;
16 }
17 
18 unsigned int get_extension_chip_id(void)
19 {
20 	/* The 0x44 is the offset of exid in DBGU */
21 	return readl(ATMEL_BASE_DBGU + 0x44);
22 }
23 
24 unsigned int has_emac1()
25 {
26 	return cpu_is_at91sam9x25();
27 }
28 
29 unsigned int has_emac0()
30 {
31 	return !(cpu_is_at91sam9g15());
32 }
33 
34 unsigned int has_lcdc()
35 {
36 	return cpu_is_at91sam9g15() || cpu_is_at91sam9g35()
37 		|| cpu_is_at91sam9x35();
38 }
39 
40 char *get_cpu_name()
41 {
42 	unsigned int extension_id = get_extension_chip_id();
43 
44 	if (cpu_is_at91sam9x5()) {
45 		switch (extension_id) {
46 		case ARCH_EXID_AT91SAM9G15:
47 			return "AT91SAM9G15";
48 		case ARCH_EXID_AT91SAM9G25:
49 			return "AT91SAM9G25";
50 		case ARCH_EXID_AT91SAM9G35:
51 			return "AT91SAM9G35";
52 		case ARCH_EXID_AT91SAM9X25:
53 			return "AT91SAM9X25";
54 		case ARCH_EXID_AT91SAM9X35:
55 			return "AT91SAM9X35";
56 		default:
57 			return "Unknown CPU type";
58 		}
59 	} else {
60 		return "Unknown CPU type";
61 	}
62 }
63 
64 void at91_seriald_hw_init(void)
65 {
66 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 9, 0);	/* DRXD */
67 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 10, 1);	/* DTXD */
68 
69 	at91_periph_clk_enable(ATMEL_ID_SYS);
70 }
71 
72 void at91_serial0_hw_init(void)
73 {
74 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 0, 1);	/* TXD */
75 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 1, 0);	/* RXD */
76 
77 	at91_periph_clk_enable(ATMEL_ID_USART0);
78 }
79 
80 void at91_serial1_hw_init(void)
81 {
82 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 5, 1);	/* TXD */
83 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 6, 0);	/* RXD */
84 
85 	at91_periph_clk_enable(ATMEL_ID_USART1);
86 }
87 
88 void at91_serial2_hw_init(void)
89 {
90 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 7, 1);	/* TXD */
91 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 8, 0);	/* RXD */
92 
93 	at91_periph_clk_enable(ATMEL_ID_USART2);
94 }
95 
96 void at91_mci_hw_init(void)
97 {
98 	/* Initialize the MCI0 */
99 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 17, 1);	/* MCCK */
100 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 16, 1);	/* MCCDA */
101 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 15, 1);	/* MCDA0 */
102 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 18, 1);	/* MCDA1 */
103 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 19, 1);	/* MCDA2 */
104 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 20, 1);	/* MCDA3 */
105 
106 	at91_periph_clk_enable(ATMEL_ID_HSMCI0);
107 }
108 
109 #ifdef CONFIG_ATMEL_SPI
110 void at91_spi0_hw_init(unsigned long cs_mask)
111 {
112 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 11, 0);	/* SPI0_MISO */
113 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 12, 0);	/* SPI0_MOSI */
114 	at91_pio3_set_a_periph(AT91_PIO_PORTA, 13, 0);	/* SPI0_SPCK */
115 
116 	at91_periph_clk_enable(ATMEL_ID_SPI0);
117 
118 	if (cs_mask & (1 << 0))
119 		at91_pio3_set_a_periph(AT91_PIO_PORTA, 14, 0);
120 	if (cs_mask & (1 << 1))
121 		at91_pio3_set_b_periph(AT91_PIO_PORTA, 7, 0);
122 	if (cs_mask & (1 << 2))
123 		at91_pio3_set_b_periph(AT91_PIO_PORTA, 1, 0);
124 	if (cs_mask & (1 << 3))
125 		at91_pio3_set_b_periph(AT91_PIO_PORTB, 3, 0);
126 	if (cs_mask & (1 << 4))
127 		at91_set_pio_output(AT91_PIO_PORTA, 14, 0);
128 	if (cs_mask & (1 << 5))
129 		at91_set_pio_output(AT91_PIO_PORTA, 7, 0);
130 	if (cs_mask & (1 << 6))
131 		at91_set_pio_output(AT91_PIO_PORTA, 1, 0);
132 	if (cs_mask & (1 << 7))
133 		at91_set_pio_output(AT91_PIO_PORTB, 3, 0);
134 }
135 
136 void at91_spi1_hw_init(unsigned long cs_mask)
137 {
138 	at91_pio3_set_b_periph(AT91_PIO_PORTA, 21, 0);	/* SPI1_MISO */
139 	at91_pio3_set_b_periph(AT91_PIO_PORTA, 22, 0);	/* SPI1_MOSI */
140 	at91_pio3_set_b_periph(AT91_PIO_PORTA, 23, 0);	/* SPI1_SPCK */
141 
142 	at91_periph_clk_enable(ATMEL_ID_SPI1);
143 
144 	if (cs_mask & (1 << 0))
145 		at91_pio3_set_b_periph(AT91_PIO_PORTA, 8, 0);
146 	if (cs_mask & (1 << 1))
147 		at91_pio3_set_b_periph(AT91_PIO_PORTA, 0, 0);
148 	if (cs_mask & (1 << 2))
149 		at91_pio3_set_b_periph(AT91_PIO_PORTA, 31, 0);
150 	if (cs_mask & (1 << 3))
151 		at91_pio3_set_b_periph(AT91_PIO_PORTA, 30, 0);
152 	if (cs_mask & (1 << 4))
153 		at91_set_pio_output(AT91_PIO_PORTA, 8, 0);
154 	if (cs_mask & (1 << 5))
155 		at91_set_pio_output(AT91_PIO_PORTA, 0, 0);
156 	if (cs_mask & (1 << 6))
157 		at91_set_pio_output(AT91_PIO_PORTA, 31, 0);
158 	if (cs_mask & (1 << 7))
159 		at91_set_pio_output(AT91_PIO_PORTA, 30, 0);
160 }
161 #endif
162 
163 #if defined(CONFIG_USB_OHCI_NEW) || defined(CONFIG_USB_EHCI_HCD)
164 void at91_uhp_hw_init(void)
165 {
166 	/* Enable VBus on UHP ports */
167 	at91_set_pio_output(AT91_PIO_PORTD, 18, 0); /* port A */
168 	at91_set_pio_output(AT91_PIO_PORTD, 19, 0); /* port B */
169 #if defined(CONFIG_USB_OHCI_NEW)
170 	/* port C is OHCI only */
171 	at91_set_pio_output(AT91_PIO_PORTD, 20, 0); /* port C */
172 #endif
173 }
174 #endif
175 
176 #ifdef CONFIG_MACB
177 void at91_macb_hw_init(void)
178 {
179 	if (has_emac0()) {
180 		/* Enable EMAC0 clock */
181 		at91_periph_clk_enable(ATMEL_ID_EMAC0);
182 		/* EMAC0 pins setup */
183 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 4, 0);	/* ETXCK */
184 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 3, 0);	/* ERXDV */
185 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 0, 0);	/* ERX0 */
186 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 1, 0);	/* ERX1 */
187 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 2, 0);	/* ERXER */
188 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 7, 0);	/* ETXEN */
189 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 9, 0);	/* ETX0 */
190 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 10, 0);	/* ETX1 */
191 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 5, 0);	/* EMDIO */
192 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 6, 0);	/* EMDC */
193 	}
194 
195 	if (has_emac1()) {
196 		/* Enable EMAC1 clock */
197 		at91_periph_clk_enable(ATMEL_ID_EMAC1);
198 		/* EMAC1 pins setup */
199 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 29, 0);	/* ETXCK */
200 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 28, 0);	/* ECRSDV */
201 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 20, 0);	/* ERXO */
202 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 21, 0);	/* ERX1 */
203 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 16, 0);	/* ERXER */
204 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 27, 0);	/* ETXEN */
205 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 18, 0);	/* ETX0 */
206 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 19, 0);	/* ETX1 */
207 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 31, 0);	/* EMDIO */
208 		at91_pio3_set_b_periph(AT91_PIO_PORTC, 30, 0);	/* EMDC */
209 	}
210 
211 #ifndef CONFIG_RMII
212 	/* Only emac0 support MII */
213 	if (has_emac0()) {
214 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 16, 0);	/* ECRS */
215 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 17, 0);	/* ECOL */
216 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 13, 0);	/* ERX2 */
217 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 14, 0);	/* ERX3 */
218 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 15, 0);	/* ERXCK */
219 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 11, 0);	/* ETX2 */
220 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 12, 0);	/* ETX3 */
221 		at91_pio3_set_a_periph(AT91_PIO_PORTB, 8, 0);	/* ETXER */
222 	}
223 #endif
224 }
225 #endif
226