1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <soc/aml-s912/s912-gpio.h>
6
7static aml_gpio_block_t s912_gpio_blocks[] = {
8    // GPIOX Block
9    {
10        .pin_count = S912_GPIOX_PINS,
11        .oen_offset = S912_GPIOX_0EN,
12        .input_offset = S912_GPIOX_IN,
13        .output_offset = S912_GPIOX_OUT,
14        .output_shift = 0,
15        .mmio_index = 0,
16        .pull_offset = S912_PULL_UP_REG4,
17        .pull_en_offset = S912_PULL_UP_EN_REG4,
18        .pin_start = S912_GPIOX_PIN_START,
19        .lock = MTX_INIT,
20    },
21    // GPIODV Block
22    {
23        .pin_count = S912_GPIODV_PINS,
24        .oen_offset = S912_GPIODV_0EN,
25        .input_offset = S912_GPIODV_IN,
26        .output_offset = S912_GPIODV_OUT,
27        .output_shift = 0,
28        .mmio_index = 0,
29        .pull_offset = S912_PULL_UP_REG0,
30        .pull_en_offset = S912_PULL_UP_EN_REG0,
31        .pin_start = S912_GPIODV_PIN_START,
32        .lock = MTX_INIT,
33    },
34    // GPIOH Block
35    {
36        .pin_count = S912_GPIOH_PINS,
37        .oen_offset = S912_GPIOH_0EN,
38        .input_offset = S912_GPIOH_IN,
39        .output_offset = S912_GPIOH_OUT,
40        .output_shift = 20,
41        .mmio_index = 0,
42        .pull_offset = S912_PULL_UP_REG1,
43        .pull_en_offset = S912_PULL_UP_EN_REG1,
44        .pin_start = S912_GPIOH_PIN_START,
45        .lock = MTX_INIT,
46    },
47    // GPIOBOOT Block
48    {
49        .pin_count = S912_GPIOBOOT_PINS,
50        .oen_offset = S912_GPIOBOOT_0EN,
51        .input_offset = S912_GPIOBOOT_IN,
52        .output_offset = S912_GPIOBOOT_OUT,
53        .output_shift = 0,
54        .mmio_index = 0,
55        .pull_offset = S912_PULL_UP_REG2,
56        .pull_en_offset = S912_PULL_UP_EN_REG2,
57        .pin_start = S912_GPIOBOOT_PIN_START,
58        .lock = MTX_INIT,
59    },
60    // GPIOCARD Block
61    {
62        .pin_count = S912_GPIOCARD_PINS,
63        .oen_offset = S912_GPIOCARD_0EN,
64        .input_offset = S912_GPIOCARD_IN,
65        .output_offset = S912_GPIOCARD_OUT,
66        .output_shift = 20,
67        .mmio_index = 0,
68        .pull_offset = S912_PULL_UP_REG2,
69        .pull_en_offset = S912_PULL_UP_EN_REG2,
70        .pin_start = S912_GPIOCARD_PIN_START,
71        .lock = MTX_INIT,
72    },
73    // GPIOCLK Block
74    {
75        .pin_count = S912_GPIOCLK_PINS,
76        .oen_offset = S912_GPIOCLK_0EN,
77        .input_offset = S912_GPIOCLK_IN,
78        .output_offset = S912_GPIOCLK_OUT,
79        .output_shift = 28,
80        .mmio_index = 0,
81        .pull_offset = S912_PULL_UP_REG3,
82        .pull_en_offset = S912_PULL_UP_EN_REG3,
83        .pin_start = S912_GPIOCLK_PIN_START,
84        .lock = MTX_INIT,
85    },
86    // GPIOZ Block
87    {
88        .pin_count = S912_GPIOZ_PINS,
89        .oen_offset = S912_GPIOZ_0EN,
90        .input_offset = S912_GPIOZ_IN,
91        .output_offset = S912_GPIOZ_OUT,
92        .output_shift = 0,
93        .mmio_index = 0,
94        .pull_offset = S912_PULL_UP_REG3,
95        .pull_en_offset = S912_PULL_UP_EN_REG3,
96        .pin_start = S912_GPIOZ_PIN_START,
97        .lock = MTX_INIT,
98    },
99    // GPIOAO Block
100    {
101        .pin_count = S912_GPIOAO_PINS,
102        .oen_offset = S912_AO_GPIO_OEN_OUT,
103        .input_offset = S912_AO_GPIO_IN,
104        .output_offset = S912_AO_GPIO_OEN_OUT,
105        .output_shift = 0,
106        .output_write_shift = 16, //OUT/EN share reg
107        .mmio_index = 1,
108        .pull_offset = 0, // not supported
109        .pull_en_offset = 0, // not supported
110        .pin_start = S912_GPIOA0_PIN_START,
111        .lock = MTX_INIT,
112    },
113};
114
115#define REG_0 S912_PERIPHS_PIN_MUX_0
116#define REG_1 S912_PERIPHS_PIN_MUX_1
117#define REG_2 S912_PERIPHS_PIN_MUX_2
118#define REG_3 S912_PERIPHS_PIN_MUX_3
119#define REG_4 S912_PERIPHS_PIN_MUX_4
120#define REG_5 S912_PERIPHS_PIN_MUX_5
121#define REG_6 S912_PERIPHS_PIN_MUX_6
122#define REG_7 S912_PERIPHS_PIN_MUX_7
123#define REG_8 S912_PERIPHS_PIN_MUX_8
124#define REG_9 S912_PERIPHS_PIN_MUX_9
125#define AO_REG S912_AO_RTI_PIN_MUX_REG
126#define AO_REG_2 S912_AO_RTI_PIN_MUX_REG2
127
128static aml_gpio_interrupt_t s912_interrupt_block = {
129    .pin_0_3_select_offset =    S912_GPIO_0_3_PIN_SELECT,
130    .pin_4_7_select_offset =    S912_GPIO_4_7_PIN_SELECT,
131    .edge_polarity_offset =     S912_GPIO_INT_EDGE_POLARITY,
132    .filter_select_offset =     S912_GPIO_FILTER_SELECT,
133    .status_offset =            S912_GPIO_INT_STATUS,
134    .mask_offset =              S912_GPIO_INT_MASK,
135};
136
137static const aml_pinmux_block_t s912_pinmux_blocks[] = {
138    // GPIOX Block
139    {
140        .mux = {
141            { .regs = { REG_5 }, .bits = { 31 }, },
142            { .regs = { REG_5 }, .bits = { 30 }, },
143            { .regs = { REG_5 }, .bits = { 29 }, },
144            { .regs = { REG_5 }, .bits = { 28 }, },
145            { .regs = { REG_5 }, .bits = { 27 }, },
146            { .regs = { REG_5 }, .bits = { 26 }, },
147            { .regs = { REG_5 }, .bits = { 25 }, },
148            { .regs = { REG_5, REG_5 }, .bits = { 24, 14 }, },
149            { .regs = { REG_5, REG_5, 0, REG_5 }, .bits = { 23, 13, 0, 3 }, },
150            { .regs = { REG_5, REG_5, 0, REG_5 }, .bits = { 22, 12, 0, 2 }, },
151            { .regs = { REG_5, REG_5, REG_5, REG_5 }, .bits = { 21, 11, 5, 1 }, },
152            { .regs = { REG_5, REG_5, REG_5, REG_5 }, .bits = { 20, 10, 4, 0 }, },
153            { .regs = { REG_5 }, .bits = { 19 }, },
154            { .regs = { REG_5 }, .bits = { 18 }, },
155            { .regs = { REG_5 }, .bits = { 17 }, },
156            { .regs = { REG_5 }, .bits = { 16 }, },
157            { .regs = { REG_5 }, .bits = { 15 }, },
158            // pinmux not specified for GPIOX_17 and GPIOX_18.
159        },
160    },
161    // GPIODV Block
162    {
163        .mux = {
164            { .regs = { REG_3, 0, 0, REG_2, REG_1 }, .bits = { 10, 0, 0, 4, 8 }, },
165            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 10, 0, 0, 3 }, },
166            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 9, 0, 0, 3 }, },
167            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 9, 0, 0, 3 }, },
168            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 9, 0, 0, 3 }, },
169            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 9, 0, 0, 3 }, },
170            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 9, 0, 0, 3 }, },
171            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 9, 0, 0, 3 }, },
172            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 8, 0, 0, 2 }, },
173            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 8, 0, 0, 1 }, },
174            { .regs = { REG_3, 0, 0, REG_2 }, .bits = { 7, 0, 0, 0 }, },
175            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 7, 0, 0, 31 }, },
176            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 7, 0, 0, 30 }, },
177            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 7, 0, 0, 29 }, },
178            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 7, 0, 0, 28 }, },
179            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 7, 0, 0, 27 }, },
180            { .regs = { REG_3, 0, 0, REG_1, REG_1 }, .bits = { 6, 0, 0, 26, 24 }, },
181            { .regs = { REG_3, 0, 0, REG_1, REG_1 }, .bits = { 6, 0, 0, 25, 23 }, },
182            { .regs = { REG_3, REG_1, 0, REG_1 }, .bits = { 5, 17, 0, 25 }, },
183            { .regs = { REG_3, REG_1, 0, REG_1 }, .bits = { 5, 16, 0, 25 }, },
184            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 5, 0, 0, 25 }, },
185            { .regs = { REG_3, 0, 0, REG_1 }, .bits = { 5, 0, 0, 25 }, },
186            { .regs = { REG_3, 0, REG_2, REG_1 }, .bits = { 5, 0, 18, 25 }, },
187            { .regs = { REG_3, 0, REG_2, REG_1 }, .bits = { 5, 0, 17, 25 }, },
188            { .regs = { REG_3, REG_1, REG_2, REG_2, REG_1 }, .bits = { 4, 15, 16, 7, 22 }, },
189            { .regs = { REG_3, REG_1, REG_2, REG_2, REG_1 }, .bits = { 3, 14, 15, 6, 21 }, },
190            { .regs = { REG_1, REG_1, REG_2 }, .bits = { 20, 13, 14 }, },
191            { .regs = { REG_1, REG_1, REG_2, 0, REG_1 }, .bits = { 18, 12, 13, 0, 19 }, },
192            { .regs = { REG_2, REG_1, 0, REG_1 }, .bits = { 12, 11, 0, 9 }, },
193            { .regs = { REG_2, REG_1, REG_2 }, .bits = { 11, 10, 5 }, },
194        },
195    },
196    // GPIOH Block
197    {
198        .mux = {
199            { .regs = { REG_6 }, .bits = { 31 }, },
200            { .regs = { REG_6 }, .bits = { 30 }, },
201            { .regs = { REG_6 }, .bits = { 29 }, },
202            {},
203            { .regs = { REG_6, REG_6 }, .bits = { 28, 27 }, },
204            {},
205            { .regs = { 0, 0, REG_6, 0, REG_6 }, .bits = { 0, 0, 26, 0, 20 }, },
206            { .regs = { 0, 0, REG_6, REG_6, REG_6 }, .bits = { 0, 0, 25, 22, 19 }, },
207            { .regs = { 0, 0, REG_6, REG_6, REG_6 }, .bits = { 0, 0, 24, 21, 18 }, },
208            { .regs = { 0, 0, REG_6, 0, REG_6 }, .bits = { 0, 0, 23, 0, 17 }, },
209        },
210    },
211    // GPIOBOOT Block
212    {
213        .mux = {
214            { .regs = { REG_7 }, .bits = { 31 }, },
215            { .regs = { REG_7 }, .bits = { 31 }, },
216            { .regs = { REG_7 }, .bits = { 31 }, },
217            { .regs = { REG_7 }, .bits = { 31 }, },
218            { .regs = { REG_7 }, .bits = { 31 }, },
219            { .regs = { REG_7 }, .bits = { 31 }, },
220            { .regs = { REG_7 }, .bits = { 31 }, },
221            { .regs = { REG_7 }, .bits = { 31 }, },
222            { .regs = { REG_7, REG_7 }, .bits = { 30, 7 }, },
223            { .regs = { 0, REG_7 }, .bits = { 0, 6 }, },
224            { .regs = { REG_7, REG_7 }, .bits = { 29, 5 }, },
225            { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 4, 13 }, },
226            { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 3, 12 }, },
227            { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 2, 11 }, },
228            { .regs = { 0, REG_7 }, .bits = { 0, 1 }, },
229            { .regs = { REG_7, REG_7, REG_7 }, .bits = { 28, 0, 10 }, },
230        },
231    },
232    // GPIOCARD Block
233    {
234        .mux = {
235            { .regs = { REG_6 }, .bits = { 5 }, },
236            { .regs = { REG_6 }, .bits = { 4 }, },
237            { .regs = { REG_6 }, .bits = { 3 }, },
238            { .regs = { REG_6 }, .bits = { 2 }, },
239            { .regs = { REG_6, REG_6, REG_6 }, .bits = { 1, 9, 11 }, },
240            { .regs = { REG_6, REG_6, REG_6 }, .bits = { 0, 8, 10 }, },
241        },
242    },
243    // GPIOCLK Block
244    {
245        .mux = {
246           { .regs = { 0, 0, REG_8 }, .bits = { 0, 0, 31 }, },
247           { .regs = { 0, REG_8, REG_8 }, .bits = { 0, 30, 29 }, },
248        },
249    },
250    // GPIOZ Block
251    {
252        .mux = {
253            { .regs = { REG_4, REG_3, REG_3, REG_3 }, .bits = { 23, 14, 31, 19 }, },
254            { .regs = { REG_4, REG_3, REG_3, REG_3 }, .bits = { 22, 13, 30, 18 }, },
255            { .regs = { REG_4, 0, REG_3, REG_3 }, .bits = { 21, 0, 29, 17 }, },
256            { .regs = { REG_4, REG_3, REG_3, REG_3 }, .bits = { 20, 12, 28, 16 }, },
257            { .regs = { REG_4, REG_3, REG_3, REG_3 }, .bits = { 19, 11, 27, 15 }, },
258            { .regs = { REG_4, REG_3, REG_3 }, .bits = { 18, 11, 26 }, },
259            { .regs = { REG_4, REG_3, REG_3, REG_4 }, .bits = { 17, 11, 25, 9 }, },
260            { .regs = { REG_4, REG_3, REG_3, REG_4 }, .bits = { 16, 11, 24, 8 }, },
261            { .regs = { REG_4, REG_3, 0, REG_3, REG_4 }, .bits = { 15, 11, 0, 23, 7 }, },
262            { .regs = { REG_4, REG_3, 0, REG_3, REG_4 }, .bits = { 14, 11, 0, 22, 6 }, },
263            { .regs = { REG_4, REG_3, 0, 0, REG_4 }, .bits = { 13, 11, 0, 0, 5 }, },
264            { .regs = { REG_4, REG_3, 0, 0, REG_4 }, .bits = { 12, 11, 0, 0, 4 }, },
265            { .regs = { REG_4, 0, 0, 0, REG_4 }, .bits = { 11, 0, 0, 0, 3 }, },
266            { .regs = { REG_4, 0, 0, 0, REG_4 }, .bits = { 10, 0, 0, 0, 2 }, },
267            { .regs = { REG_4, REG_3 }, .bits = { 25, 21 }, },
268            { .regs = { REG_4, 0, REG_3 }, .bits = { 24, 0, 20 }, },
269        },
270    },
271    // GPIOAO Block
272    {
273        .mux = {
274            { .regs = { AO_REG, AO_REG }, .bits = { 12, 26 }, },
275            { .regs = { AO_REG, AO_REG }, .bits = { 11, 25 }, },
276            { .regs = { AO_REG, AO_REG }, .bits = { 10, 8 }, },
277            { .regs = { AO_REG, AO_REG, 0, AO_REG }, .bits = { 9, 7, 0, 22 }, },
278            { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 24, 6, 2 }, },
279            { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 23, 5, 1 }, },
280            { .regs = { 0, 0, AO_REG, AO_REG }, .bits = { 0, 0, 16, 18 }, },
281            { .regs = { AO_REG, AO_REG }, .bits = { 0, 21 }, },
282            { .regs = { AO_REG, AO_REG, AO_REG_2, AO_REG }, .bits = { 15, 14, 0, 17 }, },
283            { .regs = { AO_REG, AO_REG, AO_REG_2, AO_REG }, .bits = { 31, 4, 1, 3 }, },
284        },
285    },
286};
287
288static_assert(countof(s912_gpio_blocks) == countof(s912_pinmux_blocks), "");
289
290#undef REG_0
291#undef REG_1
292#undef REG_2
293#undef REG_3
294#undef REG_4
295#undef REG_5
296#undef REG_6
297#undef REG_7
298#undef REG_8
299#undef REG_9
300#undef AO_REG
301#undef AO_REG_2
302