1 /*
2  * Copyright (C) 2012-2013 Atmel Corporation
3  * Bo Shen <voice.shen@atmel.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <asm/arch/sama5d3.h>
10 #include <asm/arch/at91_common.h>
11 #include <asm/arch/at91_pmc.h>
12 #include <asm/arch/clk.h>
13 #include <asm/arch/gpio.h>
14 #include <asm/io.h>
15 
16 unsigned int has_emac()
17 {
18 	return cpu_is_sama5d31() || cpu_is_sama5d35() || cpu_is_sama5d36();
19 }
20 
21 unsigned int has_gmac()
22 {
23 	return !cpu_is_sama5d31();
24 }
25 
26 unsigned int has_lcdc()
27 {
28 	return !cpu_is_sama5d35();
29 }
30 
31 char *get_cpu_name()
32 {
33 	unsigned int extension_id = get_extension_chip_id();
34 
35 	if (cpu_is_sama5d3())
36 		switch (extension_id) {
37 		case ARCH_EXID_SAMA5D31:
38 			return "SAMA5D31";
39 		case ARCH_EXID_SAMA5D33:
40 			return "SAMA5D33";
41 		case ARCH_EXID_SAMA5D34:
42 			return "SAMA5D34";
43 		case ARCH_EXID_SAMA5D35:
44 			return "SAMA5D35";
45 		case ARCH_EXID_SAMA5D36:
46 			return "SAMA5D36";
47 		default:
48 			return "Unknown CPU type";
49 		}
50 	else
51 		return "Unknown CPU type";
52 }
53 
54 void at91_serial0_hw_init(void)
55 {
56 	at91_set_a_periph(AT91_PIO_PORTD, 18, 1);	/* TXD0 */
57 	at91_set_a_periph(AT91_PIO_PORTD, 17, 0);	/* RXD0 */
58 
59 	/* Enable clock */
60 	at91_periph_clk_enable(ATMEL_ID_USART0);
61 }
62 
63 void at91_serial1_hw_init(void)
64 {
65 	at91_set_a_periph(AT91_PIO_PORTB, 29, 1);	/* TXD1 */
66 	at91_set_a_periph(AT91_PIO_PORTB, 28, 0);	/* RXD1 */
67 
68 	/* Enable clock */
69 	at91_periph_clk_enable(ATMEL_ID_USART1);
70 }
71 
72 void at91_serial2_hw_init(void)
73 {
74 	at91_set_b_periph(AT91_PIO_PORTE, 26, 1);	/* TXD2 */
75 	at91_set_b_periph(AT91_PIO_PORTE, 25, 0);	/* RXD2 */
76 
77 	/* Enable clock */
78 	at91_periph_clk_enable(ATMEL_ID_USART2);
79 }
80 
81 void at91_seriald_hw_init(void)
82 {
83 	at91_set_a_periph(AT91_PIO_PORTB, 31, 1);	/* DTXD */
84 	at91_set_a_periph(AT91_PIO_PORTB, 30, 0);	/* DRXD */
85 
86 	/* Enable clock */
87 	at91_periph_clk_enable(ATMEL_ID_DBGU);
88 }
89 
90 #if defined(CONFIG_ATMEL_SPI)
91 void at91_spi0_hw_init(unsigned long cs_mask)
92 {
93 	at91_set_a_periph(AT91_PIO_PORTD, 10, 0);       /* SPI0_MISO */
94 	at91_set_a_periph(AT91_PIO_PORTD, 11, 0);       /* SPI0_MOSI */
95 	at91_set_a_periph(AT91_PIO_PORTD, 12, 0);       /* SPI0_SPCK */
96 
97 	if (cs_mask & (1 << 0))
98 		at91_set_pio_output(AT91_PIO_PORTD, 13, 1);
99 	if (cs_mask & (1 << 1))
100 		at91_set_pio_output(AT91_PIO_PORTD, 14, 1);
101 	if (cs_mask & (1 << 2))
102 		at91_set_pio_output(AT91_PIO_PORTD, 15, 1);
103 	if (cs_mask & (1 << 3))
104 		at91_set_pio_output(AT91_PIO_PORTD, 16, 1);
105 
106 	/* Enable clock */
107 	at91_periph_clk_enable(ATMEL_ID_SPI0);
108 }
109 #endif
110 
111 #ifdef CONFIG_GENERIC_ATMEL_MCI
112 void at91_mci_hw_init(void)
113 {
114 	at91_set_a_periph(AT91_PIO_PORTD, 0, 0);	/* MCI0 CMD */
115 	at91_set_a_periph(AT91_PIO_PORTD, 1, 0);	/* MCI0 DA0 */
116 	at91_set_a_periph(AT91_PIO_PORTD, 2, 0);	/* MCI0 DA1 */
117 	at91_set_a_periph(AT91_PIO_PORTD, 3, 0);        /* MCI0 DA2 */
118 	at91_set_a_periph(AT91_PIO_PORTD, 4, 0);        /* MCI0 DA3 */
119 #ifdef CONFIG_ATMEL_MCI_8BIT
120 	at91_set_a_periph(AT91_PIO_PORTD, 5, 0);        /* MCI0 DA4 */
121 	at91_set_a_periph(AT91_PIO_PORTD, 6, 0);        /* MCI0 DA5 */
122 	at91_set_a_periph(AT91_PIO_PORTD, 7, 0);        /* MCI0 DA6 */
123 	at91_set_a_periph(AT91_PIO_PORTD, 8, 0);        /* MCI0 DA7 */
124 #endif
125 	at91_set_a_periph(AT91_PIO_PORTD, 9, 0);        /* MCI0 CLK */
126 
127 	/* Enable clock */
128 	at91_periph_clk_enable(ATMEL_ID_MCI0);
129 }
130 #endif
131 
132 #ifdef CONFIG_MACB
133 void at91_macb_hw_init(void)
134 {
135 	at91_set_a_periph(AT91_PIO_PORTC, 7, 0);	/* ETXCK_EREFCK */
136 	at91_set_a_periph(AT91_PIO_PORTC, 5, 0);	/* ERXDV */
137 	at91_set_a_periph(AT91_PIO_PORTC, 2, 0);	/* ERX0 */
138 	at91_set_a_periph(AT91_PIO_PORTC, 3, 0);	/* ERX1 */
139 	at91_set_a_periph(AT91_PIO_PORTC, 6, 0);	/* ERXER */
140 	at91_set_a_periph(AT91_PIO_PORTC, 4, 0);	/* ETXEN */
141 	at91_set_a_periph(AT91_PIO_PORTC, 0, 0);	/* ETX0 */
142 	at91_set_a_periph(AT91_PIO_PORTC, 1, 0);	/* ETX1 */
143 	at91_set_a_periph(AT91_PIO_PORTC, 9, 0);	/* EMDIO */
144 	at91_set_a_periph(AT91_PIO_PORTC, 8, 0);	/* EMDC */
145 
146 	/* Enable clock */
147 	at91_periph_clk_enable(ATMEL_ID_EMAC);
148 }
149 
150 void at91_gmac_hw_init(void)
151 {
152 	at91_set_a_periph(AT91_PIO_PORTB, 0, 0);	/* GTX0 */
153 	at91_set_a_periph(AT91_PIO_PORTB, 1, 0);	/* GTX1 */
154 	at91_set_a_periph(AT91_PIO_PORTB, 2, 0);	/* GTX2 */
155 	at91_set_a_periph(AT91_PIO_PORTB, 3, 0);	/* GTX3 */
156 	at91_set_a_periph(AT91_PIO_PORTB, 4, 0);	/* GRX0 */
157 	at91_set_a_periph(AT91_PIO_PORTB, 5, 0);	/* GRX1 */
158 	at91_set_a_periph(AT91_PIO_PORTB, 6, 0);	/* GRX2 */
159 	at91_set_a_periph(AT91_PIO_PORTB, 7, 0);	/* GRX3 */
160 	at91_set_a_periph(AT91_PIO_PORTB, 8, 0);	/* GTXCK */
161 	at91_set_a_periph(AT91_PIO_PORTB, 9, 0);	/* GTXEN */
162 
163 	at91_set_a_periph(AT91_PIO_PORTB, 11, 0);	/* GRXCK */
164 	at91_set_a_periph(AT91_PIO_PORTB, 13, 0);	/* GRXER */
165 
166 	at91_set_a_periph(AT91_PIO_PORTB, 16, 0);	/* GMDC */
167 	at91_set_a_periph(AT91_PIO_PORTB, 17, 0);	/* GMDIO */
168 	at91_set_a_periph(AT91_PIO_PORTB, 18, 0);	/* G125CK */
169 
170 	/* Enable clock */
171 	at91_periph_clk_enable(ATMEL_ID_GMAC);
172 }
173 #endif
174 
175 #ifdef CONFIG_LCD
176 void at91_lcd_hw_init(void)
177 {
178 	at91_set_a_periph(AT91_PIO_PORTA, 24, 0);	/* LCDPWM */
179 	at91_set_a_periph(AT91_PIO_PORTA, 25, 0);	/* LCDDISP */
180 	at91_set_a_periph(AT91_PIO_PORTA, 26, 0);	/* LCDVSYNC */
181 	at91_set_a_periph(AT91_PIO_PORTA, 27, 0);	/* LCDHSYNC */
182 	at91_set_a_periph(AT91_PIO_PORTA, 28, 0);	/* LCDDOTCK */
183 	at91_set_a_periph(AT91_PIO_PORTA, 29, 0);	/* LCDDEN */
184 
185 	/* The lower 16-bit of LCD only available on Port A */
186 	at91_set_a_periph(AT91_PIO_PORTA,  0, 0);	/* LCDD0 */
187 	at91_set_a_periph(AT91_PIO_PORTA,  1, 0);	/* LCDD1 */
188 	at91_set_a_periph(AT91_PIO_PORTA,  2, 0);	/* LCDD2 */
189 	at91_set_a_periph(AT91_PIO_PORTA,  3, 0);	/* LCDD3 */
190 	at91_set_a_periph(AT91_PIO_PORTA,  4, 0);	/* LCDD4 */
191 	at91_set_a_periph(AT91_PIO_PORTA,  5, 0);	/* LCDD5 */
192 	at91_set_a_periph(AT91_PIO_PORTA,  6, 0);	/* LCDD6 */
193 	at91_set_a_periph(AT91_PIO_PORTA,  7, 0);	/* LCDD7 */
194 	at91_set_a_periph(AT91_PIO_PORTA,  8, 0);	/* LCDD8 */
195 	at91_set_a_periph(AT91_PIO_PORTA,  9, 0);	/* LCDD9 */
196 	at91_set_a_periph(AT91_PIO_PORTA, 10, 0);	/* LCDD10 */
197 	at91_set_a_periph(AT91_PIO_PORTA, 11, 0);	/* LCDD11 */
198 	at91_set_a_periph(AT91_PIO_PORTA, 12, 0);	/* LCDD12 */
199 	at91_set_a_periph(AT91_PIO_PORTA, 13, 0);	/* LCDD13 */
200 	at91_set_a_periph(AT91_PIO_PORTA, 14, 0);	/* LCDD14 */
201 	at91_set_a_periph(AT91_PIO_PORTA, 15, 0);	/* LCDD15 */
202 
203 	/* Enable clock */
204 	at91_periph_clk_enable(ATMEL_ID_LCDC);
205 }
206 #endif
207 
208 #ifdef CONFIG_USB_GADGET_ATMEL_USBA
209 void at91_udp_hw_init(void)
210 {
211 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
212 
213 	/* Enable UPLL clock */
214 	writel(AT91_PMC_UPLLEN | AT91_PMC_BIASEN, &pmc->uckr);
215 	/* Enable UDPHS clock */
216 	at91_periph_clk_enable(ATMEL_ID_UDPHS);
217 }
218 #endif
219