blob: 6073843b5efdbf8be158a221409780cadb44ba73 [file] [log] [blame]
Jens Scharsigea8fbba2010-02-03 22:46:16 +01001/*
2 * Memory Setup stuff - taken from blob memsetup.S
3 *
4 * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
5 *
6 * Copyright (C) 2005 HP Labs
7 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Jens Scharsigea8fbba2010-02-03 22:46:16 +01009 */
10
11#include <config.h>
12#include <common.h>
Reinhard Meyer86592f62010-11-07 13:26:14 +010013#include <asm/io.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010014#include <asm/sizes.h>
15#include <asm/arch/hardware.h>
Jens Scharsigea8fbba2010-02-03 22:46:16 +010016#include <asm/arch/at91_pio.h>
17
Bo Shen4bc9b7a2013-08-22 15:24:40 +080018static struct at91_port *at91_pio_get_port(unsigned port)
19{
20 switch (port) {
21 case AT91_PIO_PORTA:
22 return (struct at91_port *)ATMEL_BASE_PIOA;
23 case AT91_PIO_PORTB:
24 return (struct at91_port *)ATMEL_BASE_PIOB;
25 case AT91_PIO_PORTC:
26 return (struct at91_port *)ATMEL_BASE_PIOC;
27#if (ATMEL_PIO_PORTS > 3)
28 case AT91_PIO_PORTD:
29 return (struct at91_port *)ATMEL_BASE_PIOD;
30#if (ATMEL_PIO_PORTS > 4)
31 case AT91_PIO_PORTE:
32 return (struct at91_port *)ATMEL_BASE_PIOE;
33#endif
34#endif
35 default:
36 return NULL;
37 }
38}
39
Jens Scharsigea8fbba2010-02-03 22:46:16 +010040int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
41{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080042 struct at91_port *at91_port = at91_pio_get_port(port);
43 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010044
Bo Shen4bc9b7a2013-08-22 15:24:40 +080045 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010046 mask = 1 << pin;
47 if (use_pullup)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080048 writel(1 << pin, &at91_port->puer);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010049 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +080050 writel(1 << pin, &at91_port->pudr);
51 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010052 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080053
Jens Scharsigea8fbba2010-02-03 22:46:16 +010054 return 0;
55}
56
57/*
58 * mux the pin to the "GPIO" peripheral role.
59 */
60int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
61{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080062 struct at91_port *at91_port = at91_pio_get_port(port);
63 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010064
Bo Shen4bc9b7a2013-08-22 15:24:40 +080065 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010066 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080067 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010068 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +080069 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010070 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080071
Jens Scharsigea8fbba2010-02-03 22:46:16 +010072 return 0;
73}
74
75/*
76 * mux the pin to the "A" internal peripheral role.
77 */
78int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
79{
Bo Shen4bc9b7a2013-08-22 15:24:40 +080080 struct at91_port *at91_port = at91_pio_get_port(port);
81 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +010082
Bo Shen4bc9b7a2013-08-22 15:24:40 +080083 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +010084 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +080085 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010086 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +000087#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +080088 writel(readl(&at91_port->abcdsr1) & ~mask,
89 &at91_port->abcdsr1);
90 writel(readl(&at91_port->abcdsr2) & ~mask,
91 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +000092#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +080093 writel(mask, &at91_port->asr);
Bo Shen2b3b1c62012-05-20 15:50:00 +000094#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +080095 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +010096 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +080097
Jens Scharsigea8fbba2010-02-03 22:46:16 +010098 return 0;
99}
100
101/*
102 * mux the pin to the "B" internal peripheral role.
103 */
104int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
105{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800106 struct at91_port *at91_port = at91_pio_get_port(port);
107 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100108
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800109 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100110 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800111 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100112 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000113#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800114 writel(readl(&at91_port->abcdsr1) | mask,
115 &at91_port->abcdsr1);
116 writel(readl(&at91_port->abcdsr2) & ~mask,
117 &at91_port->abcdsr2);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000118#else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800119 writel(mask, &at91_port->bsr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000120#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800121 writel(mask, &at91_port->pdr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100122 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800123
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100124 return 0;
125}
126
Bo Shen2b3b1c62012-05-20 15:50:00 +0000127#if defined(CPU_HAS_PIO3)
128/*
129 * mux the pin to the "C" internal peripheral role.
130 */
131int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
132{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800133 struct at91_port *at91_port = at91_pio_get_port(port);
134 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000135
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800136 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000137 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800138 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000139 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800140 writel(readl(&at91_port->abcdsr1) & ~mask,
141 &at91_port->abcdsr1);
142 writel(readl(&at91_port->abcdsr2) | mask,
143 &at91_port->abcdsr2);
144 writel(mask, &at91_port->pdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000145 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800146
Bo Shen2b3b1c62012-05-20 15:50:00 +0000147 return 0;
148}
149
150/*
151 * mux the pin to the "D" internal peripheral role.
152 */
153int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
154{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800155 struct at91_port *at91_port = at91_pio_get_port(port);
156 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000157
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800158 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000159 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800160 writel(mask, &at91_port->idr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000161 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800162 writel(readl(&at91_port->abcdsr1) | mask,
163 &at91_port->abcdsr1);
164 writel(readl(&at91_port->abcdsr2) | mask,
165 &at91_port->abcdsr2);
166 writel(mask, &at91_port->pdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000167 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800168
Bo Shen2b3b1c62012-05-20 15:50:00 +0000169 return 0;
170}
171#endif
172
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100173/*
174 * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
175 * configure it for an input.
176 */
177int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
178{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800179 struct at91_port *at91_port = at91_pio_get_port(port);
180 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100181
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800182 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100183 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800184 writel(mask, &at91_port->idr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100185 at91_set_pio_pullup(port, pin, use_pullup);
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800186 writel(mask, &at91_port->odr);
187 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100188 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800189
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100190 return 0;
191}
192
193/*
194 * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
195 * and configure it for an output.
196 */
197int at91_set_pio_output(unsigned port, u32 pin, int value)
198{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800199 struct at91_port *at91_port = at91_pio_get_port(port);
200 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100201
Reinhard Meyer372f2782010-11-03 15:47:20 +0100202 if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100203 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800204 writel(mask, &at91_port->idr);
205 writel(mask, &at91_port->pudr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100206 if (value)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800207 writel(mask, &at91_port->sodr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100208 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800209 writel(mask, &at91_port->codr);
210 writel(mask, &at91_port->oer);
211 writel(mask, &at91_port->per);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100212 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800213
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100214 return 0;
215}
216
217/*
218 * enable/disable the glitch filter. mostly used with IRQ handling.
219 */
220int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
221{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800222 struct at91_port *at91_port = at91_pio_get_port(port);
223 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100224
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800225 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100226 mask = 1 << pin;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000227 if (is_on) {
228#if defined(CPU_HAS_PIO3)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800229 writel(mask, &at91_port->ifscdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000230#endif
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800231 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000232 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800233 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000234 }
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100235 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800236
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100237 return 0;
238}
239
Bo Shen2b3b1c62012-05-20 15:50:00 +0000240#if defined(CPU_HAS_PIO3)
241/*
242 * enable/disable the debounce filter.
243 */
244int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
245{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800246 struct at91_port *at91_port = at91_pio_get_port(port);
247 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000248
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800249 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000250 mask = 1 << pin;
251 if (is_on) {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800252 writel(mask, &at91_port->ifscer);
253 writel(div & PIO_SCDR_DIV, &at91_port->scdr);
254 writel(mask, &at91_port->ifer);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000255 } else {
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800256 writel(mask, &at91_port->ifdr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000257 }
258 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800259
Bo Shen2b3b1c62012-05-20 15:50:00 +0000260 return 0;
261}
262
263/*
264 * enable/disable the pull-down.
265 * If pull-up already enabled while calling the function, we disable it.
266 */
267int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
268{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800269 struct at91_port *at91_port = at91_pio_get_port(port);
270 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000271
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800272 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000273 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800274 writel(mask, &at91_port->pudr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000275 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800276 writel(mask, &at91_port->ppder);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000277 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800278 writel(mask, &at91_port->ppddr);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000279 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800280
Bo Shen2b3b1c62012-05-20 15:50:00 +0000281 return 0;
282}
283
284/*
285 * disable Schmitt trigger
286 */
287int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
288{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800289 struct at91_port *at91_port = at91_pio_get_port(port);
290 u32 mask;
Bo Shen2b3b1c62012-05-20 15:50:00 +0000291
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800292 if (at91_port && (pin < 32)) {
Bo Shen2b3b1c62012-05-20 15:50:00 +0000293 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800294 writel(readl(&at91_port->schmitt) | mask,
295 &at91_port->schmitt);
Bo Shen2b3b1c62012-05-20 15:50:00 +0000296 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800297
Bo Shen2b3b1c62012-05-20 15:50:00 +0000298 return 0;
299}
300#endif
301
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100302/*
303 * enable/disable the multi-driver. This is only valid for output and
304 * allows the output pin to run as an open collector output.
305 */
306int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
307{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800308 struct at91_port *at91_port = at91_pio_get_port(port);
309 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100310
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800311 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100312 mask = 1 << pin;
313 if (is_on)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800314 writel(mask, &at91_port->mder);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100315 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800316 writel(mask, &at91_port->mddr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100317 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800318
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100319 return 0;
320}
321
322/*
323 * assuming the pin is muxed as a gpio output, set its value.
324 */
325int at91_set_pio_value(unsigned port, unsigned pin, int value)
326{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800327 struct at91_port *at91_port = at91_pio_get_port(port);
328 u32 mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100329
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800330 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100331 mask = 1 << pin;
332 if (value)
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800333 writel(mask, &at91_port->sodr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100334 else
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800335 writel(mask, &at91_port->codr);
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100336 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800337
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100338 return 0;
339}
340
341/*
342 * read the pin's value (works even if it's not muxed as a gpio).
343 */
344int at91_get_pio_value(unsigned port, unsigned pin)
345{
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800346 struct at91_port *at91_port = at91_pio_get_port(port);
347 u32 pdsr = 0, mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100348
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800349 if (at91_port && (pin < 32)) {
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100350 mask = 1 << pin;
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800351 pdsr = readl(&at91_port->pdsr) & mask;
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100352 }
Bo Shen4bc9b7a2013-08-22 15:24:40 +0800353
Jens Scharsigea8fbba2010-02-03 22:46:16 +0100354 return pdsr != 0;
355}
Bo Shen6edaea82013-08-13 14:38:31 +0800356
357/* Common GPIO API */
358
359#define at91_gpio_to_port(gpio) (gpio / 32)
360#define at91_gpio_to_pin(gpio) (gpio % 32)
361
362int gpio_request(unsigned gpio, const char *label)
363{
364 return 0;
365}
366
367int gpio_free(unsigned gpio)
368{
369 return 0;
370}
371
372int gpio_direction_input(unsigned gpio)
373{
374 at91_set_pio_input(at91_gpio_to_port(gpio),
375 at91_gpio_to_pin(gpio), 0);
376 return 0;
377}
378
379int gpio_direction_output(unsigned gpio, int value)
380{
381 at91_set_pio_output(at91_gpio_to_port(gpio),
382 at91_gpio_to_pin(gpio), value);
383 return 0;
384}
385
386int gpio_get_value(unsigned gpio)
387{
388 return at91_get_pio_value(at91_gpio_to_port(gpio),
389 at91_gpio_to_pin(gpio));
390}
391
392int gpio_set_value(unsigned gpio, int value)
393{
394 at91_set_pio_value(at91_gpio_to_port(gpio),
395 at91_gpio_to_pin(gpio), value);
396
397 return 0;
398}