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 }
804
aspeed_gpio_write(void * opaque,hwaddr offset,uint64_t data,uint32_t size)805 static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
806 uint32_t size)
807 {
808 AspeedGPIOState *s = ASPEED_GPIO(opaque);
809 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
810 const GPIOSetProperties *props;
811 uint64_t idx = -1;
812 const AspeedGPIOReg *reg;
813 GPIOSets *set;
814 uint32_t cleared;
815
816 trace_aspeed_gpio_write(offset, data);
817
818 idx = offset >> 2;
819
820 /* check gpio index mode */
821 if (idx == R_GPIO_INDEX_REG) {
822 aspeed_gpio_write_index_mode(opaque, offset, data, size);
823 return;
824 }
825
826 if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
827 idx -= GPIO_DEBOUNCE_TIME_1;
828 s->debounce_regs[idx] = (uint32_t) data;
829 return;
830 }
831
832 if (idx >= agc->reg_table_count) {
833 qemu_log_mask(LOG_GUEST_ERROR, "%s: idx 0x%" PRIx64 " out of bounds\n",
834 __func__, idx);
835 return;
836 }
837
838 reg = &agc->reg_table[idx];
839 if (reg->set_idx >= agc->nr_gpio_sets) {
840 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
841 PRIx64"\n", __func__, offset);
842 return;
843 }
844
845 set = &s->sets[reg->set_idx];
846 props = &agc->props[reg->set_idx];
847
848 switch (reg->type) {
849 case gpio_reg_data_value:
850 data &= props->output;
851 data = update_value_control_source(set, set->data_value, data);
852 set->data_read = data;
853 aspeed_gpio_update(s, set, data, set->direction);
854 return;
855 case gpio_reg_direction:
856 /*
857 * where data is the value attempted to be written to the pin:
858 * pin type | input mask | output mask | expected value
859 * ------------------------------------------------------------
860 * bidirectional | 1 | 1 | data
861 * input only | 1 | 0 | 0
862 * output only | 0 | 1 | 1
863 * no pin | 0 | 0 | 0
864 *
865 * which is captured by:
866 * data = ( data | ~input) & output;
867 */
868 data = (data | ~props->input) & props->output;
869 set->direction = update_value_control_source(set, set->direction, data);
870 break;
871 case gpio_reg_int_enable:
872 set->int_enable = update_value_control_source(set, set->int_enable,
873 data);
874 break;
875 case gpio_reg_int_sens_0:
876 set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
877 data);
878 break;
879 case gpio_reg_int_sens_1:
880 set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
881 data);
882 break;
883 case gpio_reg_int_sens_2:
884 set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
885 data);
886 break;
887 case gpio_reg_int_status:
888 cleared = ctpop32(data & set->int_status);
889 if (s->pending && cleared) {
890 assert(s->pending >= cleared);
891 s->pending -= cleared;
892 }
893 set->int_status &= ~data;
894 break;
895 case gpio_reg_reset_tolerant:
896 set->reset_tol = update_value_control_source(set, set->reset_tol,
897 data);
898 return;
899 case gpio_reg_debounce_1:
900 set->debounce_1 = update_value_control_source(set, set->debounce_1,
901 data);
902 return;
903 case gpio_reg_debounce_2:
904 set->debounce_2 = update_value_control_source(set, set->debounce_2,
905 data);
906 return;
907 case gpio_reg_cmd_source_0:
908 set->cmd_source_0 = data & ASPEED_CMD_SRC_MASK;
909 return;
910 case gpio_reg_cmd_source_1:
911 set->cmd_source_1 = data & ASPEED_CMD_SRC_MASK;
912 return;
913 case gpio_reg_data_read:
914 /* Read only register */
915 return;
916 case gpio_reg_input_mask:
917 /*
918 * feeds into interrupt generation
919 * 0: read from data value reg will be updated
920 * 1: read from data value reg will not be updated
921 */
922 set->input_mask = data & props->input;
923 break;
924 default:
925 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
926 PRIx64"\n", __func__, offset);
927 return;
928 }
929 aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
930 }
931
get_set_idx(AspeedGPIOState * s,const char * group,int * group_idx)932 static int get_set_idx(AspeedGPIOState *s, const char *group, int *group_idx)
933 {
934 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
935 int set_idx, g_idx;
936
937 for (set_idx = 0; set_idx < agc->nr_gpio_sets; set_idx++) {
938 const GPIOSetProperties *set_props = &agc->props[set_idx];
939 for (g_idx = 0; g_idx < ASPEED_GROUPS_PER_SET; g_idx++) {
940 if (!strncmp(group, set_props->group_label[g_idx], strlen(group))) {
941 *group_idx = g_idx;
942 return set_idx;
943 }
944 }
945 }
946 return -1;
947 }
948
aspeed_gpio_get_pin(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)949 static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
950 void *opaque, Error **errp)
951 {
952 int pin = 0xfff;
953 bool level = true;
954 char group[4];
955 AspeedGPIOState *s = ASPEED_GPIO(obj);
956 int set_idx, group_idx = 0;
957
958 if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
959 /* 1.8V gpio */
960 if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
961 error_setg(errp, "%s: error reading %s", __func__, name);
962 return;
963 }
964 }
965 set_idx = get_set_idx(s, group, &group_idx);
966 if (set_idx == -1) {
967 error_setg(errp, "%s: invalid group %s", __func__, group);
968 return;
969 }
970 pin = pin + group_idx * GPIOS_PER_GROUP;
971 level = aspeed_gpio_get_pin_level(s, set_idx, pin);
972 visit_type_bool(v, name, &level, errp);
973 }
974
aspeed_gpio_set_pin(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)975 static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
976 void *opaque, Error **errp)
977 {
978 bool level;
979 int pin = 0xfff;
980 char group[4];
981 AspeedGPIOState *s = ASPEED_GPIO(obj);
982 int set_idx, group_idx = 0;
983
984 if (!visit_type_bool(v, name, &level, errp)) {
985 return;
986 }
987 if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
988 /* 1.8V gpio */
989 if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) {
990 error_setg(errp, "%s: error reading %s", __func__, name);
991 return;
992 }
993 }
994 set_idx = get_set_idx(s, group, &group_idx);
995 if (set_idx == -1) {
996 error_setg(errp, "%s: invalid group %s", __func__, group);
997 return;
998 }
999 pin = pin + group_idx * GPIOS_PER_GROUP;
1000 aspeed_gpio_set_pin_level(s, set_idx, pin, level);
1001 }
1002
aspeed_gpio_2700_read_control_reg(AspeedGPIOState * s,uint32_t pin)1003 static uint64_t aspeed_gpio_2700_read_control_reg(AspeedGPIOState *s,
1004 uint32_t pin)
1005 {
1006 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1007 GPIOSets *set;
1008 uint64_t value = 0;
1009 uint32_t set_idx;
1010 uint32_t pin_idx;
1011
1012 set_idx = pin / ASPEED_GPIOS_PER_SET;
1013 pin_idx = pin % ASPEED_GPIOS_PER_SET;
1014
1015 if (set_idx >= agc->nr_gpio_sets) {
1016 qemu_log_mask(LOG_GUEST_ERROR, "%s: set index: %d, out of bounds\n",
1017 __func__, set_idx);
1018 return 0;
1019 }
1020
1021 set = &s->sets[set_idx];
1022 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_OUT_DATA,
1023 extract32(set->data_read, pin_idx, 1));
1024 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_DIRECTION,
1025 extract32(set->direction, pin_idx, 1));
1026 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_ENABLE,
1027 extract32(set->int_enable, pin_idx, 1));
1028 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_SENS_0,
1029 extract32(set->int_sens_0, pin_idx, 1));
1030 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_SENS_1,
1031 extract32(set->int_sens_1, pin_idx, 1));
1032 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_SENS_2,
1033 extract32(set->int_sens_2, pin_idx, 1));
1034 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_RESET_TOLERANCE,
1035 extract32(set->reset_tol, pin_idx, 1));
1036 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_DEBOUNCE_1,
1037 extract32(set->debounce_1, pin_idx, 1));
1038 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_DEBOUNCE_2,
1039 extract32(set->debounce_2, pin_idx, 1));
1040 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INPUT_MASK,
1041 extract32(set->input_mask, pin_idx, 1));
1042 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_INT_STATUS,
1043 extract32(set->int_status, pin_idx, 1));
1044 value = SHARED_FIELD_DP32(value, GPIO_CONTROL_IN_DATA,
1045 extract32(set->data_value, pin_idx, 1));
1046 return value;
1047 }
1048
aspeed_gpio_2700_write_control_reg(AspeedGPIOState * s,uint32_t pin,uint64_t data)1049 static void aspeed_gpio_2700_write_control_reg(AspeedGPIOState *s,
1050 uint32_t pin, uint64_t data)
1051 {
1052 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1053 const GPIOSetProperties *props;
1054 GPIOSets *set;
1055 uint32_t set_idx;
1056 uint32_t pin_idx;
1057 uint32_t group_value = 0;
1058 uint32_t pending = 0;
1059
1060 set_idx = pin / ASPEED_GPIOS_PER_SET;
1061 pin_idx = pin % ASPEED_GPIOS_PER_SET;
1062
1063 if (set_idx >= agc->nr_gpio_sets) {
1064 qemu_log_mask(LOG_GUEST_ERROR, "%s: set index: %d, out of bounds\n",
1065 __func__, set_idx);
1066 return;
1067 }
1068
1069 set = &s->sets[set_idx];
1070 props = &agc->props[set_idx];
1071
1072 /* direction */
1073 group_value = set->direction;
1074 group_value = deposit32(group_value, pin_idx, 1,
1075 SHARED_FIELD_EX32(data, GPIO_CONTROL_DIRECTION));
1076 /*
1077 * where data is the value attempted to be written to the pin:
1078 * pin type | input mask | output mask | expected value
1079 * ------------------------------------------------------------
1080 * bidirectional | 1 | 1 | data
1081 * input only | 1 | 0 | 0
1082 * output only | 0 | 1 | 1
1083 * no pin | 0 | 0 | 0
1084 *
1085 * which is captured by:
1086 * data = ( data | ~input) & output;
1087 */
1088 group_value = (group_value | ~props->input) & props->output;
1089 set->direction = update_value_control_source(set, set->direction,
1090 group_value);
1091
1092 /* out data */
1093 group_value = set->data_read;
1094 group_value = deposit32(group_value, pin_idx, 1,
1095 SHARED_FIELD_EX32(data, GPIO_CONTROL_OUT_DATA));
1096 group_value &= props->output;
1097 group_value = update_value_control_source(set, set->data_read,
1098 group_value);
1099 set->data_read = group_value;
1100
1101 /* interrupt enable */
1102 group_value = set->int_enable;
1103 group_value = deposit32(group_value, pin_idx, 1,
1104 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_ENABLE));
1105 set->int_enable = update_value_control_source(set, set->int_enable,
1106 group_value);
1107
1108 /* interrupt sensitivity type 0 */
1109 group_value = set->int_sens_0;
1110 group_value = deposit32(group_value, pin_idx, 1,
1111 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_SENS_0));
1112 set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
1113 group_value);
1114
1115 /* interrupt sensitivity type 1 */
1116 group_value = set->int_sens_1;
1117 group_value = deposit32(group_value, pin_idx, 1,
1118 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_SENS_1));
1119 set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
1120 group_value);
1121
1122 /* interrupt sensitivity type 2 */
1123 group_value = set->int_sens_2;
1124 group_value = deposit32(group_value, pin_idx, 1,
1125 SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_SENS_2));
1126 set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
1127 group_value);
1128
1129 /* reset tolerance enable */
1130 group_value = set->reset_tol;
1131 group_value = deposit32(group_value, pin_idx, 1,
1132 SHARED_FIELD_EX32(data, GPIO_CONTROL_RESET_TOLERANCE));
1133 set->reset_tol = update_value_control_source(set, set->reset_tol,
1134 group_value);
1135
1136 /* debounce 1 */
1137 group_value = set->debounce_1;
1138 group_value = deposit32(group_value, pin_idx, 1,
1139 SHARED_FIELD_EX32(data, GPIO_CONTROL_DEBOUNCE_1));
1140 set->debounce_1 = update_value_control_source(set, set->debounce_1,
1141 group_value);
1142
1143 /* debounce 2 */
1144 group_value = set->debounce_2;
1145 group_value = deposit32(group_value, pin_idx, 1,
1146 SHARED_FIELD_EX32(data, GPIO_CONTROL_DEBOUNCE_2));
1147 set->debounce_2 = update_value_control_source(set, set->debounce_2,
1148 group_value);
1149
1150 /* input mask */
1151 group_value = set->input_mask;
1152 group_value = deposit32(group_value, pin_idx, 1,
1153 SHARED_FIELD_EX32(data, GPIO_CONTROL_INPUT_MASK));
1154 /*
1155 * feeds into interrupt generation
1156 * 0: read from data value reg will be updated
1157 * 1: read from data value reg will not be updated
1158 */
1159 set->input_mask = group_value & props->input;
1160
1161 /* blink counter 1 */
1162 /* blink counter 2 */
1163 /* unimplement */
1164
1165 /* interrupt status */
1166 if (SHARED_FIELD_EX32(data, GPIO_CONTROL_INT_STATUS)) {
1167 /* pending is either 1 or 0 for a 1-bit field */
1168 pending = extract32(set->int_status, pin_idx, 1);
1169
1170 assert(s->pending >= pending);
1171
1172 /* No change to s->pending if pending is 0 */
1173 s->pending -= pending;
1174
1175 /*
1176 * The write acknowledged the interrupt regardless of whether it
1177 * was pending or not. The post-condition is that it mustn't be
1178 * pending. Unconditionally clear the status bit.
1179 */
1180 set->int_status = deposit32(set->int_status, pin_idx, 1, 0);
1181 }
1182
1183 aspeed_gpio_update(s, set, set->data_value, UINT32_MAX);
1184 }
1185
aspeed_gpio_2700_read(void * opaque,hwaddr offset,uint32_t size)1186 static uint64_t aspeed_gpio_2700_read(void *opaque, hwaddr offset,
1187 uint32_t size)
1188 {
1189 AspeedGPIOState *s = ASPEED_GPIO(opaque);
1190 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1191 GPIOSets *set;
1192 uint64_t value;
1193 uint64_t reg;
1194 uint32_t pin;
1195 uint32_t idx;
1196
1197 reg = offset >> 2;
1198
1199 if (reg >= agc->reg_table_count) {
1200 qemu_log_mask(LOG_GUEST_ERROR,
1201 "%s: offset 0x%" PRIx64 " out of bounds\n",
1202 __func__, offset);
1203 return 0;
1204 }
1205
1206 switch (reg) {
1207 case R_GPIO_2700_DEBOUNCE_TIME_1 ... R_GPIO_2700_DEBOUNCE_TIME_3:
1208 idx = reg - R_GPIO_2700_DEBOUNCE_TIME_1;
1209
1210 if (idx >= ASPEED_GPIO_NR_DEBOUNCE_REGS) {
1211 qemu_log_mask(LOG_GUEST_ERROR,
1212 "%s: debounce index: %d, out of bounds\n",
1213 __func__, idx);
1214 return 0;
1215 }
1216
1217 value = (uint64_t) s->debounce_regs[idx];
1218 break;
1219 case R_GPIO_2700_INT_STATUS_1 ... R_GPIO_2700_INT_STATUS_7:
1220 idx = reg - R_GPIO_2700_INT_STATUS_1;
1221
1222 if (idx >= agc->nr_gpio_sets) {
1223 qemu_log_mask(LOG_GUEST_ERROR,
1224 "%s: interrupt status index: %d, out of bounds\n",
1225 __func__, idx);
1226 return 0;
1227 }
1228
1229 set = &s->sets[idx];
1230 value = (uint64_t) set->int_status;
1231 break;
1232 case R_GPIO_A0_CONTROL ... R_GPIO_AA7_CONTROL:
1233 pin = reg - R_GPIO_A0_CONTROL;
1234
1235 if (pin >= agc->nr_gpio_pins) {
1236 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid pin number: %d\n",
1237 __func__, pin);
1238 return 0;
1239 }
1240
1241 value = aspeed_gpio_2700_read_control_reg(s, pin);
1242 break;
1243 default:
1244 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
1245 PRIx64"\n", __func__, offset);
1246 return 0;
1247 }
1248
1249 trace_aspeed_gpio_read(offset, value);
1250 return value;
1251 }
1252
aspeed_gpio_2700_write(void * opaque,hwaddr offset,uint64_t data,uint32_t size)1253 static void aspeed_gpio_2700_write(void *opaque, hwaddr offset,
1254 uint64_t data, uint32_t size)
1255 {
1256 AspeedGPIOState *s = ASPEED_GPIO(opaque);
1257 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1258 uint64_t reg;
1259 uint32_t pin;
1260 uint32_t idx;
1261
1262 trace_aspeed_gpio_write(offset, data);
1263
1264 reg = offset >> 2;
1265
1266 if (reg >= agc->reg_table_count) {
1267 qemu_log_mask(LOG_GUEST_ERROR,
1268 "%s: offset 0x%" PRIx64 " out of bounds\n",
1269 __func__, offset);
1270 return;
1271 }
1272
1273 switch (reg) {
1274 case R_GPIO_2700_DEBOUNCE_TIME_1 ... R_GPIO_2700_DEBOUNCE_TIME_3:
1275 idx = reg - R_GPIO_2700_DEBOUNCE_TIME_1;
1276
1277 if (idx >= ASPEED_GPIO_NR_DEBOUNCE_REGS) {
1278 qemu_log_mask(LOG_GUEST_ERROR,
1279 "%s: debounce index: %d out of bounds\n",
1280 __func__, idx);
1281 return;
1282 }
1283
1284 s->debounce_regs[idx] = (uint32_t) data;
1285 break;
1286 case R_GPIO_A0_CONTROL ... R_GPIO_AA7_CONTROL:
1287 pin = reg - R_GPIO_A0_CONTROL;
1288
1289 if (pin >= agc->nr_gpio_pins) {
1290 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid pin number: %d\n",
1291 __func__, pin);
1292 return;
1293 }
1294
1295 if (SHARED_FIELD_EX32(data, GPIO_CONTROL_RESERVED)) {
1296 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid reserved data: 0x%"
1297 PRIx64"\n", __func__, data);
1298 return;
1299 }
1300
1301 aspeed_gpio_2700_write_control_reg(s, pin, data);
1302 break;
1303 default:
1304 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
1305 PRIx64"\n", __func__, offset);
1306 break;
1307 }
1308 }
1309
1310 /* Setup functions */
1311 static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1312 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1313 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1314 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1315 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1316 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
1317 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
1318 [6] = {0x0000000f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
1319 };
1320
1321 static const GPIOSetProperties ast2500_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1322 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1323 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1324 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1325 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1326 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
1327 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
1328 [6] = {0x0fffffff, 0x0fffffff, {"Y", "Z", "AA", "AB"} },
1329 [7] = {0x000000ff, 0x000000ff, {"AC"} },
1330 };
1331
1332 static GPIOSetProperties ast2600_3_3v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1333 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1334 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1335 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1336 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1337 [4] = {0xffffffff, 0x00ffffff, {"Q", "R", "S", "T"} },
1338 [5] = {0xffffffff, 0xffffff00, {"U", "V", "W", "X"} },
1339 [6] = {0x0000ffff, 0x0000ffff, {"Y", "Z"} },
1340 };
1341
1342 static GPIOSetProperties ast2600_1_8v_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1343 [0] = {0xffffffff, 0xffffffff, {"18A", "18B", "18C", "18D"} },
1344 [1] = {0x0000000f, 0x0000000f, {"18E"} },
1345 };
1346
1347 static GPIOSetProperties ast1030_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1348 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1349 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
1350 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1351 [3] = {0xffffff3f, 0xffffff3f, {"M", "N", "O", "P"} },
1352 [4] = {0xff060c1f, 0x00060c1f, {"Q", "R", "S", "T"} },
1353 [5] = {0x000000ff, 0x00000000, {"U"} },
1354 };
1355
1356 static GPIOSetProperties ast2700_set_props[ASPEED_GPIO_MAX_NR_SETS] = {
1357 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
1358 [1] = {0x0fffffff, 0x0fffffff, {"E", "F", "G", "H"} },
1359 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
1360 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
1361 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
1362 [5] = {0xffffffff, 0xffffffff, {"U", "V", "W", "X"} },
1363 [6] = {0x00ffffff, 0x00ffffff, {"Y", "Z", "AA"} },
1364 };
1365
1366 static const MemoryRegionOps aspeed_gpio_ops = {
1367 .read = aspeed_gpio_read,
1368 .write = aspeed_gpio_write,
1369 .endianness = DEVICE_LITTLE_ENDIAN,
1370 .valid.min_access_size = 4,
1371 .valid.max_access_size = 4,
1372 };
1373
1374 static const MemoryRegionOps aspeed_gpio_2700_ops = {
1375 .read = aspeed_gpio_2700_read,
1376 .write = aspeed_gpio_2700_write,
1377 .endianness = DEVICE_LITTLE_ENDIAN,
1378 .valid.min_access_size = 4,
1379 .valid.max_access_size = 4,
1380 };
1381
aspeed_gpio_reset(DeviceState * dev)1382 static void aspeed_gpio_reset(DeviceState *dev)
1383 {
1384 AspeedGPIOState *s = ASPEED_GPIO(dev);
1385
1386 /* TODO: respect the reset tolerance registers */
1387 memset(s->sets, 0, sizeof(s->sets));
1388 }
1389
aspeed_gpio_realize(DeviceState * dev,Error ** errp)1390 static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
1391 {
1392 AspeedGPIOState *s = ASPEED_GPIO(dev);
1393 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1394 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1395
1396 /* Interrupt parent line */
1397 sysbus_init_irq(sbd, &s->irq);
1398
1399 /* Individual GPIOs */
1400 for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
1401 const GPIOSetProperties *props = &agc->props[i];
1402 uint32_t skip = ~(props->input | props->output);
1403 for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
1404 if (skip >> j & 1) {
1405 continue;
1406 }
1407 sysbus_init_irq(sbd, &s->gpios[i][j]);
1408 }
1409 }
1410
1411 memory_region_init_io(&s->iomem, OBJECT(s), agc->reg_ops, s,
1412 TYPE_ASPEED_GPIO, agc->mem_size);
1413
1414 sysbus_init_mmio(sbd, &s->iomem);
1415 }
1416
aspeed_gpio_init(Object * obj)1417 static void aspeed_gpio_init(Object *obj)
1418 {
1419 AspeedGPIOState *s = ASPEED_GPIO(obj);
1420 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
1421
1422 for (int i = 0; i < ASPEED_GPIO_MAX_NR_SETS; i++) {
1423 const GPIOSetProperties *props = &agc->props[i];
1424 uint32_t skip = ~(props->input | props->output);
1425 for (int j = 0; j < ASPEED_GPIOS_PER_SET; j++) {
1426 if (skip >> j & 1) {
1427 continue;
1428 }
1429 int group_idx = j / GPIOS_PER_GROUP;
1430 int pin_idx = j % GPIOS_PER_GROUP;
1431 const char *group = &props->group_label[group_idx][0];
1432 char *name = g_strdup_printf("gpio%s%d", group, pin_idx);
1433 object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
1434 aspeed_gpio_set_pin, NULL, NULL);
1435 g_free(name);
1436 }
1437 }
1438 }
1439
1440 static const VMStateDescription vmstate_gpio_regs = {
1441 .name = TYPE_ASPEED_GPIO"/regs",
1442 .version_id = 1,
1443 .minimum_version_id = 1,
1444 .fields = (const VMStateField[]) {
1445 VMSTATE_UINT32(data_value, GPIOSets),
1446 VMSTATE_UINT32(data_read, GPIOSets),
1447 VMSTATE_UINT32(direction, GPIOSets),
1448 VMSTATE_UINT32(int_enable, GPIOSets),
1449 VMSTATE_UINT32(int_sens_0, GPIOSets),
1450 VMSTATE_UINT32(int_sens_1, GPIOSets),
1451 VMSTATE_UINT32(int_sens_2, GPIOSets),
1452 VMSTATE_UINT32(int_status, GPIOSets),
1453 VMSTATE_UINT32(reset_tol, GPIOSets),
1454 VMSTATE_UINT32(cmd_source_0, GPIOSets),
1455 VMSTATE_UINT32(cmd_source_1, GPIOSets),
1456 VMSTATE_UINT32(debounce_1, GPIOSets),
1457 VMSTATE_UINT32(debounce_2, GPIOSets),
1458 VMSTATE_UINT32(input_mask, GPIOSets),
1459 VMSTATE_END_OF_LIST(),
1460 }
1461 };
1462
1463 static const VMStateDescription vmstate_aspeed_gpio = {
1464 .name = TYPE_ASPEED_GPIO,
1465 .version_id = 1,
1466 .minimum_version_id = 1,
1467 .fields = (const VMStateField[]) {
1468 VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS,
1469 1, vmstate_gpio_regs, GPIOSets),
1470 VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState,
1471 ASPEED_GPIO_NR_DEBOUNCE_REGS),
1472 VMSTATE_END_OF_LIST(),
1473 }
1474 };
1475
aspeed_gpio_class_init(ObjectClass * klass,const void * data)1476 static void aspeed_gpio_class_init(ObjectClass *klass, const void *data)
1477 {
1478 DeviceClass *dc = DEVICE_CLASS(klass);
1479
1480 dc->realize = aspeed_gpio_realize;
1481 device_class_set_legacy_reset(dc, aspeed_gpio_reset);
1482 dc->desc = "Aspeed GPIO Controller";
1483 dc->vmsd = &vmstate_aspeed_gpio;
1484 }
1485
aspeed_gpio_ast2400_class_init(ObjectClass * klass,const void * data)1486 static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, const void *data)
1487 {
1488 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1489
1490 agc->props = ast2400_set_props;
1491 agc->nr_gpio_pins = 216;
1492 agc->nr_gpio_sets = 7;
1493 agc->reg_table = aspeed_3_3v_gpios;
1494 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1495 agc->mem_size = 0x1000;
1496 agc->reg_ops = &aspeed_gpio_ops;
1497 }
1498
aspeed_gpio_2500_class_init(ObjectClass * klass,const void * data)1499 static void aspeed_gpio_2500_class_init(ObjectClass *klass, const void *data)
1500 {
1501 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1502
1503 agc->props = ast2500_set_props;
1504 agc->nr_gpio_pins = 228;
1505 agc->nr_gpio_sets = 8;
1506 agc->reg_table = aspeed_3_3v_gpios;
1507 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1508 agc->mem_size = 0x1000;
1509 agc->reg_ops = &aspeed_gpio_ops;
1510 }
1511
aspeed_gpio_ast2600_3_3v_class_init(ObjectClass * klass,const void * data)1512 static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass,
1513 const void *data)
1514 {
1515 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1516
1517 agc->props = ast2600_3_3v_set_props;
1518 agc->nr_gpio_pins = 208;
1519 agc->nr_gpio_sets = 7;
1520 agc->reg_table = aspeed_3_3v_gpios;
1521 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1522 agc->mem_size = 0x800;
1523 agc->reg_ops = &aspeed_gpio_ops;
1524 }
1525
aspeed_gpio_ast2600_1_8v_class_init(ObjectClass * klass,const void * data)1526 static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass,
1527 const void *data)
1528 {
1529 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1530
1531 agc->props = ast2600_1_8v_set_props;
1532 agc->nr_gpio_pins = 36;
1533 agc->nr_gpio_sets = 2;
1534 agc->reg_table = aspeed_1_8v_gpios;
1535 agc->reg_table_count = GPIO_1_8V_REG_ARRAY_SIZE;
1536 agc->mem_size = 0x800;
1537 agc->reg_ops = &aspeed_gpio_ops;
1538 }
1539
aspeed_gpio_1030_class_init(ObjectClass * klass,const void * data)1540 static void aspeed_gpio_1030_class_init(ObjectClass *klass, const void *data)
1541 {
1542 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1543
1544 agc->props = ast1030_set_props;
1545 agc->nr_gpio_pins = 151;
1546 agc->nr_gpio_sets = 6;
1547 agc->reg_table = aspeed_3_3v_gpios;
1548 agc->reg_table_count = GPIO_3_3V_REG_ARRAY_SIZE;
1549 agc->mem_size = 0x1000;
1550 agc->reg_ops = &aspeed_gpio_ops;
1551 }
1552
aspeed_gpio_2700_class_init(ObjectClass * klass,const void * data)1553 static void aspeed_gpio_2700_class_init(ObjectClass *klass, const void *data)
1554 {
1555 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1556
1557 agc->props = ast2700_set_props;
1558 agc->nr_gpio_pins = 216;
1559 agc->nr_gpio_sets = 7;
1560 agc->reg_table_count = GPIO_2700_REG_ARRAY_SIZE;
1561 agc->mem_size = 0x1000;
1562 agc->reg_ops = &aspeed_gpio_2700_ops;
1563 }
1564
1565 static const TypeInfo aspeed_gpio_info = {
1566 .name = TYPE_ASPEED_GPIO,
1567 .parent = TYPE_SYS_BUS_DEVICE,
1568 .instance_size = sizeof(AspeedGPIOState),
1569 .class_size = sizeof(AspeedGPIOClass),
1570 .class_init = aspeed_gpio_class_init,
1571 .abstract = true,
1572 };
1573
1574 static const TypeInfo aspeed_gpio_ast2400_info = {
1575 .name = TYPE_ASPEED_GPIO "-ast2400",
1576 .parent = TYPE_ASPEED_GPIO,
1577 .class_init = aspeed_gpio_ast2400_class_init,
1578 .instance_init = aspeed_gpio_init,
1579 };
1580
1581 static const TypeInfo aspeed_gpio_ast2500_info = {
1582 .name = TYPE_ASPEED_GPIO "-ast2500",
1583 .parent = TYPE_ASPEED_GPIO,
1584 .class_init = aspeed_gpio_2500_class_init,
1585 .instance_init = aspeed_gpio_init,
1586 };
1587
1588 static const TypeInfo aspeed_gpio_ast2600_3_3v_info = {
1589 .name = TYPE_ASPEED_GPIO "-ast2600",
1590 .parent = TYPE_ASPEED_GPIO,
1591 .class_init = aspeed_gpio_ast2600_3_3v_class_init,
1592 .instance_init = aspeed_gpio_init,
1593 };
1594
1595 static const TypeInfo aspeed_gpio_ast2600_1_8v_info = {
1596 .name = TYPE_ASPEED_GPIO "-ast2600-1_8v",
1597 .parent = TYPE_ASPEED_GPIO,
1598 .class_init = aspeed_gpio_ast2600_1_8v_class_init,
1599 .instance_init = aspeed_gpio_init,
1600 };
1601
1602 static const TypeInfo aspeed_gpio_ast1030_info = {
1603 .name = TYPE_ASPEED_GPIO "-ast1030",
1604 .parent = TYPE_ASPEED_GPIO,
1605 .class_init = aspeed_gpio_1030_class_init,
1606 .instance_init = aspeed_gpio_init,
1607 };
1608
1609 static const TypeInfo aspeed_gpio_ast2700_info = {
1610 .name = TYPE_ASPEED_GPIO "-ast2700",
1611 .parent = TYPE_ASPEED_GPIO,
1612 .class_init = aspeed_gpio_2700_class_init,
1613 .instance_init = aspeed_gpio_init,
1614 };
1615
aspeed_gpio_register_types(void)1616 static void aspeed_gpio_register_types(void)
1617 {
1618 type_register_static(&aspeed_gpio_info);
1619 type_register_static(&aspeed_gpio_ast2400_info);
1620 type_register_static(&aspeed_gpio_ast2500_info);
1621 type_register_static(&aspeed_gpio_ast2600_3_3v_info);
1622 type_register_static(&aspeed_gpio_ast2600_1_8v_info);
1623 type_register_static(&aspeed_gpio_ast1030_info);
1624 type_register_static(&aspeed_gpio_ast2700_info);
1625 }
1626
1627 type_init(aspeed_gpio_register_types);
1628