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-s905x/s905x-gpio.h>
6 
7 #include "aml-gxl-gpio.h"
8 
9 namespace gpio {
10 
11 constexpr AmlGpioBlock s905x_gpio_blocks[] = {
12     // GPIOX Block
13     {
14         .pin_count = S905X_GPIOX_PINS,
15         .oen_offset = S905X_GPIOX_0EN,
16         .input_offset = S905X_GPIOX_IN,
17         .output_offset = S905X_GPIOX_OUT,
18         .output_shift = 0,
19         .mmio_index = 0,
20         .pull_offset = S905X_PULL_UP_REG4,
21         .pull_en_offset = S905X_PULL_UP_EN_REG4,
22         .pin_start = S905X_GPIOX_PIN_START,
23     },
24     // GPIODV Block
25     {
26         .pin_count = S905X_GPIODV_PINS,
27         .oen_offset = S905X_GPIODV_0EN,
28         .input_offset = S905X_GPIODV_IN,
29         .output_offset = S905X_GPIODV_OUT,
30         .output_shift = 0,
31         .mmio_index = 0,
32         .pull_offset = S905X_PULL_UP_REG0,
33         .pull_en_offset = S905X_PULL_UP_EN_REG0,
34         .pin_start = S905X_GPIODV_PIN_START,
35     },
36     // GPIOH Block
37     {
38         .pin_count = S905X_GPIOH_PINS,
39         .oen_offset = S905X_GPIOH_0EN,
40         .input_offset = S905X_GPIOH_IN,
41         .output_offset = S905X_GPIOH_OUT,
42         .output_shift = 20,
43         .mmio_index = 0,
44         .pull_offset = S905X_PULL_UP_REG1,
45         .pull_en_offset = S905X_PULL_UP_EN_REG1,
46         .pin_start = S905X_GPIOH_PIN_START,
47     },
48     // GPIOBOOT Block
49     {
50         .pin_count = S905X_GPIOBOOT_PINS,
51         .oen_offset = S905X_GPIOBOOT_0EN,
52         .input_offset = S905X_GPIOBOOT_IN,
53         .output_offset = S905X_GPIOBOOT_OUT,
54         .output_shift = 0,
55         .mmio_index = 0,
56         .pull_offset = S905X_PULL_UP_REG2,
57         .pull_en_offset = S905X_PULL_UP_EN_REG2,
58         .pin_start = S905X_GPIOBOOT_PIN_START,
59     },
60     // GPIOCARD Block
61     {
62         .pin_count = S905X_GPIOCARD_PINS,
63         .oen_offset = S905X_GPIOCARD_0EN,
64         .input_offset = S905X_GPIOCARD_IN,
65         .output_offset = S905X_GPIOCARD_OUT,
66         .output_shift = 20,
67         .mmio_index = 0,
68         .pull_offset = S905X_PULL_UP_REG2,
69         .pull_en_offset = S905X_PULL_UP_EN_REG2,
70         .pin_start = S905X_GPIOCARD_PIN_START,
71     },
72     // GPIOCLK Block
73     {
74         .pin_count = S905X_GPIOCLK_PINS,
75         .oen_offset = S905X_GPIOCLK_0EN,
76         .input_offset = S905X_GPIOCLK_IN,
77         .output_offset = S905X_GPIOCLK_OUT,
78         .output_shift = 28,
79         .mmio_index = 0,
80         .pull_offset = S905X_PULL_UP_REG3,
81         .pull_en_offset = S905X_PULL_UP_EN_REG3,
82         .pin_start = S905X_GPIOCLK_PIN_START,
83     },
84     // GPIOZ Block
85     {
86         .pin_count = S905X_GPIOZ_PINS,
87         .oen_offset = S905X_GPIOZ_0EN,
88         .input_offset = S905X_GPIOZ_IN,
89         .output_offset = S905X_GPIOZ_OUT,
90         .output_shift = 0,
91         .mmio_index = 0,
92         .pull_offset = S905X_PULL_UP_REG3,
93         .pull_en_offset = S905X_PULL_UP_EN_REG3,
94         .pin_start = S905X_GPIOZ_PIN_START,
95     },
96     // GPIOAO Block
97     {
98         .pin_count = S905X_GPIOAO_PINS,
99         .oen_offset = S905X_AO_GPIO_OEN_OUT,
100         .input_offset = S905X_AO_GPIO_IN,
101         .output_offset = S905X_AO_GPIO_OEN_OUT,
102         .output_shift = 0, // output is shared with OEN
103         .output_write_shift = 16, //OUT/EN share reg
104         .mmio_index = 1,
105         .pull_offset = 0, // not supported
106         .pull_en_offset = 0, // not supported
107         .pin_start = S905X_GPIOA0_PIN_START,
108     },
109 };
110 
111 #define REG_0 S905X_PERIPHS_PIN_MUX_0
112 #define REG_1 S905X_PERIPHS_PIN_MUX_1
113 #define REG_2 S905X_PERIPHS_PIN_MUX_2
114 #define REG_3 S905X_PERIPHS_PIN_MUX_3
115 #define REG_4 S905X_PERIPHS_PIN_MUX_4
116 #define REG_5 S905X_PERIPHS_PIN_MUX_5
117 #define REG_6 S905X_PERIPHS_PIN_MUX_6
118 #define REG_7 S905X_PERIPHS_PIN_MUX_7
119 #define REG_8 S905X_PERIPHS_PIN_MUX_8
120 #define REG_9 S905X_PERIPHS_PIN_MUX_9
121 #define AO_REG S905X_AO_RTI_PIN_MUX_REG
122 #define AO_REG_2 S905X_AO_RTI_PIN_MUX_REG2
123 
124 constexpr AmlGpioInterrupt s905x_interrupt_block = {
125     .pin_0_3_select_offset =    S905X_GPIO_0_3_PIN_SELECT,
126     .pin_4_7_select_offset =    S905X_GPIO_4_7_PIN_SELECT,
127     .edge_polarity_offset =     S905X_GPIO_INT_EDGE_POLARITY,
128     .filter_select_offset =     S905X_GPIO_FILTER_SELECT,
129     .status_offset =            S905X_GPIO_INT_STATUS,
130     .mask_offset =              S905X_GPIO_INT_MASK,
131 };
132 
133 constexpr AmlPinMuxBlock s905x_pinmux_blocks[] = {
134     // GPIOX Block
135     {
136         .mux = {
137             { .regs = { REG_5 }, .bits = { 31 }, },
138             { .regs = { REG_5 }, .bits = { 30 }, },
139             { .regs = { REG_5 }, .bits = { 29 }, },
140             { .regs = { REG_5 }, .bits = { 28 }, },
141             { .regs = { REG_5 }, .bits = { 27 }, },
142             { .regs = { REG_5 }, .bits = { 26 }, },
143             { .regs = { REG_5 }, .bits = { 25 }, },
144             { .regs = { REG_5, REG_5 }, .bits = { 24, 14 }, },
145             { .regs = { REG_5, REG_5, 0, REG_5 }, .bits = { 23, 13, 0, 3 }, },
146             { .regs = { REG_5, REG_5, 0, REG_5 }, .bits = { 22, 12, 0, 2 }, },
147             { .regs = { REG_5, REG_5, REG_5, REG_5 }, .bits = { 21, 11, 5, 1 }, },
148             { .regs = { REG_5, REG_5, REG_5, REG_5 }, .bits = { 20, 10, 4, 0 }, },
149             { .regs = { REG_5 }, .bits = { 19 }, },
150             { .regs = { REG_5 }, .bits = { 18 }, },
151             { .regs = { REG_5 }, .bits = { 17 }, },
152             { .regs = { REG_5 }, .bits = { 16 }, },
153             { .regs = { REG_5 }, .bits = { 15 }, },
154             // pinmux not specified for GPIOX_17 and GPIOX_18.
155         },
156     },
157     // GPIODV Block
158     {
159         .mux = {
160             {},
161             {},
162             {},
163             {},
164             {},
165             {},
166             {},
167             {},
168             {},
169             {},
170             {},
171             {},
172             {},
173             {},
174             {},
175             {},
176             {},
177             {},
178             {},
179             {},
180             {},
181             {},
182             {},
183             {},
184             { .regs = { REG_2, REG_2, REG_1 }, .bits = { 16, 7, 15 }, },
185             { .regs = { REG_2, REG_2, REG_1 }, .bits = { 15, 6, 14 }, },
186             { .regs = { REG_2, 0, REG_1 }, .bits = { 14, 0, 13 }, },
187             { .regs = { REG_2, 0, REG_1 }, .bits = { 13, 0, 12 }, },
188             { .regs = { REG_2, REG_1, REG_1 }, .bits = { 12, 9, 11 }, },
189             { .regs = { REG_2, REG_2, REG_1 }, .bits = { 11, 5, 10 }, },
190         },
191     },
192     // GPIOH Block
193     {
194         .mux = {
195             { .regs = { REG_6 }, .bits = { 31 }, },
196             { .regs = { REG_6 }, .bits = { 30 }, },
197             { .regs = { REG_6 }, .bits = { 29 }, },
198             {},
199             { .regs = { REG_6, REG_6 }, .bits = { 28, 27 }, },
200             {},
201             { .regs = { 0, 0, REG_6 }, .bits = { 0, 0, 26 }, },
202             { .regs = { 0, 0, REG_6, REG_6 }, .bits = { 0, 0, 25, 22 }, },
203             { .regs = { 0, 0, REG_6, REG_6 }, .bits = { 0, 0, 24, 21 }, },
204             { .regs = { 0, 0, REG_6 }, .bits = { 0, 0, 23 }, },
205         },
206     },
207     // GPIOBOOT Block
208     {
209         .mux = {
210             { .regs = { REG_7 }, .bits = { 31 }, },
211             { .regs = { REG_7 }, .bits = { 31 }, },
212             { .regs = { REG_7 }, .bits = { 31 }, },
213             { .regs = { REG_7 }, .bits = { 31 }, },
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, REG_7 }, .bits = { 30, 7 }, },
219             { .regs = { 0, REG_7 }, .bits = { 0, 6 }, },
220             { .regs = { REG_7, REG_7 }, .bits = { 29, 5 }, },
221             { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 4, 13 }, },
222             { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 3, 12 }, },
223             { .regs = { 0, REG_7, REG_7 }, .bits = { 0, 2, 11 }, },
224             { .regs = { 0, REG_7 }, .bits = { 0, 1 }, },
225         },
226     },
227     // GPIOCARD Block
228     {
229         .mux = {
230             { .regs = { REG_6 }, .bits = { 5 }, },
231             { .regs = { REG_6 }, .bits = { 4 }, },
232             { .regs = { REG_6 }, .bits = { 3 }, },
233             { .regs = { REG_6 }, .bits = { 2 }, },
234             { .regs = { REG_6, REG_6, REG_6 }, .bits = { 1, 9, 11 }, },
235             { .regs = { REG_6, REG_6, REG_6 }, .bits = { 0, 8, 10 }, },
236         },
237     },
238     // GPIOCLK Block
239     {
240         .mux = {
241            {},
242            {},
243         },
244     },
245     // GPIOZ Block
246     {
247         .mux = {
248             {},
249             {},
250             {},
251             {},
252             {},
253             {},
254             {},
255             {},
256             {},
257             {},
258             {},
259             {},
260             {},
261             {},
262             { .regs = { REG_4, REG_3 }, .bits = { 25, 21 }, },
263             { .regs = { REG_4, 0, REG_3 }, .bits = { 24, 0, 20 }, },
264         },
265     },
266     // GPIOAO Block
267     {
268         .mux = {
269             { .regs = { AO_REG, AO_REG }, .bits = { 12, 26 }, },
270             { .regs = { AO_REG, AO_REG }, .bits = { 11, 25 }, },
271             { .regs = { AO_REG, AO_REG }, .bits = { 10, 8 }, },
272             { .regs = { AO_REG, AO_REG, 0, AO_REG }, .bits = { 9, 7, 0, 22 }, },
273             { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 24, 6, 2 }, },
274             { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 23, 5, 1 }, },
275             { .regs = { 0, 0, AO_REG, AO_REG }, .bits = { 0, 0, 16, 18 }, },
276             { .regs = { AO_REG, AO_REG }, .bits = { 0, 21 }, },
277             { .regs = { AO_REG, AO_REG, AO_REG_2, AO_REG }, .bits = { 15, 14, 0, 17 }, },
278             { .regs = { AO_REG, AO_REG, AO_REG_2, AO_REG }, .bits = { 31, 4, 1, 3 }, },
279         },
280     },
281 };
282 
283 static_assert(countof(s905x_gpio_blocks) == countof(s905x_pinmux_blocks), "");
284 
285 #undef REG_0
286 #undef REG_1
287 #undef REG_2
288 #undef REG_3
289 #undef REG_4
290 #undef REG_5
291 #undef REG_6
292 #undef REG_7
293 #undef REG_8
294 #undef REG_9
295 #undef AO_REG
296 #undef AO_REG_2
297 
298 }  // namespace gpio
299