1 /*
2 * ASPEED GPIO Controller
3 *
4 * Copyright (C) 2017-2019 IBM Corp.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "qemu/osdep.h"
10 #include "qemu/host-utils.h"
11 #include "qemu/log.h"
12 #include "hw/gpio/aspeed_gpio.h"
13 #include "hw/misc/aspeed_scu.h"
14 #include "qapi/error.h"
15 #include "qapi/visitor.h"
16 #include "hw/irq.h"
17 #include "migration/vmstate.h"
18 #include "trace.h"
19 #include "hw/registerfields.h"
20
21 #define GPIOS_PER_GROUP 8
22
23 /* GPIO Source Types */
24 #define ASPEED_CMD_SRC_MASK 0x01010101
25 #define ASPEED_SOURCE_ARM 0
26 #define ASPEED_SOURCE_LPC 1
27 #define ASPEED_SOURCE_COPROCESSOR 2
28 #define ASPEED_SOURCE_RESERVED 3
29
30 /* GPIO Interrupt Triggers */
31 /*
32 * For each set of gpios there are three sensitivity registers that control
33 * the interrupt trigger mode.
34 *
35 * | 2 | 1 | 0 | trigger mode
36 * -----------------------------
37 * | 0 | 0 | 0 | falling-edge
38 * | 0 | 0 | 1 | rising-edge
39 * | 0 | 1 | 0 | level-low
40 * | 0 | 1 | 1 | level-high
41 * | 1 | X | X | dual-edge
42 */
43 #define ASPEED_FALLING_EDGE 0
44 #define ASPEED_RISING_EDGE 1
45 #define ASPEED_LEVEL_LOW 2
46 #define ASPEED_LEVEL_HIGH 3
47 #define ASPEED_DUAL_EDGE 4
48
49 /* GPIO Register Address Offsets */
50 #define GPIO_ABCD_DATA_VALUE (0x000 >> 2)
51 #define GPIO_ABCD_DIRECTION (0x004 >> 2)
52 #define GPIO_ABCD_INT_ENABLE (0x008 >> 2)
53 #define GPIO_ABCD_INT_SENS_0 (0x00C >> 2)
54 #define GPIO_ABCD_INT_SENS_1 (0x010 >> 2)
55 #define GPIO_ABCD_INT_SENS_2 (0x014 >> 2)
56 #define GPIO_ABCD_INT_STATUS (0x018 >> 2)
57 #define GPIO_ABCD_RESET_TOLERANT (0x01C >> 2)
58 #define GPIO_EFGH_DATA_VALUE (0x020 >> 2)
59 #define GPIO_EFGH_DIRECTION (0x024 >> 2)
60 #define GPIO_EFGH_INT_ENABLE (0x028 >> 2)
61 #define GPIO_EFGH_INT_SENS_0 (0x02C >> 2)
62 #define GPIO_EFGH_INT_SENS_1 (0x030 >> 2)
63 #define GPIO_EFGH_INT_SENS_2 (0x034 >> 2)
64 #define GPIO_EFGH_INT_STATUS (0x038 >> 2)
65 #define GPIO_EFGH_RESET_TOLERANT (0x03C >> 2)
66 #define GPIO_ABCD_DEBOUNCE_1 (0x040 >> 2)
67 #define GPIO_ABCD_DEBOUNCE_2 (0x044 >> 2)
68 #define GPIO_EFGH_DEBOUNCE_1 (0x048 >> 2)
69 #define GPIO_EFGH_DEBOUNCE_2 (0x04C >> 2)
70 #define GPIO_DEBOUNCE_TIME_1 (0x050 >> 2)
71 #define GPIO_DEBOUNCE_TIME_2 (0x054 >> 2)
72 #define GPIO_DEBOUNCE_TIME_3 (0x058 >> 2)
73 #define GPIO_ABCD_COMMAND_SRC_0 (0x060 >> 2)
74 #define GPIO_ABCD_COMMAND_SRC_1 (0x064 >> 2)
75 #define GPIO_EFGH_COMMAND_SRC_0 (0x068 >> 2)
76 #define GPIO_EFGH_COMMAND_SRC_1 (0x06C >> 2)
77 #define GPIO_IJKL_DATA_VALUE (0x070 >> 2)
78 #define GPIO_IJKL_DIRECTION (0x074 >> 2)
79 #define GPIO_MNOP_DATA_VALUE (0x078 >> 2)
80 #define GPIO_MNOP_DIRECTION (0x07C >> 2)
81 #define GPIO_QRST_DATA_VALUE (0x080 >> 2)
82 #define GPIO_QRST_DIRECTION (0x084 >> 2)
83 #define GPIO_UVWX_DATA_VALUE (0x088 >> 2)
84 #define GPIO_UVWX_DIRECTION (0x08C >> 2)
85 #define GPIO_IJKL_COMMAND_SRC_0 (0x090 >> 2)
86 #define GPIO_IJKL_COMMAND_SRC_1 (0x094 >> 2)
87 #define GPIO_IJKL_INT_ENABLE (0x098 >> 2)
88 #define GPIO_IJKL_INT_SENS_0 (0x09C >> 2)
89 #define GPIO_IJKL_INT_SENS_1 (0x0A0 >> 2)
90 #define GPIO_IJKL_INT_SENS_2 (0x0A4 >> 2)
91 #define GPIO_IJKL_INT_STATUS (0x0A8 >> 2)
92 #define GPIO_IJKL_RESET_TOLERANT (0x0AC >> 2)
93 #define GPIO_IJKL_DEBOUNCE_1 (0x0B0 >> 2)
94 #define GPIO_IJKL_DEBOUNCE_2 (0x0B4 >> 2)
95 #define GPIO_IJKL_INPUT_MASK (0x0B8 >> 2)
96 #define GPIO_ABCD_DATA_READ (0x0C0 >> 2)
97 #define GPIO_EFGH_DATA_READ (0x0C4 >> 2)
98 #define GPIO_IJKL_DATA_READ (0x0C8 >> 2)
99 #define GPIO_MNOP_DATA_READ (0x0CC >> 2)
100 #define GPIO_QRST_DATA_READ (0x0D0 >> 2)
101 #define GPIO_UVWX_DATA_READ (0x0D4 >> 2)
102 #define GPIO_YZAAAB_DATA_READ (0x0D8 >> 2)
103 #define GPIO_AC_DATA_READ (0x0DC >> 2)
104 #define GPIO_MNOP_COMMAND_SRC_0 (0x0E0 >> 2)
105 #define GPIO_MNOP_COMMAND_SRC_1 (0x0E4 >> 2)
106 #define GPIO_MNOP_INT_ENABLE (0x0E8 >> 2)
107 #define GPIO_MNOP_INT_SENS_0 (0x0EC >> 2)
108 #define GPIO_MNOP_INT_SENS_1 (0x0F0 >> 2)
109 #define GPIO_MNOP_INT_SENS_2 (0x0F4 >> 2)
110 #define GPIO_MNOP_INT_STATUS (0x0F8 >> 2)
111 #define GPIO_MNOP_RESET_TOLERANT (0x0FC >> 2)
112 #define GPIO_MNOP_DEBOUNCE_1 (0x100 >> 2)
113 #define GPIO_MNOP_DEBOUNCE_2 (0x104 >> 2)
114 #define GPIO_MNOP_INPUT_MASK (0x108 >> 2)
115 #define GPIO_QRST_COMMAND_SRC_0 (0x110 >> 2)
116 #define GPIO_QRST_COMMAND_SRC_1 (0x114 >> 2)
117 #define GPIO_QRST_INT_ENABLE (0x118 >> 2)
118 #define GPIO_QRST_INT_SENS_0 (0x11C >> 2)
119 #define GPIO_QRST_INT_SENS_1 (0x120 >> 2)
120 #define GPIO_QRST_INT_SENS_2 (0x124 >> 2)
121 #define GPIO_QRST_INT_STATUS (0x128 >> 2)
122 #define GPIO_QRST_RESET_TOLERANT (0x12C >> 2)
123 #define GPIO_QRST_DEBOUNCE_1 (0x130 >> 2)
124 #define GPIO_QRST_DEBOUNCE_2 (0x134 >> 2)
125 #define GPIO_QRST_INPUT_MASK (0x138 >> 2)
126 #define GPIO_UVWX_COMMAND_SRC_0 (0x140 >> 2)
127 #define GPIO_UVWX_COMMAND_SRC_1 (0x144 >> 2)
128 #define GPIO_UVWX_INT_ENABLE (0x148 >> 2)
129 #define GPIO_UVWX_INT_SENS_0 (0x14C >> 2)
130 #define GPIO_UVWX_INT_SENS_1 (0x150 >> 2)
131 #define GPIO_UVWX_INT_SENS_2 (0x154 >> 2)
132 #define GPIO_UVWX_INT_STATUS (0x158 >> 2)
133 #define GPIO_UVWX_RESET_TOLERANT (0x15C >> 2)
134 #define GPIO_UVWX_DEBOUNCE_1 (0x160 >> 2)
135 #define GPIO_UVWX_DEBOUNCE_2 (0x164 >> 2)
136 #define GPIO_UVWX_INPUT_MASK (0x168 >> 2)
137 #define GPIO_YZAAAB_COMMAND_SRC_0 (0x170 >> 2)
138 #define GPIO_YZAAAB_COMMAND_SRC_1 (0x174 >> 2)
139 #define GPIO_YZAAAB_INT_ENABLE (0x178 >> 2)
140 #define GPIO_YZAAAB_INT_SENS_0 (0x17C >> 2)
141 #define GPIO_YZAAAB_INT_SENS_1 (0x180 >> 2)
142 #define GPIO_YZAAAB_INT_SENS_2 (0x184 >> 2)
143 #define GPIO_YZAAAB_INT_STATUS (0x188 >> 2)
144 #define GPIO_YZAAAB_RESET_TOLERANT (0x18C >> 2)
145 #define GPIO_YZAAAB_DEBOUNCE_1 (0x190 >> 2)
146 #define GPIO_YZAAAB_DEBOUNCE_2 (0x194 >> 2)
147 #define GPIO_YZAAAB_INPUT_MASK (0x198 >> 2)
148 #define GPIO_AC_COMMAND_SRC_0 (0x1A0 >> 2)
149 #define GPIO_AC_COMMAND_SRC_1 (0x1A4 >> 2)
150 #define GPIO_AC_INT_ENABLE (0x1A8 >> 2)
151 #define GPIO_AC_INT_SENS_0 (0x1AC >> 2)
152 #define GPIO_AC_INT_SENS_1 (0x1B0 >> 2)
153 #define GPIO_AC_INT_SENS_2 (0x1B4 >> 2)
154 #define GPIO_AC_INT_STATUS (0x1B8 >> 2)
155 #define GPIO_AC_RESET_TOLERANT (0x1BC >> 2)
156 #define GPIO_AC_DEBOUNCE_1 (0x1C0 >> 2)
157 #define GPIO_AC_DEBOUNCE_2 (0x1C4 >> 2)
158 #define GPIO_AC_INPUT_MASK (0x1C8 >> 2)
159 #define GPIO_ABCD_INPUT_MASK (0x1D0 >> 2)
160 #define GPIO_EFGH_INPUT_MASK (0x1D4 >> 2)
161 #define GPIO_YZAAAB_DATA_VALUE (0x1E0 >> 2)
162 #define GPIO_YZAAAB_DIRECTION (0x1E4 >> 2)
163 #define GPIO_AC_DATA_VALUE (0x1E8 >> 2)
164 #define GPIO_AC_DIRECTION (0x1EC >> 2)
165 #define GPIO_3_3V_MEM_SIZE 0x1F0
166 #define GPIO_3_3V_REG_ARRAY_SIZE (GPIO_3_3V_MEM_SIZE >> 2)
167
168 /* AST2600 only - 1.8V gpios */
169 /*
170 * The AST2600 two copies of the GPIO controller: the same 3.3V gpios as the
171 * AST2400 (memory offsets 0x0-0x198) and a second controller with 1.8V gpios
172 * (memory offsets 0x800-0x9D4).
173 */
174 #define GPIO_1_8V_ABCD_DATA_VALUE (0x000 >> 2)
175 #define GPIO_1_8V_ABCD_DIRECTION (0x004 >> 2)
176 #define GPIO_1_8V_ABCD_INT_ENABLE (0x008 >> 2)
177 #define GPIO_1_8V_ABCD_INT_SENS_0 (0x00C >> 2)
178 #define GPIO_1_8V_ABCD_INT_SENS_1 (0x010 >> 2)
179 #define GPIO_1_8V_ABCD_INT_SENS_2 (0x014 >> 2)
180 #define GPIO_1_8V_ABCD_INT_STATUS (0x018 >> 2)
181 #define GPIO_1_8V_ABCD_RESET_TOLERANT (0x01C >> 2)
182 #define GPIO_1_8V_E_DATA_VALUE (0x020 >> 2)
183 #define GPIO_1_8V_E_DIRECTION (0x024 >> 2)
184 #define GPIO_1_8V_E_INT_ENABLE (0x028 >> 2)
185 #define GPIO_1_8V_E_INT_SENS_0 (0x02C >> 2)
186 #define GPIO_1_8V_E_INT_SENS_1 (0x030 >> 2)
187 #define GPIO_1_8V_E_INT_SENS_2 (0x034 >> 2)
188 #define GPIO_1_8V_E_INT_STATUS (0x038 >> 2)
189 #define GPIO_1_8V_E_RESET_TOLERANT (0x03C >> 2)
190 #define GPIO_1_8V_ABCD_DEBOUNCE_1 (0x040 >> 2)
191 #define GPIO_1_8V_ABCD_DEBOUNCE_2 (0x044 >> 2)
192 #define GPIO_1_8V_E_DEBOUNCE_1 (0x048 >> 2)
193 #define GPIO_1_8V_E_DEBOUNCE_2 (0x04C >> 2)
194 #define GPIO_1_8V_DEBOUNCE_TIME_1 (0x050 >> 2)
195 #define GPIO_1_8V_DEBOUNCE_TIME_2 (0x054 >> 2)
196 #define GPIO_1_8V_DEBOUNCE_TIME_3 (0x058 >> 2)
197 #define GPIO_1_8V_ABCD_COMMAND_SRC_0 (0x060 >> 2)
198 #define GPIO_1_8V_ABCD_COMMAND_SRC_1 (0x064 >> 2)
199 #define GPIO_1_8V_E_COMMAND_SRC_0 (0x068 >> 2)
200 #define GPIO_1_8V_E_COMMAND_SRC_1 (0x06C >> 2)
201 #define GPIO_1_8V_ABCD_DATA_READ (0x0C0 >> 2)
202 #define GPIO_1_8V_E_DATA_READ (0x0C4 >> 2)
203 #define GPIO_1_8V_ABCD_INPUT_MASK (0x1D0 >> 2)
204 #define GPIO_1_8V_E_INPUT_MASK (0x1D4 >> 2)
205 #define GPIO_1_8V_MEM_SIZE 0x1D8
206 #define GPIO_1_8V_REG_ARRAY_SIZE (GPIO_1_8V_MEM_SIZE >> 2)
207
208 /*
209 * GPIO index mode support
210 * It only supports write operation
211 */
212 REG32(GPIO_INDEX_REG, 0x2AC)
213 FIELD(GPIO_INDEX_REG, NUMBER, 0, 8)
214 FIELD(GPIO_INDEX_REG, COMMAND, 12, 1)
215 FIELD(GPIO_INDEX_REG, TYPE, 16, 4)
216 FIELD(GPIO_INDEX_REG, DATA_VALUE, 20, 1)
217 FIELD(GPIO_INDEX_REG, DIRECTION, 20, 1)
218 FIELD(GPIO_INDEX_REG, INT_ENABLE, 20, 1)
219 FIELD(GPIO_INDEX_REG, INT_SENS_0, 21, 1)
220 FIELD(GPIO_INDEX_REG, INT_SENS_1, 22, 1)
221 FIELD(GPIO_INDEX_REG, INT_SENS_2, 23, 1)
222 FIELD(GPIO_INDEX_REG, INT_STATUS, 24, 1)
223 FIELD(GPIO_INDEX_REG, DEBOUNCE_1, 20, 1)
224 FIELD(GPIO_INDEX_REG, DEBOUNCE_2, 21, 1)
225 FIELD(GPIO_INDEX_REG, RESET_TOLERANT, 20, 1)
226 FIELD(GPIO_INDEX_REG, COMMAND_SRC_0, 20, 1)
227 FIELD(GPIO_INDEX_REG, COMMAND_SRC_1, 21, 1)
228 FIELD(GPIO_INDEX_REG, INPUT_MASK, 20, 1)
229
230 /* AST2700 GPIO Register Address Offsets */
231 REG32(GPIO_2700_DEBOUNCE_TIME_1, 0x000)
232 REG32(GPIO_2700_DEBOUNCE_TIME_2, 0x004)
233 REG32(GPIO_2700_DEBOUNCE_TIME_3, 0x008)
234 REG32(GPIO_2700_INT_STATUS_1, 0x100)
235 REG32(GPIO_2700_INT_STATUS_2, 0x104)
236 REG32(GPIO_2700_INT_STATUS_3, 0x108)
237 REG32(GPIO_2700_INT_STATUS_4, 0x10C)
238 REG32(GPIO_2700_INT_STATUS_5, 0x110)
239 REG32(GPIO_2700_INT_STATUS_6, 0x114)
240 REG32(GPIO_2700_INT_STATUS_7, 0x118)
241 /* GPIOA0 - GPIOAA7 Control Register */
242 REG32(GPIO_A0_CONTROL, 0x180)
243 SHARED_FIELD(GPIO_CONTROL_OUT_DATA, 0, 1)
244 SHARED_FIELD(GPIO_CONTROL_DIRECTION, 1, 1)
245 SHARED_FIELD(GPIO_CONTROL_INT_ENABLE, 2, 1)
246 SHARED_FIELD(GPIO_CONTROL_INT_SENS_0, 3, 1)
247 SHARED_FIELD(GPIO_CONTROL_INT_SENS_1, 4, 1)
248 SHARED_FIELD(GPIO_CONTROL_INT_SENS_2, 5, 1)
249 SHARED_FIELD(GPIO_CONTROL_RESET_TOLERANCE, 6, 1)
250 SHARED_FIELD(GPIO_CONTROL_DEBOUNCE_1, 7, 1)
251 SHARED_FIELD(GPIO_CONTROL_DEBOUNCE_2, 8, 1)
252 SHARED_FIELD(GPIO_CONTROL_INPUT_MASK, 9, 1)
253 SHARED_FIELD(GPIO_CONTROL_BLINK_COUNTER_1, 10, 1)
254 SHARED_FIELD(GPIO_CONTROL_BLINK_COUNTER_2, 11, 1)
255 SHARED_FIELD(GPIO_CONTROL_INT_STATUS, 12, 1)
256 SHARED_FIELD(GPIO_CONTROL_IN_DATA, 13, 1)
257 SHARED_FIELD(GPIO_CONTROL_RESERVED, 14, 18)
258 REG32(GPIO_AA7_CONTROL, 0x4DC)
259 #define GPIO_2700_MEM_SIZE 0x4E0
260 #define GPIO_2700_REG_ARRAY_SIZE (GPIO_2700_MEM_SIZE >> 2)
261
aspeed_evaluate_irq(GPIOSets * regs,int gpio_prev_high,int gpio)262 static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
263 {
264 uint32_t falling_edge = 0, rising_edge = 0;
265 uint32_t int_trigger = extract32(regs->int_sens_0, gpio, 1)
266 | extract32(regs->int_sens_1, gpio, 1) << 1
267 | extract32(regs->int_sens_2, gpio, 1) << 2;
268 uint32_t gpio_curr_high = extract32(regs->data_value, gpio, 1);
269 uint32_t gpio_int_enabled = extract32(regs->int_enable, gpio, 1);
270
271 if (!gpio_int_enabled) {
272 return 0;
273 }
274
275 /* Detect edges */
276 if (gpio_curr_high && !gpio_prev_high) {
277 rising_edge = 1;
278 } else if (!gpio_curr_high && gpio_prev_high) {
279 falling_edge = 1;
280 }
281
282 if (((int_trigger == ASPEED_FALLING_EDGE) && falling_edge) ||
283 ((int_trigger == ASPEED_RISING_EDGE) && rising_edge) ||
284 ((int_trigger == ASPEED_LEVEL_LOW) && !gpio_curr_high) ||
285 ((int_trigger == ASPEED_LEVEL_HIGH) && gpio_curr_high) ||
286 ((int_trigger >= ASPEED_DUAL_EDGE) && (rising_edge || falling_edge)))
287 {
288 regs->int_status = deposit32(regs->int_status, gpio, 1, 1);
289 return 1;
290 }
291 return 0;
292 }
293
294 #define nested_struct_index(ta, pa, m, tb, pb) \
295 (pb - ((tb *)(((char *)pa) + offsetof(ta, m))))
296
aspeed_gpio_set_idx(AspeedGPIOState * s,GPIOSets * regs)297 static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, GPIOSets *regs)
298 {
299 return nested_struct_index(AspeedGPIOState, s, sets, GPIOSets, regs);
300 }
301
aspeed_gpio_update(AspeedGPIOState * s,GPIOSets * regs,uint32_t value,uint32_t mode_mask)302 static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
303 uint32_t value, uint32_t mode_mask)
304 {
305 uint32_t input_mask = regs->input_mask;
306 uint32_t direction = regs->direction;
307 uint32_t old = regs->data_value;
308 uint32_t new = value;
309 uint32_t diff;
310 int gpio;
311
312 diff = (old ^ new);
313 diff &= mode_mask;
314 if (diff) {
315 for (gpio = 0; gpio < ASPEED_GPIOS_PER_SET; gpio++) {
316 uint32_t mask = 1U << gpio;
317
318 /* If the gpio needs to be updated... */
319 if (!(diff & mask)) {
320 continue;
321 }
322
323 /* ...and we're output or not input-masked... */
324 if (!(direction & mask) && (input_mask & mask)) {
325 continue;
326 }
327
328 /* ...then update the state. */
329 if (mask & new) {
330 regs->data_value |= mask;
331 } else {
332 regs->data_value &= ~mask;
333 }
334
335 /* If the gpio is set to output... */
336 if (direction & mask) {
337 /* ...trigger the line-state IRQ */
338 ptrdiff_t set = aspeed_gpio_set_idx(s, regs);
339 qemu_set_irq(s->gpios[set][gpio], !!(new & mask));
340 } else {
341 /* ...otherwise if we meet the line's current IRQ policy... */
342 if (aspeed_evaluate_irq(regs, old & mask, gpio)) {
343 /* ...trigger the VIC IRQ */
344 s->pending++;
345 }
346 }
347 }
348 }
349 qemu_set_irq(s->irq, !!(s->pending));
350 }
351
aspeed_gpio_get_pin_level(AspeedGPIOState * s,uint32_t set_idx,uint32_t pin)352 static bool aspeed_gpio_get_pin_level(AspeedGPIOState *s, uint32_t set_idx,
353 uint32_t pin)
354 {
355 uint32_t reg_val;
356 uint32_t pin_mask = 1 << pin;
357
358 reg_val = s->sets[set_idx].data_value;
359
360 return !!(reg_val & pin_mask);
361 }
362
aspeed_gpio_set_pin_level(AspeedGPIOState * s,uint32_t set_idx,uint32_t pin,bool level)363 static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, uint32_t set_idx,
364 uint32_t pin, bool level)
365 {
366 uint32_t value = s->sets[set_idx].data_value;
367 uint32_t pin_mask = 1 << pin;
368
369 if (level) {
370 value |= pin_mask;
371 } else {
372 value &= ~pin_mask;
373 }
374
375 aspeed_gpio_update(s, &s->sets[set_idx], value,
376 ~s->sets[set_idx].direction);
377 }
378
379 /*
380 * | src_1 | src_2 | source |
381 * |-----------------------------|
382 * | 0 | 0 | ARM |
383 * | 0 | 1 | LPC |
384 * | 1 | 0 | Coprocessor|
385 * | 1 | 1 | Reserved |
386 *
387 * Once the source of a set is programmed, corresponding bits in the
388 * data_value, direction, interrupt [enable, sens[0-2]], reset_tol and
389 * debounce registers can only be written by the source.
390 *
391 * Source is ARM by default
392 * only bits 24, 16, 8, and 0 can be set
393 *
394 * we don't currently have a model for the LPC or Coprocessor
395 */
update_value_control_source(GPIOSets * regs,uint32_t old_value,uint32_t value)396 static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
397 uint32_t value)
398 {
399 int i;
400 int cmd_source;
401
402 /* assume the source is always ARM for now */
403 int source = ASPEED_SOURCE_ARM;
404
405 uint32_t new_value = 0;
406
407 /* for each group in set */
408 for (i = 0; i < ASPEED_GPIOS_PER_SET; i += GPIOS_PER_GROUP) {
409 cmd_source = extract32(regs->cmd_source_0, i, 1)
410 | (extract32(regs->cmd_source_1, i, 1) << 1);
411
412 if (source == cmd_source) {
413 new_value |= (0xff << i) & value;
414 } else {
415 new_value |= (0xff << i) & old_value;
416 }
417 }
418 return new_value;
419 }
420
421 static const AspeedGPIOReg aspeed_3_3v_gpios[GPIO_3_3V_REG_ARRAY_SIZE] = {
422 /* Set ABCD */
423 [GPIO_ABCD_DATA_VALUE] = { 0, gpio_reg_data_value },
424 [GPIO_ABCD_DIRECTION] = { 0, gpio_reg_direction },
425 [GPIO_ABCD_INT_ENABLE] = { 0, gpio_reg_int_enable },
426 [GPIO_ABCD_INT_SENS_0] = { 0, gpio_reg_int_sens_0 },
427 [GPIO_ABCD_INT_SENS_1] = { 0, gpio_reg_int_sens_1 },
428 [GPIO_ABCD_INT_SENS_2] = { 0, gpio_reg_int_sens_2 },
429 [GPIO_ABCD_INT_STATUS] = { 0, gpio_reg_int_status },
430 [GPIO_ABCD_RESET_TOLERANT] = { 0, gpio_reg_reset_tolerant },
431 [GPIO_ABCD_DEBOUNCE_1] = { 0, gpio_reg_debounce_1 },
432 [GPIO_ABCD_DEBOUNCE_2] = { 0, gpio_reg_debounce_2 },
433 [GPIO_ABCD_COMMAND_SRC_0] = { 0, gpio_reg_cmd_source_0 },
434 [GPIO_ABCD_COMMAND_SRC_1] = { 0, gpio_reg_cmd_source_1 },
435 [GPIO_ABCD_DATA_READ] = { 0, gpio_reg_data_read },
436 [GPIO_ABCD_INPUT_MASK] = { 0, gpio_reg_input_mask },
437 /* Set EFGH */
438 [GPIO_EFGH_DATA_VALUE] = { 1, gpio_reg_data_value },
439 [GPIO_EFGH_DIRECTION] = { 1, gpio_reg_direction },
440 [GPIO_EFGH_INT_ENABLE] = { 1, gpio_reg_int_enable },
441 [GPIO_EFGH_INT_SENS_0] = { 1, gpio_reg_int_sens_0 },
442 [GPIO_EFGH_INT_SENS_1] = { 1, gpio_reg_int_sens_1 },
443 [GPIO_EFGH_INT_SENS_2] = { 1, gpio_reg_int_sens_2 },
444 [GPIO_EFGH_INT_STATUS] = { 1, gpio_reg_int_status },
445 [GPIO_EFGH_RESET_TOLERANT] = { 1, gpio_reg_reset_tolerant },
446 [GPIO_EFGH_DEBOUNCE_1] = { 1, gpio_reg_debounce_1 },
447 [GPIO_EFGH_DEBOUNCE_2] = { 1, gpio_reg_debounce_2 },
448 [GPIO_EFGH_COMMAND_SRC_0] = { 1, gpio_reg_cmd_source_0 },
449 [GPIO_EFGH_COMMAND_SRC_1] = { 1, gpio_reg_cmd_source_1 },
450 [GPIO_EFGH_DATA_READ] = { 1, gpio_reg_data_read },
451 [GPIO_EFGH_INPUT_MASK] = { 1, gpio_reg_input_mask },
452 /* Set IJKL */
453 [GPIO_IJKL_DATA_VALUE] = { 2, gpio_reg_data_value },
454 [GPIO_IJKL_DIRECTION] = { 2, gpio_reg_direction },
455 [GPIO_IJKL_INT_ENABLE] = { 2, gpio_reg_int_enable },
456 [GPIO_IJKL_INT_SENS_0] = { 2, gpio_reg_int_sens_0 },
457 [GPIO_IJKL_INT_SENS_1] = { 2, gpio_reg_int_sens_1 },
458 [GPIO_IJKL_INT_SENS_2] = { 2, gpio_reg_int_sens_2 },
459 [GPIO_IJKL_INT_STATUS] = { 2, gpio_reg_int_status },
460 [GPIO_IJKL_RESET_TOLERANT] = { 2, gpio_reg_reset_tolerant },
461 [GPIO_IJKL_DEBOUNCE_1] = { 2, gpio_reg_debounce_1 },
462 [GPIO_IJKL_DEBOUNCE_2] = { 2, gpio_reg_debounce_2 },
463 [GPIO_IJKL_COMMAND_SRC_0] = { 2, gpio_reg_cmd_source_0 },
464 [GPIO_IJKL_COMMAND_SRC_1] = { 2, gpio_reg_cmd_source_1 },
465 [GPIO_IJKL_DATA_READ] = { 2, gpio_reg_data_read },
466 [GPIO_IJKL_INPUT_MASK] = { 2, gpio_reg_input_mask },
467 /* Set MNOP */
468 [GPIO_MNOP_DATA_VALUE] = { 3, gpio_reg_data_value },
469 [GPIO_MNOP_DIRECTION] = { 3, gpio_reg_direction },
470 [GPIO_MNOP_INT_ENABLE] = { 3, gpio_reg_int_enable },
471 [GPIO_MNOP_INT_SENS_0] = { 3, gpio_reg_int_sens_0 },
472 [GPIO_MNOP_INT_SENS_1] = { 3, gpio_reg_int_sens_1 },
473 [GPIO_MNOP_INT_SENS_2] = { 3, gpio_reg_int_sens_2 },
474 [GPIO_MNOP_INT_STATUS] = { 3, gpio_reg_int_status },
475 [GPIO_MNOP_RESET_TOLERANT] = { 3, gpio_reg_reset_tolerant },
476 [GPIO_MNOP_DEBOUNCE_1] = { 3, gpio_reg_debounce_1 },
477 [GPIO_MNOP_DEBOUNCE_2] = { 3, gpio_reg_debounce_2 },
478 [GPIO_MNOP_COMMAND_SRC_0] = { 3, gpio_reg_cmd_source_0 },
479 [GPIO_MNOP_COMMAND_SRC_1] = { 3, gpio_reg_cmd_source_1 },
480 [GPIO_MNOP_DATA_READ] = { 3, gpio_reg_data_read },
481 [GPIO_MNOP_INPUT_MASK] = { 3, gpio_reg_input_mask },
482 /* Set QRST */
483 [GPIO_QRST_DATA_VALUE] = { 4, gpio_reg_data_value },
484 [GPIO_QRST_DIRECTION] = { 4, gpio_reg_direction },
485 [GPIO_QRST_INT_ENABLE] = { 4, gpio_reg_int_enable },
486 [GPIO_QRST_INT_SENS_0] = { 4, gpio_reg_int_sens_0 },
487 [GPIO_QRST_INT_SENS_1] = { 4, gpio_reg_int_sens_1 },
488 [GPIO_QRST_INT_SENS_2] = { 4, gpio_reg_int_sens_2 },
489 [GPIO_QRST_INT_STATUS] = { 4, gpio_reg_int_status },
490 [GPIO_QRST_RESET_TOLERANT] = { 4, gpio_reg_reset_tolerant },
491 [GPIO_QRST_DEBOUNCE_1] = { 4, gpio_reg_debounce_1 },
492 [GPIO_QRST_DEBOUNCE_2] = { 4, gpio_reg_debounce_2 },
493 [GPIO_QRST_COMMAND_SRC_0] = { 4, gpio_reg_cmd_source_0 },
494 [GPIO_QRST_COMMAND_SRC_1] = { 4, gpio_reg_cmd_source_1 },
495 [GPIO_QRST_DATA_READ] = { 4, gpio_reg_data_read },
496 [GPIO_QRST_INPUT_MASK] = { 4, gpio_reg_input_mask },
497 /* Set UVWX */
498 [GPIO_UVWX_DATA_VALUE] = { 5, gpio_reg_data_value },
499 [GPIO_UVWX_DIRECTION] = { 5, gpio_reg_direction },
500 [GPIO_UVWX_INT_ENABLE] = { 5, gpio_reg_int_enable },
501 [GPIO_UVWX_INT_SENS_0] = { 5, gpio_reg_int_sens_0 },
502 [GPIO_UVWX_INT_SENS_1] = { 5, gpio_reg_int_sens_1 },
503 [GPIO_UVWX_INT_SENS_2] = { 5, gpio_reg_int_sens_2 },
504 [GPIO_UVWX_INT_STATUS] = { 5, gpio_reg_int_status },
505 [GPIO_UVWX_RESET_TOLERANT] = { 5, gpio_reg_reset_tolerant },
506 [GPIO_UVWX_DEBOUNCE_1] = { 5, gpio_reg_debounce_1 },
507 [GPIO_UVWX_DEBOUNCE_2] = { 5, gpio_reg_debounce_2 },
508 [GPIO_UVWX_COMMAND_SRC_0] = { 5, gpio_reg_cmd_source_0 },
509 [GPIO_UVWX_COMMAND_SRC_1] = { 5, gpio_reg_cmd_source_1 },
510 [GPIO_UVWX_DATA_READ] = { 5, gpio_reg_data_read },
511 [GPIO_UVWX_INPUT_MASK] = { 5, gpio_reg_input_mask },
512 /* Set YZAAAB */
513 [GPIO_YZAAAB_DATA_VALUE] = { 6, gpio_reg_data_value },
514 [GPIO_YZAAAB_DIRECTION] = { 6, gpio_reg_direction },
515 [GPIO_YZAAAB_INT_ENABLE] = { 6, gpio_reg_int_enable },
516 [GPIO_YZAAAB_INT_SENS_0] = { 6, gpio_reg_int_sens_0 },
517 [GPIO_YZAAAB_INT_SENS_1] = { 6, gpio_reg_int_sens_1 },
518 [GPIO_YZAAAB_INT_SENS_2] = { 6, gpio_reg_int_sens_2 },
519 [GPIO_YZAAAB_INT_STATUS] = { 6, gpio_reg_int_status },
520 [GPIO_YZAAAB_RESET_TOLERANT] = { 6, gpio_reg_reset_tolerant },
521 [GPIO_YZAAAB_DEBOUNCE_1] = { 6, gpio_reg_debounce_1 },
522 [GPIO_YZAAAB_DEBOUNCE_2] = { 6, gpio_reg_debounce_2 },
523 [GPIO_YZAAAB_COMMAND_SRC_0] = { 6, gpio_reg_cmd_source_0 },
524 [GPIO_YZAAAB_COMMAND_SRC_1] = { 6, gpio_reg_cmd_source_1 },
525 [GPIO_YZAAAB_DATA_READ] = { 6, gpio_reg_data_read },
526 [GPIO_YZAAAB_INPUT_MASK] = { 6, gpio_reg_input_mask },
527 /* Set AC (ast2500 only) */
528 [GPIO_AC_DATA_VALUE] = { 7, gpio_reg_data_value },
529 [GPIO_AC_DIRECTION] = { 7, gpio_reg_direction },
530 [GPIO_AC_INT_ENABLE] = { 7, gpio_reg_int_enable },
531 [GPIO_AC_INT_SENS_0] = { 7, gpio_reg_int_sens_0 },
532 [GPIO_AC_INT_SENS_1] = { 7, gpio_reg_int_sens_1 },
533 [GPIO_AC_INT_SENS_2] = { 7, gpio_reg_int_sens_2 },
534 [GPIO_AC_INT_STATUS] = { 7, gpio_reg_int_status },
535 [GPIO_AC_RESET_TOLERANT] = { 7, gpio_reg_reset_tolerant },
536 [GPIO_AC_DEBOUNCE_1] = { 7, gpio_reg_debounce_1 },
537 [GPIO_AC_DEBOUNCE_2] = { 7, gpio_reg_debounce_2 },
538 [GPIO_AC_COMMAND_SRC_0] = { 7, gpio_reg_cmd_source_0 },
539 [GPIO_AC_COMMAND_SRC_1] = { 7, gpio_reg_cmd_source_1 },
540 [GPIO_AC_DATA_READ] = { 7, gpio_reg_data_read },
541 [GPIO_AC_INPUT_MASK] = { 7, gpio_reg_input_mask },
542 };
543
544 static const AspeedGPIOReg aspeed_1_8v_gpios[GPIO_1_8V_REG_ARRAY_SIZE] = {
545 /* 1.8V Set ABCD */
546 [GPIO_1_8V_ABCD_DATA_VALUE] = {0, gpio_reg_data_value},
547 [GPIO_1_8V_ABCD_DIRECTION] = {0, gpio_reg_direction},
548 [GPIO_1_8V_ABCD_INT_ENABLE] = {0, gpio_reg_int_enable},
549 [GPIO_1_8V_ABCD_INT_SENS_0] = {0, gpio_reg_int_sens_0},
550 [GPIO_1_8V_ABCD_INT_SENS_1] = {0, gpio_reg_int_sens_1},
551 [GPIO_1_8V_ABCD_INT_SENS_2] = {0, gpio_reg_int_sens_2},
552 [GPIO_1_8V_ABCD_INT_STATUS] = {0, gpio_reg_int_status},
553 [GPIO_1_8V_ABCD_RESET_TOLERANT] = {0, gpio_reg_reset_tolerant},
554 [GPIO_1_8V_ABCD_DEBOUNCE_1] = {0, gpio_reg_debounce_1},
555 [GPIO_1_8V_ABCD_DEBOUNCE_2] = {0, gpio_reg_debounce_2},
556 [GPIO_1_8V_ABCD_COMMAND_SRC_0] = {0, gpio_reg_cmd_source_0},
557 [GPIO_1_8V_ABCD_COMMAND_SRC_1] = {0, gpio_reg_cmd_source_1},
558 [GPIO_1_8V_ABCD_DATA_READ] = {0, gpio_reg_data_read},
559 [GPIO_1_8V_ABCD_INPUT_MASK] = {0, gpio_reg_input_mask},
560 /* 1.8V Set E */
561 [GPIO_1_8V_E_DATA_VALUE] = {1, gpio_reg_data_value},
562 [GPIO_1_8V_E_DIRECTION] = {1, gpio_reg_direction},
563 [GPIO_1_8V_E_INT_ENABLE] = {1, gpio_reg_int_enable},
564 [GPIO_1_8V_E_INT_SENS_0] = {1, gpio_reg_int_sens_0},
565 [GPIO_1_8V_E_INT_SENS_1] = {1, gpio_reg_int_sens_1},
566 [GPIO_1_8V_E_INT_SENS_2] = {1, gpio_reg_int_sens_2},
567 [GPIO_1_8V_E_INT_STATUS] = {1, gpio_reg_int_status},
568 [GPIO_1_8V_E_RESET_TOLERANT] = {1, gpio_reg_reset_tolerant},
569 [GPIO_1_8V_E_DEBOUNCE_1] = {1, gpio_reg_debounce_1},
570 [GPIO_1_8V_E_DEBOUNCE_2] = {1, gpio_reg_debounce_2},
571 [GPIO_1_8V_E_COMMAND_SRC_0] = {1, gpio_reg_cmd_source_0},
572 [GPIO_1_8V_E_COMMAND_SRC_1] = {1, gpio_reg_cmd_source_1},
573 [GPIO_1_8V_E_DATA_READ] = {1, gpio_reg_data_read},
574 [GPIO_1_8V_E_INPUT_MASK] = {1, gpio_reg_input_mask},
575 };
576
aspeed_gpio_read(void * opaque,hwaddr offset,uint32_t size)577 static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
578 {
579 AspeedGPIOState *s = ASPEED_GPIO(opaque);
580 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
581 uint64_t idx = -1;
582 const AspeedGPIOReg *reg;
583 GPIOSets *set;
584 uint32_t value = 0;
585 uint64_t debounce_value;
586
587 idx = offset >> 2;
588 if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
589 idx -= GPIO_DEBOUNCE_TIME_1;
590 debounce_value = (uint64_t) s->debounce_regs[idx];
591 trace_aspeed_gpio_read(offset, debounce_value);
592 return debounce_value;
593 }
594
595 if (idx >= agc->reg_table_count) {
596 qemu_log_mask(LOG_GUEST_ERROR, "%s: idx 0x%" PRIx64 " out of bounds\n",
597 __func__, idx);
598 return 0;
599 }
600
601 reg = &agc->reg_table[idx];
602 if (reg->set_idx >= agc->nr_gpio_sets) {
603 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
604 PRIx64"\n", __func__, offset);
605 return 0;
606 }
607
608 set = &s->sets[reg->set_idx];
609 switch (reg->type) {
610 case gpio_reg_data_value:
611 value = set->data_value;
612 break;
613 case gpio_reg_direction:
614 value = set->direction;
615 break;
616 case gpio_reg_int_enable:
617 value = set->int_enable;
618 break;
619 case gpio_reg_int_sens_0:
620 value = set->int_sens_0;
621 break;
622 case gpio_reg_int_sens_1:
623 value = set->int_sens_1;
624 break;
625 case gpio_reg_int_sens_2:
626 value = set->int_sens_2;
627 break;
628 case gpio_reg_int_status:
629 value = set->int_status;
630 break;
631 case gpio_reg_reset_tolerant:
632 value = set->reset_tol;
633 break;
634 case gpio_reg_debounce_1:
635 value = set->debounce_1;
636 break;
637 case gpio_reg_debounce_2:
638 value = set->debounce_2;
639 break;
640 case gpio_reg_cmd_source_0:
641 value = set->cmd_source_0;
642 break;
643 case gpio_reg_cmd_source_1:
644 value = set->cmd_source_1;
645 break;
646 case gpio_reg_data_read:
647 value = set->data_read;
648 break;
649 case gpio_reg_input_mask:
650 value = set->input_mask;
651 break;
652 default:
653 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
654 PRIx64"\n", __func__, offset);
655 return 0;
656 }
657
658 trace_aspeed_gpio_read(offset, value);
659 return value;
660 }
661
aspeed_gpio_write_index_mode(void * opaque,hwaddr offset,uint64_t data,uint32_t size)662 static void aspeed_gpio_write_index_mode(void *opaque, hwaddr offset,
663 uint64_t data, uint32_t size)
664 {
665 AspeedGPIOState *s = ASPEED_GPIO(opaque);
666 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
667 const GPIOSetProperties *props;
668 GPIOSets *set;
669 uint32_t reg_idx_number = FIELD_EX32(data, GPIO_INDEX_REG, NUMBER);
670 uint32_t reg_idx_type = FIELD_EX32(data, GPIO_INDEX_REG, TYPE);
671 uint32_t reg_idx_command = FIELD_EX32(data, GPIO_INDEX_REG, COMMAND);
672 uint32_t set_idx = reg_idx_number / ASPEED_GPIOS_PER_SET;
673 uint32_t pin_idx = reg_idx_number % ASPEED_GPIOS_PER_SET;
674 uint32_t group_idx = pin_idx / GPIOS_PER_GROUP;
675 uint32_t reg_value = 0;
676 uint32_t pending = 0;
677
678 set = &s->sets[set_idx];
679 props = &agc->props[set_idx];
680
681 if (reg_idx_command)
682 qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%" PRIx64 "data 0x%"
683 PRIx64 "index mode wrong command 0x%x\n",
684 __func__, offset, data, reg_idx_command);
685
686 switch (reg_idx_type) {
687 case gpio_reg_idx_data:
688 reg_value = set->data_read;
689 reg_value = deposit32(reg_value, pin_idx, 1,
690 FIELD_EX32(data, GPIO_INDEX_REG, DATA_VALUE));
691 reg_value &= props->output;
692 reg_value = update_value_control_source(set, set->data_value,
693 reg_value);
694 set->data_read = reg_value;
695 aspeed_gpio_update(s, set, reg_value, set->direction);
696 return;
697 case gpio_reg_idx_direction:
698 reg_value = set->direction;
699 reg_value = deposit32(reg_value, pin_idx, 1,
700 FIELD_EX32(data, GPIO_INDEX_REG, DIRECTION));
701 /*
702 * where data is the value attempted to be written to the pin:
703 * pin type | input mask | output mask | expected value
704 * ------------------------------------------------------------
705 * bidirectional | 1 | 1 | data
706 * input only | 1 | 0 | 0
707 * output only | 0 | 1 | 1
708 * no pin | 0 | 0 | 0
709 *
710 * which is captured by:
711 * data = ( data | ~input) & output;
712 */
713 reg_value = (reg_value | ~props->input) & props->output;
714 set->direction = update_value_control_source(set, set->direction,
715 reg_value);
716 break;
717 case gpio_reg_idx_interrupt:
718 reg_value = set->int_enable;
719 reg_value = deposit32(reg_value, pin_idx, 1,
720 FIELD_EX32(data, GPIO_INDEX_REG, INT_ENABLE));
721 set->int_enable = update_value_control_source(set, set->int_enable,
722 reg_value);
723 reg_value = set->int_sens_0;
724 reg_value = deposit32(reg_value, pin_idx, 1,
725 FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_0));
726 set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
727 reg_value);
728 reg_value = set->int_sens_1;
729 reg_value = deposit32(reg_value, pin_idx, 1,
730 FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_1));
731 set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
732 reg_value);
733 reg_value = set->int_sens_2;
734 reg_value = deposit32(reg_value, pin_idx, 1,
735 FIELD_EX32(data, GPIO_INDEX_REG, INT_SENS_2));
736 set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
737 reg_value);
738 /* interrupt status */
739 if (FIELD_EX32(data, GPIO_INDEX_REG, INT_STATUS)) {
740 /* pending is either 1 or 0 for a 1-bit field */
741 pending = extract32(set->int_status, pin_idx, 1);
742
743 assert(s->pending >= pending);
744
745 /* No change to s->pending if pending is 0 */
746 s->pending -= pending;
747
748 /*
749 * The write acknowledged the interrupt regardless of whether it
750 * was pending or not. The post-condition is that it mustn't be
751 * pending. Unconditionally clear the status bit.
752 */
753 set->int_status = deposit32(set->int_status, pin_idx, 1, 0);
754 }
755 break;
756 case gpio_reg_idx_debounce:
757 reg_value = set->debounce_1;
758 reg_value = deposit32(reg_value, pin_idx, 1,
759 FIELD_EX32(data, GPIO_INDEX_REG, DEBOUNCE_1));
760 set->debounce_1 = update_value_control_source(set, set->debounce_1,
761 reg_value);
762 reg_value = set->debounce_2;
763 reg_value = deposit32(reg_value, pin_idx, 1,
764 FIELD_EX32(data, GPIO_INDEX_REG, DEBOUNCE_2));
765 set->debounce_2 = update_value_control_source(set, set->debounce_2,
766 reg_value);
767 return;
768 case gpio_reg_idx_tolerance:
769 reg_value = set->reset_tol;
770 reg_value = deposit32(reg_value, pin_idx, 1,
771 FIELD_EX32(data, GPIO_INDEX_REG, RESET_TOLERANT));
772 set->reset_tol = update_value_control_source(set, set->reset_tol,
773 reg_value);
774 return;
775 case gpio_reg_idx_cmd_src:
776 reg_value = set->cmd_source_0;
777 reg_value = deposit32(reg_value, GPIOS_PER_GROUP * group_idx, 1,
778 FIELD_EX32(data, GPIO_INDEX_REG, COMMAND_SRC_0));
779 set->cmd_source_0 = reg_value & ASPEED_CMD_SRC_MASK;
780 reg_value = set->cmd_source_1;
781 reg_value = deposit32(reg_value, GPIOS_PER_GROUP * group_idx, 1,
782 FIELD_EX32(data, GPIO_INDEX_REG, COMMAND_SRC_1));
783 set->cmd_source_1 = reg_value & ASPEED_CMD_SRC_MASK;
784 return;
785 case gpio_reg_idx_input_mask:
786 reg_value = set->input_mask;
787 reg_value = deposit32(reg_value, pin_idx, 1,
788 FIELD_EX32(data, GPIO_INDEX_REG, INPUT_MASK));
789 /*
790 * feeds into interrupt generation
791 * 0: read from data value reg will be updated
792 * 1: read from data value reg will not be updated
793 */
794 set->input_mask = reg_value & props->input;
795 break;
796 default:
797 qemu_log_mask(LOG_GUEST_ERROR, "%s: offset 0x%" PRIx64 "data 0x%"
798 PRIx64 "index mode wrong type 0x%x\n",
799 __func__, offset, data, reg_idx_type);
800 return;
801 }
802 aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
803 return;
804 }
805
aspeed_gpio_write(void * opaque,hwaddr offset,uint64_t data,uint32_t size)806 static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
807 uint32_t size)
808 {
809 AspeedGPIOState *s = ASPEED_GPIO(opaque);
810 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
811 const GPIOSetProperties *props;
812 uint64_t idx = -1;
813 const AspeedGPIOReg *reg;
814 GPIOSets *set;
815 uint32_t cleared;
816
817 trace_aspeed_gpio_write(offset, data);
818
819 idx = offset >> 2;
820
821 /* check gpio index mode */
822 if (idx == R_GPIO_INDEX_REG) {
823 aspeed_gpio_write_index_mode(opaque, offset, data, size);
824 return;
825 }
826
827 if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
828 idx -= GPIO_DEBOUNCE_TIME_1;
829 s->debounce_regs[idx] = (uint32_t) data;
830 return;
831 }
832
833 if (idx >= agc->reg_table_count) {
834 qemu_log_mask(LOG_GUEST_ERROR, "%s: idx 0x%" PRIx64 " out of bounds\n",
835 __func__, idx);
836 return;
837 }
838
839 reg = &agc->reg_table[idx];
840 if (reg->set_idx >= agc->nr_gpio_sets) {
841 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
842 PRIx64"\n", __func__, offset);
843 return;
844 }
845
846 set = &s->sets[reg->set_idx];
847 props = &agc->props[reg->set_idx];
848
849 switch (reg->type) {
850 case gpio_reg_data_value:
851 data &= props->output;
852 data = update_value_control_source(set, set->data_value, data);
853 set->data_read = data;
854 aspeed_gpio_update(s, set, data, set->direction);
855 return;
856 case gpio_reg_direction:
857 /*
858 * where data is the value attempted to be written to the pin:
859 * pin type | input mask | output mask | expected value
860 * ------------------------------------------------------------
861 * bidirectional | 1 | 1 | data
862 * input only | 1 | 0 | 0
863 * output only | 0 | 1 | 1
864 * no pin | 0 | 0 | 0
865 *
866 * which is captured by:
867 * data = ( data | ~input) & output;
868 */
869 data = (data | ~props->input) & props->output;
870 set->direction = update_value_control_source(set, set->direction, data);
871 break;
872 case gpio_reg_int_enable:
873 set->int_enable = update_value_control_source(set, set->int_enable,
874 data);
875 break;
876 case gpio_reg_int_sens_0:
877 set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
878 data);
879 break;
880 case gpio_reg_int_sens_1:
881 set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
882 data);
883 break;
884 case gpio_reg_int_sens_2:
885 set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
886 data);
887 break;
888 case gpio_reg_int_status:
889 cleared = ctpop32(data & set->int_status);
890 if (s->pending && cleared) {
891 assert(s->pending >= cleared);
892 s->pending -= cleared;
893 }
894 set->int_status &= ~data;
895 break;
896 case gpio_reg_reset_tolerant:
897 set->reset_tol = update_value_control_source(set, set->reset_tol,
898 data);
899 return;
900 case gpio_reg_debounce_1:
901 set->debounce_1 = update_value_control_source(set, set->debounce_1,
902 data);
903 return;
904 case gpio_reg_debounce_2:
905 set->debounce_2 = update_value_control_source(set, set->debounce_2,
906 data);
907 return;
908 case gpio_reg_cmd_source_0:
909 set->cmd_source_0 = data & ASPEED_CMD_SRC_MASK;
910 return;
911 case gpio_reg_cmd_source_1:
912 set->cmd_source_1 = data & ASPEED_CMD_SRC_MASK;
913 return;
914 case gpio_reg_data_read:
915 /* Read only register */
916 return;
917 case gpio_reg_input_mask:
918 /*
919 * feeds into interrupt generation
920 * 0: read from data value reg will be updated
921 * 1: read from data value reg will not be updated
922 */
923 set->input_mask = data & props->input;
924 break;
925 default:
926 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
927 PRIx64"\n", __func__, offset);
928 return;
929 }
930 aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
931 return;
932 }
933
get_set_idx(AspeedGPIOState * s,const char * group,int * group_idx)934 static int get_set_idx(AspeedGPIOState *s, const char *group, int *group_idx)
935 {
936 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
937 int set_idx, g_idx;
938
939 for (set_idx = 0; set_idx < agc->nr_gpio_sets; set_idx++) {
940 const GPIOSetProperties *set_props = &agc->props[set_idx];
941 for (g_idx = 0; g_idx < ASPEED_GROUPS_PER_SET; g_idx++) {
942 if (!strncmp(group, set_props->group_label[g_idx], strlen(group))) {
943 *group_idx = g_idx;
944 return set_idx;
945 }
946 }
947 }
948 return -1;
949 }
950
aspeed_gpio_get_pin(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)951 static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
952 void *opaque, Error **errp)
953 {
954 int pin = 0xfff;
955 bool level = true;
956 char group[4];
957 AspeedGPIOState *s = ASPEED_GPIO(obj);
958 int set_idx, group_idx = 0;
959
960 if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
961 /* 1.8V gpio */
962 if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
963 error_setg(errp, "%s: error reading %s", __func__, name);
964 return;
965 }
966 }
967 set_idx = get_set_idx(s, group, &group_idx);
968 if (set_idx == -1) {
969 error_setg(errp, "%s: invalid group %s", __func__, group);
970 return;
971 }
972 pin = pin + group_idx * GPIOS_PER_GROUP;
973 level = aspeed_gpio_get_pin_level(s, set_idx, pin);
974 visit_type_bool(v, name, &level, errp);
975 }
976
aspeed_gpio_set_pin(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)977 static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
978 void *opaque, Error **errp)
979 {
980 bool level;
981 int pin = 0xfff;
982 char group[4];
983 AspeedGPIOState *s = ASPEED_GPIO(obj);
984 int set_idx, group_idx = 0;
985
986 if (!visit_type_bool(v, name, &level, errp)) {
987 return;
988 }
989 if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
990 /* 1.8V gpio */
991 if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
992 error_setg(errp, "%s: error reading %s", __func__, name);
993 return;
994 }
995 }
996 set_idx = get_set_idx(s, group, &group_idx);
997 if (set_idx == -1) {
998 error_setg(errp, "%s: invalid group %s", __func__, group);
999 return;
1000 }
1001 pin = pin + group_idx * GPIOS_PER_GROUP;
1002 aspeed_gpio_set_pin_level(s, set_idx, pin, level);
1003 }
1004
aspeed_gpio_2700_read_control_reg(AspeedGPIOState * s,uint32_t pin)1005 static uint64_t aspeed_gpio_2700_read_control_reg(AspeedGPIOState *s,
1006 uint32_t pin)
1007 {
1008 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1009 GPIOSets *set;
1010 uint64_t value = 0;
1011 uint32_t set_idx;
1012 uint32_t pin_idx;
1013
1014 set_idx = pin / ASPEED_GPIOS_PER_SET;
1015 pin_idx = pin % ASPEED_GPIOS_PER_SET;
1016
1017 if (set_idx >= agc->nr_gpio_sets) {
1018 qemu_log_mask(LOG_GUEST_ERROR, "%s: set index: %d, out of bounds\n",
1019 __func__, set_idx);
1020 return 0;
1021 }
1022
1023 set = &s->sets[set_idx];
1024 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_OUT_DATA,
1025 extract32(set->data_read, pin_idx, 1));
1026 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_DIRECTION,
1027 extract32(set->direction, pin_idx, 1));
1028 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_ENABLE,
1029 extract32(set->int_enable, pin_idx, 1));
1030 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_SENS_0,
1031 extract32(set->int_sens_0, pin_idx, 1));
1032 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_SENS_1,
1033 extract32(set->int_sens_1, pin_idx, 1));
1034 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_SENS_2,
1035 extract32(set->int_sens_2, pin_idx, 1));
1036 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_RESET_TOLERANCE,
1037 extract32(set->reset_tol, pin_idx, 1));
1038 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_DEBOUNCE_1,
1039 extract32(set->debounce_1, pin_idx, 1));
1040 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_DEBOUNCE_2,
1041 extract32(set->debounce_2, pin_idx, 1));
1042 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INPUT_MASK,
1043 extract32(set->input_mask, pin_idx, 1));
1044 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_STATUS,
1045 extract32(set->int_status, pin_idx, 1));
1046 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_IN_DATA,
1047 extract32(set->data_value, pin_idx, 1));
1048 return value;
1049 }
1050
aspeed_gpio_2700_write_control_reg(AspeedGPIOState * s,uint32_t pin,uint64_t data)1051 static void aspeed_gpio_2700_write_control_reg(AspeedGPIOState *s,
1052 uint32_t pin, uint64_t data)
1053 {
1054 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1055 const GPIOSetProperties *props;
1056 GPIOSets *set;
1057 uint32_t set_idx;
1058 uint32_t pin_idx;
1059 uint32_t group_value = 0;
1060 uint32_t pending = 0;
1061
1062 set_idx = pin / ASPEED_GPIOS_PER_SET;
1063 pin_idx = pin % ASPEED_GPIOS_PER_SET;
1064
1065 if (set_idx >= agc->nr_gpio_sets) {
1066 qemu_log_mask(LOG_GUEST_ERROR, "%s: set index: %d, out of bounds\n",
1067 __func__, set_idx);
1068 return;
1069 }
1070
1071 set = &s->sets[set_idx];
1072 props = &agc->props[set_idx];
1073
1074 /* direction */
1075 group_value = set->direction;
1076 group_value = deposit32(group_value, pin_idx, 1,
1077 SHARED_FIELD_EX32(data, GPIO_CONTROL_DIRECTION));
1078 /*
1079 * where data is the value attempted to be written to the pin:
1080 * pin type | input mask | output mask | expected value
1081 * ------------------------------------------------------------
1082 * bidirectional | 1 | 1 | data
1083 * input only | 1 | 0 | 0
1084 * output only | 0 | 1 | 1
1085 * no pin | 0 | 0 | 0
1086 *
1087 * which is captured by:
1088 * data = ( data | ~input) & output;
1089 */
1090 group_value = (group_value | ~props->input) & props->output;
1091 set->direction = update_value_control_source(set, set->direction,
1092 group_value);
1093
1094 /* out data */
1095 group_value = set->data_read;
1096 group_value = deposit32(group_value, pin_idx, 1,
1097 SHARED_FIELD_EX32(data, GPIO_CONTROL_OUT_DATA));
1098 group_value &= props->output;
1099 group_value = update_value_control_source(set, set->data_read,
1100 group_value);
1101 set->data_read = group_value;
1102
1103 /* interrupt enable */
1104 group_value = set->int_enable;
1105 group_value = deposit32(group_value, pin_idx, 1,
1106 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_ENABLE));
1107 set->int_enable = update_value_control_source(set, set->int_enable,
1108 group_value);
1109
1110 /* interrupt sensitivity type 0 */
1111 group_value = set->int_sens_0;
1112 group_value = deposit32(group_value, pin_idx, 1,
1113 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_SENS_0));
1114 set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
1115 group_value);
1116
1117 /* interrupt sensitivity type 1 */
1118 group_value = set->int_sens_1;
1119 group_value = deposit32(group_value, pin_idx, 1,
1120 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_SENS_1));
1121 set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
1122 group_value);
1123
1124 /* interrupt sensitivity type 2 */
1125 group_value = set->int_sens_2;
1126 group_value = deposit32(group_value, pin_idx, 1,
1127 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_SENS_2));
1128 set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
1129 group_value);
1130
1131 /* reset tolerance enable */
1132 group_value = set->reset_tol;
1133 group_value = deposit32(group_value, pin_idx, 1,
1134 SHARED_FIELD_EX32(data, GPIO_CONTROL_RESET_TOLERANCE));
1135 set->reset_tol = update_value_control_source(set, set->reset_tol,
1136 group_value);
1137
1138 /* debounce 1 */
1139 group_value = set->debounce_1;
1140 group_value = deposit32(group_value, pin_idx, 1,
1141 SHARED_FIELD_EX32(data, GPIO_CONTROL_DEBOUNCE_1));
1142 set->debounce_1 = update_value_control_source(set, set->debounce_1,
1143 group_value);
1144
1145 /* debounce 2 */
1146 group_value = set->debounce_2;
1147 group_value = deposit32(group_value, pin_idx, 1,
1148 SHARED_FIELD_EX32(data, GPIO_CONTROL_DEBOUNCE_2));
1149 set->debounce_2 = update_value_control_source(set, set->debounce_2,
1150 group_value);
1151
1152 /* input mask */
1153 group_value = set->input_mask;
1154 group_value = deposit32(group_value, pin_idx, 1,
1155 SHARED_FIELD_EX32(data, GPIO_CONTROL_INPUT_MASK));
1156 /*
1157 * feeds into interrupt generation
1158 * 0: read from data value reg will be updated
1159 * 1: read from data value reg will not be updated
1160 */
1161 set->input_mask = group_value & props->input;
1162
1163 /* blink counter 1 */
1164 /* blink counter 2 */
1165 /* unimplement */
1166
1167 /* interrupt status */
1168 if (SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_STATUS)) {
1169 /* pending is either 1 or 0 for a 1-bit field */
1170 pending = extract32(set->int_status, pin_idx, 1);
1171
1172 assert(s->pending >= pending);
1173
1174 /* No change to s->pending if pending is 0 */
1175 s->pending -= pending;
1176
1177 /*
1178 * The write acknowledged the interrupt regardless of whether it
1179 * was pending or not. The post-condition is that it mustn't be
1180 * pending. Unconditionally clear the status bit.
1181 */
1182 set->int_status = deposit32(set->int_status, pin_idx, 1, 0);
1183 }
1184
1185 aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
1186 return;
1187 }
1188
aspeed_gpio_2700_read(void * opaque,hwaddr offset,uint32_t size)1189 static uint64_t aspeed_gpio_2700_read(void *opaque, hwaddr offset,
1190 uint32_t size)
1191 {
1192 AspeedGPIOState *s = ASPEED_GPIO(opaque);
1193 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1194 GPIOSets *set;
1195 uint64_t value;
1196 uint64_t reg;
1197 uint32_t pin;
1198 uint32_t idx;
1199
1200 reg = offset >> 2;
1201
1202 if (reg >= agc->reg_table_count) {
1203 qemu_log_mask(LOG_GUEST_ERROR,
1204 "%s: offset 0x%" PRIx64 " out of bounds\n",
1205 __func__, offset);
1206 return 0;
1207 }
1208
1209 switch (reg) {
1210 case R_GPIO_2700_DEBOUNCE_TIME_1 ... R_GPIO_2700_DEBOUNCE_TIME_3:
1211 idx = reg - R_GPIO_2700_DEBOUNCE_TIME_1;
1212
1213 if (idx >= ASPEED_GPIO_NR_DEBOUNCE_REGS) {
1214 qemu_log_mask(LOG_GUEST_ERROR,
1215 "%s: debounce index: %d, out of bounds\n",
1216 __func__, idx);
1217 return 0;
1218 }
1219
1220 value = (uint64_t) s->debounce_regs[idx];
1221 break;
1222 case R_GPIO_2700_INT_STATUS_1 ... R_GPIO_2700_INT_STATUS_7:
1223 idx = reg - R_GPIO_2700_INT_STATUS_1;
1224
1225 if (idx >= agc->nr_gpio_sets) {
1226 qemu_log_mask(LOG_GUEST_ERROR,
1227 "%s: interrupt status index: %d, out of bounds\n",
1228 __func__, idx);
1229 return 0;
1230 }
1231
1232 set = &s->sets[idx];
1233 value = (uint64_t) set->int_status;
1234 break;
1235 case R_GPIO_A0_CONTROL ... R_GPIO_AA7_CONTROL:
1236 pin = reg - R_GPIO_A0_CONTROL;
1237
1238 if (pin >= agc->nr_gpio_pins) {
1239 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid pin number: %d\n",
1240 __func__, pin);
1241 return 0;
1242 }
1243
1244 value = aspeed_gpio_2700_read_control_reg(s, pin);
1245 break;
1246 default:
1247 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
1248 PRIx64"\n", __func__, offset);
1249 return 0;
1250 }
1251
1252 trace_aspeed_gpio_read(offset, value);
1253 return value;
1254 }
1255
aspeed_gpio_2700_write(void * opaque,hwaddr offset,uint64_t data,uint32_t size)1256 static void aspeed_gpio_2700_write(void *opaque, hwaddr offset,
1257 uint64_t data, uint32_t size)
1258 {
1259 AspeedGPIOState *s = ASPEED_GPIO(opaque);
1260 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1261 uint64_t reg;
1262 uint32_t pin;
1263 uint32_t idx;
1264
1265 trace_aspeed_gpio_write(offset, data);
1266
1267 reg = offset >> 2;
1268
1269 if (reg >= agc->reg_table_count) {
1270 qemu_log_mask(LOG_GUEST_ERROR,
1271 "%s: offset 0x%" PRIx64 " out of bounds\n",
1272 __func__, offset);
1273 return;
1274 }
1275
1276 switch (reg) {
1277 case R_GPIO_2700_DEBOUNCE_TIME_1 ... R_GPIO_2700_DEBOUNCE_TIME_3:
1278 idx = reg - R_GPIO_2700_DEBOUNCE_TIME_1;
1279
1280 if (idx >= ASPEED_GPIO_NR_DEBOUNCE_REGS) {
1281 qemu_log_mask(LOG_GUEST_ERROR,
1282 "%s: debounce index: %d out of bounds\n",
1283 __func__, idx);
1284 return;
1285 }
1286
1287 s->debounce_regs[idx] = (uint32_t) data;
1288 break;
1289 case R_GPIO_A0_CONTROL ... R_GPIO_AA7_CONTROL:
1290 pin = reg - R_GPIO_A0_CONTROL;
1291
1292 if (pin >= agc->nr_gpio_pins) {
1293 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid pin number: %d\n",
1294 __func__, pin);
1295 return;
1296 }
1297
1298 if (SHARED_FIELD_EX32(data, GPIO_CONTROL_RESERVED)) {
1299 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reserved data: 0x%"
1300 PRIx64"\n", __func__, data);
1301 return;
1302 }
1303
1304 aspeed_gpio_2700_write_control_reg(s, pin, data);
1305 break;
1306 default:
1307 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
1308 PRIx64"\n", __func__, offset);
1309 break;
1310 }
1311
1312 return;
1313 }
1314
1315 /* Setup functions */
1316 static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1317 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1318 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1319 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1320 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1321 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
1322 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
1323 [6] = {0x0000000f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
1324 };
1325
1326 static const GPIOSetProperties ast2500_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1327 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1328 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1329 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1330 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1331 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
1332 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
1333 [6] = {0x0fffffff, 0x0fffffff, {"Y", "Z", "AA", "AB"} },
1334 [7] = {0x000000ff, 0x000000ff, {"AC"} },
1335 };
1336
1337 static GPIOSetProperties ast2600_3_3v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1338 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1339 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1340 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1341 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1342 [4] = {0xffffffff, 0x00ffffff, {"Q", "R", "S", "T"} },
1343 [5] = {0xffffffff, 0xffffff00, {"U", "V", "W", "X"} },
1344 [6] = {0x0000ffff, 0x0000ffff, {"Y", "Z"} },
1345 };
1346
1347 static GPIOSetProperties ast2600_1_8v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1348 [0] = {0xffffffff, 0xffffffff, {"18A", "18B", "18C", "18D"} },
1349 [1] = {0x0000000f, 0x0000000f, {"18E"} },
1350 };
1351
1352 static GPIOSetProperties ast1030_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1353 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1354 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1355 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1356 [3] = {0xffffff3f, 0xffffff3f, {"M", "N", "O", "P"} },
1357 [4] = {0xff060c1f, 0x00060c1f, {"Q", "R", "S", "T"} },
1358 [5] = {0x000000ff, 0x00000000, {"U"} },
1359 };
1360
1361 static GPIOSetProperties ast2700_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1362 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1363 [1] = {0x0fffffff, 0x0fffffff, {"E", "F", "G", "H"} },
1364 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1365 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1366 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
1367 [5] = {0xffffffff, 0xffffffff, {"U", "V", "W", "X"} },
1368 [6] = {0x00ffffff, 0x00ffffff, {"Y", "Z", "AA"} },
1369 };
1370
1371 static const MemoryRegionOps aspeed_gpio_ops = {
1372 .read = aspeed_gpio_read,
1373 .write = aspeed_gpio_write,
1374 .endianness = DEVICE_LITTLE_ENDIAN,
1375 .valid.min_access_size = 1,
1376 .valid.max_access_size = 4,
1377 };
1378
1379 static const MemoryRegionOps aspeed_gpio_2700_ops = {
1380 .read = aspeed_gpio_2700_read,
1381 .write = aspeed_gpio_2700_write,
1382 .endianness = DEVICE_LITTLE_ENDIAN,
1383 .valid.min_access_size = 1,
1384 .valid.max_access_size = 4,
1385 };
1386
aspeed_gpio_reset(DeviceState * dev)1387 static void aspeed_gpio_reset(DeviceState *dev)
1388 {
1389 AspeedGPIOState *s = ASPEED_GPIO(dev);
1390
1391 /* TODO: respect the reset tolerance registers */
1392 memset(s->sets, 0, sizeof(s->sets));
1393 }
1394
aspeed_gpio_realize(DeviceState * dev,Error ** errp)1395 static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
1396 {
1397 AspeedGPIOState *s = ASPEED_GPIO(dev);
1398 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1399 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1400
1401 /* Interrupt parent line */
1402 sysbus_init_irq(sbd, &s->irq);
1403
1404 /* Individual GPIOs */
1405 for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
1406 const GPIOSetProperties *props = &agc->props[i];
1407 uint32_t skip = ~(props->input | props->output);
1408 for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
1409 if (skip >> j & 1) {
1410 continue;
1411 }
1412 sysbus_init_irq(sbd, &s->gpios[i][j]);
1413 }
1414 }
1415
1416 memory_region_init_io(&s->iomem, OBJECT(s), agc->reg_ops, s,
1417 TYPE_ASPEED_GPIO, agc->mem_size);
1418
1419 sysbus_init_mmio(sbd, &s->iomem);
1420 }
1421
aspeed_gpio_init(Object * obj)1422 static void aspeed_gpio_init(Object *obj)
1423 {
1424 AspeedGPIOState *s = ASPEED_GPIO(obj);
1425 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1426
1427 for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
1428 const GPIOSetProperties *props = &agc->props[i];
1429 uint32_t skip = ~(props->input | props->output);
1430 for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
1431 if (skip >> j & 1) {
1432 continue;
1433 }
1434 int group_idx = j / GPIOS_PER_GROUP;
1435 int pin_idx = j % GPIOS_PER_GROUP;
1436 const char *group = &props->group_label[group_idx][0];
1437 char *name = g_strdup_printf("gpio%s%d", group, pin_idx);
1438 object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
1439 aspeed_gpio_set_pin, NULL, NULL);
1440 g_free(name);
1441 }
1442 }
1443 }
1444
1445 static const VMStateDescription vmstate_gpio_regs = {
1446 .name = TYPE_ASPEED_GPIO"/regs",
1447 .version_id = 1,
1448 .minimum_version_id = 1,
1449 .fields = (const VMStateField[]) {
1450 VMSTATE_UINT32(data_value, GPIOSets),
1451 VMSTATE_UINT32(data_read, GPIOSets),
1452 VMSTATE_UINT32(direction, GPIOSets),
1453 VMSTATE_UINT32(int_enable, GPIOSets),
1454 VMSTATE_UINT32(int_sens_0, GPIOSets),
1455 VMSTATE_UINT32(int_sens_1, GPIOSets),
1456 VMSTATE_UINT32(int_sens_2, GPIOSets),
1457 VMSTATE_UINT32(int_status, GPIOSets),
1458 VMSTATE_UINT32(reset_tol, GPIOSets),
1459 VMSTATE_UINT32(cmd_source_0, GPIOSets),
1460 VMSTATE_UINT32(cmd_source_1, GPIOSets),
1461 VMSTATE_UINT32(debounce_1, GPIOSets),
1462 VMSTATE_UINT32(debounce_2, GPIOSets),
1463 VMSTATE_UINT32(input_mask, GPIOSets),
1464 VMSTATE_END_OF_LIST(),
1465 }
1466 };
1467
1468 static const VMStateDescription vmstate_aspeed_gpio = {
1469 .name = TYPE_ASPEED_GPIO,
1470 .version_id = 1,
1471 .minimum_version_id = 1,
1472 .fields = (const VMStateField[]) {
1473 VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS,
1474 1, vmstate_gpio_regs, GPIOSets),
1475 VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState,
1476 ASPEED_GPIO_NR_DEBOUNCE_REGS),
1477 VMSTATE_END_OF_LIST(),
1478 }
1479 };
1480
aspeed_gpio_class_init(ObjectClass * klass,void * data)1481 static void aspeed_gpio_class_init(ObjectClass *klass, void *data)
1482 {
1483 DeviceClass *dc = DEVICE_CLASS(klass);
1484
1485 dc->realize = aspeed_gpio_realize;
1486 device_class_set_legacy_reset(dc, aspeed_gpio_reset);
1487 dc->desc = "Aspeed GPIO Controller";
1488 dc->vmsd = &vmstate_aspeed_gpio;
1489 }
1490
aspeed_gpio_ast2400_class_init(ObjectClass * klass,void * data)1491 static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
1492 {
1493 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1494
1495 agc->props = ast2400_set_props;
1496 agc->nr_gpio_pins = 216;
1497 agc->nr_gpio_sets = 7;
1498 agc->reg_table = aspeed_3_3v_gpios;
1499 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1500 agc->mem_size = 0x1000;
1501 agc->reg_ops = &aspeed_gpio_ops;
1502 }
1503
aspeed_gpio_2500_class_init(ObjectClass * klass,void * data)1504 static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
1505 {
1506 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1507
1508 agc->props = ast2500_set_props;
1509 agc->nr_gpio_pins = 228;
1510 agc->nr_gpio_sets = 8;
1511 agc->reg_table = aspeed_3_3v_gpios;
1512 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1513 agc->mem_size = 0x1000;
1514 agc->reg_ops = &aspeed_gpio_ops;
1515 }
1516
aspeed_gpio_ast2600_3_3v_class_init(ObjectClass * klass,void * data)1517 static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass, void *data)
1518 {
1519 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1520
1521 agc->props = ast2600_3_3v_set_props;
1522 agc->nr_gpio_pins = 208;
1523 agc->nr_gpio_sets = 7;
1524 agc->reg_table = aspeed_3_3v_gpios;
1525 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1526 agc->mem_size = 0x800;
1527 agc->reg_ops = &aspeed_gpio_ops;
1528 }
1529
aspeed_gpio_ast2600_1_8v_class_init(ObjectClass * klass,void * data)1530 static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data)
1531 {
1532 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1533
1534 agc->props = ast2600_1_8v_set_props;
1535 agc->nr_gpio_pins = 36;
1536 agc->nr_gpio_sets = 2;
1537 agc->reg_table = aspeed_1_8v_gpios;
1538 agc->reg_table_count = GPIO_1_8V_REG_ARRAY_SIZE;
1539 agc->mem_size = 0x800;
1540 agc->reg_ops = &aspeed_gpio_ops;
1541 }
1542
aspeed_gpio_1030_class_init(ObjectClass * klass,void * data)1543 static void aspeed_gpio_1030_class_init(ObjectClass *klass, void *data)
1544 {
1545 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1546
1547 agc->props = ast1030_set_props;
1548 agc->nr_gpio_pins = 151;
1549 agc->nr_gpio_sets = 6;
1550 agc->reg_table = aspeed_3_3v_gpios;
1551 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1552 agc->mem_size = 0x1000;
1553 agc->reg_ops = &aspeed_gpio_ops;
1554 }
1555
aspeed_gpio_2700_class_init(ObjectClass * klass,void * data)1556 static void aspeed_gpio_2700_class_init(ObjectClass *klass, void *data)
1557 {
1558 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1559
1560 agc->props = ast2700_set_props;
1561 agc->nr_gpio_pins = 216;
1562 agc->nr_gpio_sets = 7;
1563 agc->reg_table_count = GPIO_2700_REG_ARRAY_SIZE;
1564 agc->mem_size = 0x1000;
1565 agc->reg_ops = &aspeed_gpio_2700_ops;
1566 }
1567
1568 static const TypeInfo aspeed_gpio_info = {
1569 .name = TYPE_ASPEED_GPIO,
1570 .parent = TYPE_SYS_BUS_DEVICE,
1571 .instance_size = sizeof(AspeedGPIOState),
1572 .class_size = sizeof(AspeedGPIOClass),
1573 .class_init = aspeed_gpio_class_init,
1574 .abstract = true,
1575 };
1576
1577 static const TypeInfo aspeed_gpio_ast2400_info = {
1578 .name = TYPE_ASPEED_GPIO "-ast2400",
1579 .parent = TYPE_ASPEED_GPIO,
1580 .class_init = aspeed_gpio_ast2400_class_init,
1581 .instance_init = aspeed_gpio_init,
1582 };
1583
1584 static const TypeInfo aspeed_gpio_ast2500_info = {
1585 .name = TYPE_ASPEED_GPIO "-ast2500",
1586 .parent = TYPE_ASPEED_GPIO,
1587 .class_init = aspeed_gpio_2500_class_init,
1588 .instance_init = aspeed_gpio_init,
1589 };
1590
1591 static const TypeInfo aspeed_gpio_ast2600_3_3v_info = {
1592 .name = TYPE_ASPEED_GPIO "-ast2600",
1593 .parent = TYPE_ASPEED_GPIO,
1594 .class_init = aspeed_gpio_ast2600_3_3v_class_init,
1595 .instance_init = aspeed_gpio_init,
1596 };
1597
1598 static const TypeInfo aspeed_gpio_ast2600_1_8v_info = {
1599 .name = TYPE_ASPEED_GPIO "-ast2600-1_8v",
1600 .parent = TYPE_ASPEED_GPIO,
1601 .class_init = aspeed_gpio_ast2600_1_8v_class_init,
1602 .instance_init = aspeed_gpio_init,
1603 };
1604
1605 static const TypeInfo aspeed_gpio_ast1030_info = {
1606 .name = TYPE_ASPEED_GPIO "-ast1030",
1607 .parent = TYPE_ASPEED_GPIO,
1608 .class_init = aspeed_gpio_1030_class_init,
1609 .instance_init = aspeed_gpio_init,
1610 };
1611
1612 static const TypeInfo aspeed_gpio_ast2700_info = {
1613 .name = TYPE_ASPEED_GPIO "-ast2700",
1614 .parent = TYPE_ASPEED_GPIO,
1615 .class_init = aspeed_gpio_2700_class_init,
1616 .instance_init = aspeed_gpio_init,
1617 };
1618
aspeed_gpio_register_types(void)1619 static void aspeed_gpio_register_types(void)
1620 {
1621 type_register_static(&aspeed_gpio_info);
1622 type_register_static(&aspeed_gpio_ast2400_info);
1623 type_register_static(&aspeed_gpio_ast2500_info);
1624 type_register_static(&aspeed_gpio_ast2600_3_3v_info);
1625 type_register_static(&aspeed_gpio_ast2600_1_8v_info);
1626 type_register_static(&aspeed_gpio_ast1030_info);
1627 type_register_static(&aspeed_gpio_ast2700_info);
1628 }
1629
1630 type_init(aspeed_gpio_register_types);
1631