blob: bf693c8d4578de943e07616b9ed81cc5a36176d3 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Joe Hershberger911c6062011-11-11 15:55:37 -06002/*
3 * Freescale MPC83xx GPIO handling.
Joe Hershberger911c6062011-11-11 15:55:37 -06004 */
5
6#include <common.h>
Simon Glass9bc15642020-02-03 07:36:16 -07007#include <malloc.h>
Joe Hershberger911c6062011-11-11 15:55:37 -06008#include <mpc83xx.h>
9#include <asm/gpio.h>
10#include <asm/io.h>
11
Tom Rini364d0022023-01-10 11:19:45 -050012#ifndef CFG_MPC83XX_GPIO_0_INIT_DIRECTION
13#define CFG_MPC83XX_GPIO_0_INIT_DIRECTION 0
Joe Hershberger911c6062011-11-11 15:55:37 -060014#endif
Tom Rini364d0022023-01-10 11:19:45 -050015#ifndef CFG_MPC83XX_GPIO_1_INIT_DIRECTION
16#define CFG_MPC83XX_GPIO_1_INIT_DIRECTION 0
Joe Hershberger911c6062011-11-11 15:55:37 -060017#endif
Tom Rini364d0022023-01-10 11:19:45 -050018#ifndef CFG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN
19#define CFG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN 0
Joe Hershberger911c6062011-11-11 15:55:37 -060020#endif
Tom Rini364d0022023-01-10 11:19:45 -050021#ifndef CFG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN
22#define CFG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN 0
Joe Hershberger911c6062011-11-11 15:55:37 -060023#endif
Tom Rini364d0022023-01-10 11:19:45 -050024#ifndef CFG_MPC83XX_GPIO_0_INIT_VALUE
25#define CFG_MPC83XX_GPIO_0_INIT_VALUE 0
Joe Hershberger911c6062011-11-11 15:55:37 -060026#endif
Tom Rini364d0022023-01-10 11:19:45 -050027#ifndef CFG_MPC83XX_GPIO_1_INIT_VALUE
28#define CFG_MPC83XX_GPIO_1_INIT_VALUE 0
Joe Hershberger911c6062011-11-11 15:55:37 -060029#endif
30
31static unsigned int gpio_output_value[MPC83XX_GPIO_CTRLRS];
32
33/*
34 * Generic_GPIO primitives.
35 */
36
37int gpio_request(unsigned gpio, const char *label)
38{
39 if (gpio >= MAX_NUM_GPIOS)
40 return -1;
41
42 return 0;
43}
44
45int gpio_free(unsigned gpio)
46{
47 /* Do not set to input */
48 return 0;
49}
50
51/* set GPIO pin 'gpio' as an input */
52int gpio_direction_input(unsigned gpio)
53{
54 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
55 unsigned int ctrlr;
56 unsigned int line;
57 unsigned int line_mask;
58
59 /* 32-bits per controller */
60 ctrlr = gpio >> 5;
61 line = gpio & (0x1F);
62
63 /* Big endian */
64 line_mask = 1 << (31 - line);
65
66 clrbits_be32(&im->gpio[ctrlr].dir, line_mask);
67
68 return 0;
69}
70
71/* set GPIO pin 'gpio' as an output, with polarity 'value' */
72int gpio_direction_output(unsigned gpio, int value)
73{
74 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
75 unsigned int ctrlr;
76 unsigned int line;
77 unsigned int line_mask;
78
79 if (value != 0 && value != 1) {
80 printf("Error: Value parameter must be 0 or 1.\n");
81 return -1;
82 }
83
84 gpio_set_value(gpio, value);
85
86 /* 32-bits per controller */
87 ctrlr = gpio >> 5;
88 line = gpio & (0x1F);
89
90 /* Big endian */
91 line_mask = 1 << (31 - line);
92
93 /* Make the line output */
94 setbits_be32(&im->gpio[ctrlr].dir, line_mask);
95
96 return 0;
97}
98
99/* read GPIO IN value of pin 'gpio' */
100int gpio_get_value(unsigned gpio)
101{
102 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
103 unsigned int ctrlr;
104 unsigned int line;
105 unsigned int line_mask;
106
107 /* 32-bits per controller */
108 ctrlr = gpio >> 5;
109 line = gpio & (0x1F);
110
111 /* Big endian */
112 line_mask = 1 << (31 - line);
113
114 /* Read the value and mask off the bit */
115 return (in_be32(&im->gpio[ctrlr].dat) & line_mask) != 0;
116}
117
118/* write GPIO OUT value to pin 'gpio' */
119int gpio_set_value(unsigned gpio, int value)
120{
121 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
122 unsigned int ctrlr;
123 unsigned int line;
124 unsigned int line_mask;
125
126 if (value != 0 && value != 1) {
127 printf("Error: Value parameter must be 0 or 1.\n");
128 return -1;
129 }
130
131 /* 32-bits per controller */
132 ctrlr = gpio >> 5;
133 line = gpio & (0x1F);
134
135 /* Big endian */
136 line_mask = 1 << (31 - line);
137
138 /* Update the local output buffer soft copy */
139 gpio_output_value[ctrlr] =
140 (gpio_output_value[ctrlr] & ~line_mask) | \
141 (value ? line_mask : 0);
142
143 /* Write the output */
144 out_be32(&im->gpio[ctrlr].dat, gpio_output_value[ctrlr]);
145
146 return 0;
147}
148
149/* Configure GPIO registers early */
Kim Phillipsbd76f012012-10-29 13:34:41 +0000150void mpc83xx_gpio_init_f(void)
Joe Hershberger911c6062011-11-11 15:55:37 -0600151{
152 immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
153
154#if MPC83XX_GPIO_CTRLRS >= 1
Tom Rini364d0022023-01-10 11:19:45 -0500155 out_be32(&im->gpio[0].dir, CFG_MPC83XX_GPIO_0_INIT_DIRECTION);
156 out_be32(&im->gpio[0].odr, CFG_MPC83XX_GPIO_0_INIT_OPEN_DRAIN);
157 out_be32(&im->gpio[0].dat, CFG_MPC83XX_GPIO_0_INIT_VALUE);
Joe Hershberger911c6062011-11-11 15:55:37 -0600158 out_be32(&im->gpio[0].ier, 0xFFFFFFFF); /* Clear all events */
159 out_be32(&im->gpio[0].imr, 0);
160 out_be32(&im->gpio[0].icr, 0);
161#endif
162
163#if MPC83XX_GPIO_CTRLRS >= 2
Tom Rini364d0022023-01-10 11:19:45 -0500164 out_be32(&im->gpio[1].dir, CFG_MPC83XX_GPIO_1_INIT_DIRECTION);
165 out_be32(&im->gpio[1].odr, CFG_MPC83XX_GPIO_1_INIT_OPEN_DRAIN);
166 out_be32(&im->gpio[1].dat, CFG_MPC83XX_GPIO_1_INIT_VALUE);
Joe Hershberger911c6062011-11-11 15:55:37 -0600167 out_be32(&im->gpio[1].ier, 0xFFFFFFFF); /* Clear all events */
168 out_be32(&im->gpio[1].imr, 0);
169 out_be32(&im->gpio[1].icr, 0);
170#endif
171}
172
173/* Initialize GPIO soft-copies */
Kim Phillipsbd76f012012-10-29 13:34:41 +0000174void mpc83xx_gpio_init_r(void)
Joe Hershberger911c6062011-11-11 15:55:37 -0600175{
176#if MPC83XX_GPIO_CTRLRS >= 1
Tom Rini364d0022023-01-10 11:19:45 -0500177 gpio_output_value[0] = CFG_MPC83XX_GPIO_0_INIT_VALUE;
Joe Hershberger911c6062011-11-11 15:55:37 -0600178#endif
179
180#if MPC83XX_GPIO_CTRLRS >= 2
Tom Rini364d0022023-01-10 11:19:45 -0500181 gpio_output_value[1] = CFG_MPC83XX_GPIO_1_INIT_VALUE;
Joe Hershberger911c6062011-11-11 15:55:37 -0600182#endif
183}