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 19 #define GPIOS_PER_REG 32 20 #define GPIOS_PER_SET GPIOS_PER_REG 21 #define GPIO_PIN_GAP_SIZE 4 22 #define GPIOS_PER_GROUP 8 23 #define GPIO_GROUP_SHIFT 3 24 25 /* GPIO Source Types */ 26 #define ASPEED_CMD_SRC_MASK 0x01010101 27 #define ASPEED_SOURCE_ARM 0 28 #define ASPEED_SOURCE_LPC 1 29 #define ASPEED_SOURCE_COPROCESSOR 2 30 #define ASPEED_SOURCE_RESERVED 3 31 32 /* GPIO Interrupt Triggers */ 33 /* 34 * For each set of gpios there are three sensitivity registers that control 35 * the interrupt trigger mode. 36 * 37 * | 2 | 1 | 0 | trigger mode 38 * ----------------------------- 39 * | 0 | 0 | 0 | falling-edge 40 * | 0 | 0 | 1 | rising-edge 41 * | 0 | 1 | 0 | level-low 42 * | 0 | 1 | 1 | level-high 43 * | 1 | X | X | dual-edge 44 */ 45 #define ASPEED_FALLING_EDGE 0 46 #define ASPEED_RISING_EDGE 1 47 #define ASPEED_LEVEL_LOW 2 48 #define ASPEED_LEVEL_HIGH 3 49 #define ASPEED_DUAL_EDGE 4 50 51 /* GPIO Register Address Offsets */ 52 #define GPIO_ABCD_DATA_VALUE (0x000 >> 2) 53 #define GPIO_ABCD_DIRECTION (0x004 >> 2) 54 #define GPIO_ABCD_INT_ENABLE (0x008 >> 2) 55 #define GPIO_ABCD_INT_SENS_0 (0x00C >> 2) 56 #define GPIO_ABCD_INT_SENS_1 (0x010 >> 2) 57 #define GPIO_ABCD_INT_SENS_2 (0x014 >> 2) 58 #define GPIO_ABCD_INT_STATUS (0x018 >> 2) 59 #define GPIO_ABCD_RESET_TOLERANT (0x01C >> 2) 60 #define GPIO_EFGH_DATA_VALUE (0x020 >> 2) 61 #define GPIO_EFGH_DIRECTION (0x024 >> 2) 62 #define GPIO_EFGH_INT_ENABLE (0x028 >> 2) 63 #define GPIO_EFGH_INT_SENS_0 (0x02C >> 2) 64 #define GPIO_EFGH_INT_SENS_1 (0x030 >> 2) 65 #define GPIO_EFGH_INT_SENS_2 (0x034 >> 2) 66 #define GPIO_EFGH_INT_STATUS (0x038 >> 2) 67 #define GPIO_EFGH_RESET_TOLERANT (0x03C >> 2) 68 #define GPIO_ABCD_DEBOUNCE_1 (0x040 >> 2) 69 #define GPIO_ABCD_DEBOUNCE_2 (0x044 >> 2) 70 #define GPIO_EFGH_DEBOUNCE_1 (0x048 >> 2) 71 #define GPIO_EFGH_DEBOUNCE_2 (0x04C >> 2) 72 #define GPIO_DEBOUNCE_TIME_1 (0x050 >> 2) 73 #define GPIO_DEBOUNCE_TIME_2 (0x054 >> 2) 74 #define GPIO_DEBOUNCE_TIME_3 (0x058 >> 2) 75 #define GPIO_ABCD_COMMAND_SRC_0 (0x060 >> 2) 76 #define GPIO_ABCD_COMMAND_SRC_1 (0x064 >> 2) 77 #define GPIO_EFGH_COMMAND_SRC_0 (0x068 >> 2) 78 #define GPIO_EFGH_COMMAND_SRC_1 (0x06C >> 2) 79 #define GPIO_IJKL_DATA_VALUE (0x070 >> 2) 80 #define GPIO_IJKL_DIRECTION (0x074 >> 2) 81 #define GPIO_MNOP_DATA_VALUE (0x078 >> 2) 82 #define GPIO_MNOP_DIRECTION (0x07C >> 2) 83 #define GPIO_QRST_DATA_VALUE (0x080 >> 2) 84 #define GPIO_QRST_DIRECTION (0x084 >> 2) 85 #define GPIO_UVWX_DATA_VALUE (0x088 >> 2) 86 #define GPIO_UVWX_DIRECTION (0x08C >> 2) 87 #define GPIO_IJKL_COMMAND_SRC_0 (0x090 >> 2) 88 #define GPIO_IJKL_COMMAND_SRC_1 (0x094 >> 2) 89 #define GPIO_IJKL_INT_ENABLE (0x098 >> 2) 90 #define GPIO_IJKL_INT_SENS_0 (0x09C >> 2) 91 #define GPIO_IJKL_INT_SENS_1 (0x0A0 >> 2) 92 #define GPIO_IJKL_INT_SENS_2 (0x0A4 >> 2) 93 #define GPIO_IJKL_INT_STATUS (0x0A8 >> 2) 94 #define GPIO_IJKL_RESET_TOLERANT (0x0AC >> 2) 95 #define GPIO_IJKL_DEBOUNCE_1 (0x0B0 >> 2) 96 #define GPIO_IJKL_DEBOUNCE_2 (0x0B4 >> 2) 97 #define GPIO_IJKL_INPUT_MASK (0x0B8 >> 2) 98 #define GPIO_ABCD_DATA_READ (0x0C0 >> 2) 99 #define GPIO_EFGH_DATA_READ (0x0C4 >> 2) 100 #define GPIO_IJKL_DATA_READ (0x0C8 >> 2) 101 #define GPIO_MNOP_DATA_READ (0x0CC >> 2) 102 #define GPIO_QRST_DATA_READ (0x0D0 >> 2) 103 #define GPIO_UVWX_DATA_READ (0x0D4 >> 2) 104 #define GPIO_YZAAAB_DATA_READ (0x0D8 >> 2) 105 #define GPIO_AC_DATA_READ (0x0DC >> 2) 106 #define GPIO_MNOP_COMMAND_SRC_0 (0x0E0 >> 2) 107 #define GPIO_MNOP_COMMAND_SRC_1 (0x0E4 >> 2) 108 #define GPIO_MNOP_INT_ENABLE (0x0E8 >> 2) 109 #define GPIO_MNOP_INT_SENS_0 (0x0EC >> 2) 110 #define GPIO_MNOP_INT_SENS_1 (0x0F0 >> 2) 111 #define GPIO_MNOP_INT_SENS_2 (0x0F4 >> 2) 112 #define GPIO_MNOP_INT_STATUS (0x0F8 >> 2) 113 #define GPIO_MNOP_RESET_TOLERANT (0x0FC >> 2) 114 #define GPIO_MNOP_DEBOUNCE_1 (0x100 >> 2) 115 #define GPIO_MNOP_DEBOUNCE_2 (0x104 >> 2) 116 #define GPIO_MNOP_INPUT_MASK (0x108 >> 2) 117 #define GPIO_QRST_COMMAND_SRC_0 (0x110 >> 2) 118 #define GPIO_QRST_COMMAND_SRC_1 (0x114 >> 2) 119 #define GPIO_QRST_INT_ENABLE (0x118 >> 2) 120 #define GPIO_QRST_INT_SENS_0 (0x11C >> 2) 121 #define GPIO_QRST_INT_SENS_1 (0x120 >> 2) 122 #define GPIO_QRST_INT_SENS_2 (0x124 >> 2) 123 #define GPIO_QRST_INT_STATUS (0x128 >> 2) 124 #define GPIO_QRST_RESET_TOLERANT (0x12C >> 2) 125 #define GPIO_QRST_DEBOUNCE_1 (0x130 >> 2) 126 #define GPIO_QRST_DEBOUNCE_2 (0x134 >> 2) 127 #define GPIO_QRST_INPUT_MASK (0x138 >> 2) 128 #define GPIO_UVWX_COMMAND_SRC_0 (0x140 >> 2) 129 #define GPIO_UVWX_COMMAND_SRC_1 (0x144 >> 2) 130 #define GPIO_UVWX_INT_ENABLE (0x148 >> 2) 131 #define GPIO_UVWX_INT_SENS_0 (0x14C >> 2) 132 #define GPIO_UVWX_INT_SENS_1 (0x150 >> 2) 133 #define GPIO_UVWX_INT_SENS_2 (0x154 >> 2) 134 #define GPIO_UVWX_INT_STATUS (0x158 >> 2) 135 #define GPIO_UVWX_RESET_TOLERANT (0x15C >> 2) 136 #define GPIO_UVWX_DEBOUNCE_1 (0x160 >> 2) 137 #define GPIO_UVWX_DEBOUNCE_2 (0x164 >> 2) 138 #define GPIO_UVWX_INPUT_MASK (0x168 >> 2) 139 #define GPIO_YZAAAB_COMMAND_SRC_0 (0x170 >> 2) 140 #define GPIO_YZAAAB_COMMAND_SRC_1 (0x174 >> 2) 141 #define GPIO_YZAAAB_INT_ENABLE (0x178 >> 2) 142 #define GPIO_YZAAAB_INT_SENS_0 (0x17C >> 2) 143 #define GPIO_YZAAAB_INT_SENS_1 (0x180 >> 2) 144 #define GPIO_YZAAAB_INT_SENS_2 (0x184 >> 2) 145 #define GPIO_YZAAAB_INT_STATUS (0x188 >> 2) 146 #define GPIO_YZAAAB_RESET_TOLERANT (0x18C >> 2) 147 #define GPIO_YZAAAB_DEBOUNCE_1 (0x190 >> 2) 148 #define GPIO_YZAAAB_DEBOUNCE_2 (0x194 >> 2) 149 #define GPIO_YZAAAB_INPUT_MASK (0x198 >> 2) 150 #define GPIO_AC_COMMAND_SRC_0 (0x1A0 >> 2) 151 #define GPIO_AC_COMMAND_SRC_1 (0x1A4 >> 2) 152 #define GPIO_AC_INT_ENABLE (0x1A8 >> 2) 153 #define GPIO_AC_INT_SENS_0 (0x1AC >> 2) 154 #define GPIO_AC_INT_SENS_1 (0x1B0 >> 2) 155 #define GPIO_AC_INT_SENS_2 (0x1B4 >> 2) 156 #define GPIO_AC_INT_STATUS (0x1B8 >> 2) 157 #define GPIO_AC_RESET_TOLERANT (0x1BC >> 2) 158 #define GPIO_AC_DEBOUNCE_1 (0x1C0 >> 2) 159 #define GPIO_AC_DEBOUNCE_2 (0x1C4 >> 2) 160 #define GPIO_AC_INPUT_MASK (0x1C8 >> 2) 161 #define GPIO_ABCD_INPUT_MASK (0x1D0 >> 2) 162 #define GPIO_EFGH_INPUT_MASK (0x1D4 >> 2) 163 #define GPIO_YZAAAB_DATA_VALUE (0x1E0 >> 2) 164 #define GPIO_YZAAAB_DIRECTION (0x1E4 >> 2) 165 #define GPIO_AC_DATA_VALUE (0x1E8 >> 2) 166 #define GPIO_AC_DIRECTION (0x1EC >> 2) 167 #define GPIO_3_6V_MEM_SIZE 0x1F0 168 #define GPIO_3_6V_REG_ARRAY_SIZE (GPIO_3_6V_MEM_SIZE >> 2) 169 170 /* AST2600 only - 1.8V gpios */ 171 /* 172 * The AST2600 has same 3.6V gpios as the AST2400 (memory offsets 0x0-0x198) 173 * and additional 1.8V gpios (memory offsets 0x800-0x9D4). 174 */ 175 #define GPIO_1_8V_REG_OFFSET 0x800 176 #define GPIO_1_8V_ABCD_DATA_VALUE ((0x800 - GPIO_1_8V_REG_OFFSET) >> 2) 177 #define GPIO_1_8V_ABCD_DIRECTION ((0x804 - GPIO_1_8V_REG_OFFSET) >> 2) 178 #define GPIO_1_8V_ABCD_INT_ENABLE ((0x808 - GPIO_1_8V_REG_OFFSET) >> 2) 179 #define GPIO_1_8V_ABCD_INT_SENS_0 ((0x80C - GPIO_1_8V_REG_OFFSET) >> 2) 180 #define GPIO_1_8V_ABCD_INT_SENS_1 ((0x810 - GPIO_1_8V_REG_OFFSET) >> 2) 181 #define GPIO_1_8V_ABCD_INT_SENS_2 ((0x814 - GPIO_1_8V_REG_OFFSET) >> 2) 182 #define GPIO_1_8V_ABCD_INT_STATUS ((0x818 - GPIO_1_8V_REG_OFFSET) >> 2) 183 #define GPIO_1_8V_ABCD_RESET_TOLERANT ((0x81C - GPIO_1_8V_REG_OFFSET) >> 2) 184 #define GPIO_1_8V_E_DATA_VALUE ((0x820 - GPIO_1_8V_REG_OFFSET) >> 2) 185 #define GPIO_1_8V_E_DIRECTION ((0x824 - GPIO_1_8V_REG_OFFSET) >> 2) 186 #define GPIO_1_8V_E_INT_ENABLE ((0x828 - GPIO_1_8V_REG_OFFSET) >> 2) 187 #define GPIO_1_8V_E_INT_SENS_0 ((0x82C - GPIO_1_8V_REG_OFFSET) >> 2) 188 #define GPIO_1_8V_E_INT_SENS_1 ((0x830 - GPIO_1_8V_REG_OFFSET) >> 2) 189 #define GPIO_1_8V_E_INT_SENS_2 ((0x834 - GPIO_1_8V_REG_OFFSET) >> 2) 190 #define GPIO_1_8V_E_INT_STATUS ((0x838 - GPIO_1_8V_REG_OFFSET) >> 2) 191 #define GPIO_1_8V_E_RESET_TOLERANT ((0x83C - GPIO_1_8V_REG_OFFSET) >> 2) 192 #define GPIO_1_8V_ABCD_DEBOUNCE_1 ((0x840 - GPIO_1_8V_REG_OFFSET) >> 2) 193 #define GPIO_1_8V_ABCD_DEBOUNCE_2 ((0x844 - GPIO_1_8V_REG_OFFSET) >> 2) 194 #define GPIO_1_8V_E_DEBOUNCE_1 ((0x848 - GPIO_1_8V_REG_OFFSET) >> 2) 195 #define GPIO_1_8V_E_DEBOUNCE_2 ((0x84C - GPIO_1_8V_REG_OFFSET) >> 2) 196 #define GPIO_1_8V_DEBOUNCE_TIME_1 ((0x850 - GPIO_1_8V_REG_OFFSET) >> 2) 197 #define GPIO_1_8V_DEBOUNCE_TIME_2 ((0x854 - GPIO_1_8V_REG_OFFSET) >> 2) 198 #define GPIO_1_8V_DEBOUNCE_TIME_3 ((0x858 - GPIO_1_8V_REG_OFFSET) >> 2) 199 #define GPIO_1_8V_ABCD_COMMAND_SRC_0 ((0x860 - GPIO_1_8V_REG_OFFSET) >> 2) 200 #define GPIO_1_8V_ABCD_COMMAND_SRC_1 ((0x864 - GPIO_1_8V_REG_OFFSET) >> 2) 201 #define GPIO_1_8V_E_COMMAND_SRC_0 ((0x868 - GPIO_1_8V_REG_OFFSET) >> 2) 202 #define GPIO_1_8V_E_COMMAND_SRC_1 ((0x86C - GPIO_1_8V_REG_OFFSET) >> 2) 203 #define GPIO_1_8V_ABCD_DATA_READ ((0x8C0 - GPIO_1_8V_REG_OFFSET) >> 2) 204 #define GPIO_1_8V_E_DATA_READ ((0x8C4 - GPIO_1_8V_REG_OFFSET) >> 2) 205 #define GPIO_1_8V_ABCD_INPUT_MASK ((0x9D0 - GPIO_1_8V_REG_OFFSET) >> 2) 206 #define GPIO_1_8V_E_INPUT_MASK ((0x9D4 - GPIO_1_8V_REG_OFFSET) >> 2) 207 #define GPIO_1_8V_MEM_SIZE 0x9D8 208 #define GPIO_1_8V_REG_ARRAY_SIZE ((GPIO_1_8V_MEM_SIZE - \ 209 GPIO_1_8V_REG_OFFSET) >> 2) 210 #define GPIO_MAX_MEM_SIZE MAX(GPIO_3_6V_MEM_SIZE, GPIO_1_8V_MEM_SIZE) 211 212 static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio) 213 { 214 uint32_t falling_edge = 0, rising_edge = 0; 215 uint32_t int_trigger = extract32(regs->int_sens_0, gpio, 1) 216 | extract32(regs->int_sens_1, gpio, 1) << 1 217 | extract32(regs->int_sens_2, gpio, 1) << 2; 218 uint32_t gpio_curr_high = extract32(regs->data_value, gpio, 1); 219 uint32_t gpio_int_enabled = extract32(regs->int_enable, gpio, 1); 220 221 if (!gpio_int_enabled) { 222 return 0; 223 } 224 225 /* Detect edges */ 226 if (gpio_curr_high && !gpio_prev_high) { 227 rising_edge = 1; 228 } else if (!gpio_curr_high && gpio_prev_high) { 229 falling_edge = 1; 230 } 231 232 if (((int_trigger == ASPEED_FALLING_EDGE) && falling_edge) || 233 ((int_trigger == ASPEED_RISING_EDGE) && rising_edge) || 234 ((int_trigger == ASPEED_LEVEL_LOW) && !gpio_curr_high) || 235 ((int_trigger == ASPEED_LEVEL_HIGH) && gpio_curr_high) || 236 ((int_trigger >= ASPEED_DUAL_EDGE) && (rising_edge || falling_edge))) 237 { 238 regs->int_status = deposit32(regs->int_status, gpio, 1, 1); 239 return 1; 240 } 241 return 0; 242 } 243 244 #define nested_struct_index(ta, pa, m, tb, pb) \ 245 (pb - ((tb *)(((char *)pa) + offsetof(ta, m)))) 246 247 static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, GPIOSets *regs) 248 { 249 return nested_struct_index(AspeedGPIOState, s, sets, GPIOSets, regs); 250 } 251 252 static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs, 253 uint32_t value) 254 { 255 uint32_t input_mask = regs->input_mask; 256 uint32_t direction = regs->direction; 257 uint32_t old = regs->data_value; 258 uint32_t new = value; 259 uint32_t diff; 260 int gpio; 261 262 diff = old ^ new; 263 if (diff) { 264 for (gpio = 0; gpio < GPIOS_PER_REG; gpio++) { 265 uint32_t mask = 1 << gpio; 266 267 /* If the gpio needs to be updated... */ 268 if (!(diff & mask)) { 269 continue; 270 } 271 272 /* ...and we're output or not input-masked... */ 273 if (!(direction & mask) && (input_mask & mask)) { 274 continue; 275 } 276 277 /* ...then update the state. */ 278 if (mask & new) { 279 regs->data_value |= mask; 280 } else { 281 regs->data_value &= ~mask; 282 } 283 284 /* If the gpio is set to output... */ 285 if (direction & mask) { 286 /* ...trigger the line-state IRQ */ 287 ptrdiff_t set = aspeed_gpio_set_idx(s, regs); 288 size_t offset = set * GPIOS_PER_SET + gpio; 289 qemu_set_irq(s->gpios[offset], !!(new & mask)); 290 } else { 291 /* ...otherwise if we meet the line's current IRQ policy... */ 292 if (aspeed_evaluate_irq(regs, old & mask, gpio)) { 293 /* ...trigger the VIC IRQ */ 294 s->pending++; 295 } 296 } 297 } 298 } 299 qemu_set_irq(s->irq, !!(s->pending)); 300 } 301 302 static uint32_t aspeed_adjust_pin(AspeedGPIOState *s, uint32_t pin) 303 { 304 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); 305 /* 306 * The 2500 has a 4 pin gap in group AB and the 2400 has a 4 pin 307 * gap in group Y (and only four pins in AB but this is the last group so 308 * it doesn't matter). 309 */ 310 if (agc->gap && pin >= agc->gap) { 311 pin += GPIO_PIN_GAP_SIZE; 312 } 313 314 return pin; 315 } 316 317 static bool aspeed_gpio_get_pin_level(AspeedGPIOState *s, uint32_t set_idx, 318 uint32_t pin) 319 { 320 uint32_t reg_val; 321 uint32_t pin_mask = 1 << pin; 322 323 reg_val = s->sets[set_idx].data_value; 324 325 return !!(reg_val & pin_mask); 326 } 327 328 static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, uint32_t set_idx, 329 uint32_t pin, bool level) 330 { 331 uint32_t value = s->sets[set_idx].data_value; 332 uint32_t pin_mask = 1 << pin; 333 334 if (level) { 335 value |= pin_mask; 336 } else { 337 value &= !pin_mask; 338 } 339 340 aspeed_gpio_update(s, &s->sets[set_idx], value); 341 } 342 343 /* 344 * | src_1 | src_2 | source | 345 * |-----------------------------| 346 * | 0 | 0 | ARM | 347 * | 0 | 1 | LPC | 348 * | 1 | 0 | Coprocessor| 349 * | 1 | 1 | Reserved | 350 * 351 * Once the source of a set is programmed, corresponding bits in the 352 * data_value, direction, interrupt [enable, sens[0-2]], reset_tol and 353 * debounce registers can only be written by the source. 354 * 355 * Source is ARM by default 356 * only bits 24, 16, 8, and 0 can be set 357 * 358 * we don't currently have a model for the LPC or Coprocessor 359 */ 360 static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value, 361 uint32_t value) 362 { 363 int i; 364 int cmd_source; 365 366 /* assume the source is always ARM for now */ 367 int source = ASPEED_SOURCE_ARM; 368 369 uint32_t new_value = 0; 370 371 /* for each group in set */ 372 for (i = 0; i < GPIOS_PER_REG; i += GPIOS_PER_GROUP) { 373 cmd_source = extract32(regs->cmd_source_0, i, 1) 374 | (extract32(regs->cmd_source_1, i, 1) << 1); 375 376 if (source == cmd_source) { 377 new_value |= (0xff << i) & value; 378 } else { 379 new_value |= (0xff << i) & old_value; 380 } 381 } 382 return new_value; 383 } 384 385 static const AspeedGPIOReg aspeed_3_6v_gpios[GPIO_3_6V_REG_ARRAY_SIZE] = { 386 /* Set ABCD */ 387 [GPIO_ABCD_DATA_VALUE] = { 0, gpio_reg_data_value }, 388 [GPIO_ABCD_DIRECTION] = { 0, gpio_reg_direction }, 389 [GPIO_ABCD_INT_ENABLE] = { 0, gpio_reg_int_enable }, 390 [GPIO_ABCD_INT_SENS_0] = { 0, gpio_reg_int_sens_0 }, 391 [GPIO_ABCD_INT_SENS_1] = { 0, gpio_reg_int_sens_1 }, 392 [GPIO_ABCD_INT_SENS_2] = { 0, gpio_reg_int_sens_2 }, 393 [GPIO_ABCD_INT_STATUS] = { 0, gpio_reg_int_status }, 394 [GPIO_ABCD_RESET_TOLERANT] = { 0, gpio_reg_reset_tolerant }, 395 [GPIO_ABCD_DEBOUNCE_1] = { 0, gpio_reg_debounce_1 }, 396 [GPIO_ABCD_DEBOUNCE_2] = { 0, gpio_reg_debounce_2 }, 397 [GPIO_ABCD_COMMAND_SRC_0] = { 0, gpio_reg_cmd_source_0 }, 398 [GPIO_ABCD_COMMAND_SRC_1] = { 0, gpio_reg_cmd_source_1 }, 399 [GPIO_ABCD_DATA_READ] = { 0, gpio_reg_data_read }, 400 [GPIO_ABCD_INPUT_MASK] = { 0, gpio_reg_input_mask }, 401 /* Set EFGH */ 402 [GPIO_EFGH_DATA_VALUE] = { 1, gpio_reg_data_value }, 403 [GPIO_EFGH_DIRECTION] = { 1, gpio_reg_direction }, 404 [GPIO_EFGH_INT_ENABLE] = { 1, gpio_reg_int_enable }, 405 [GPIO_EFGH_INT_SENS_0] = { 1, gpio_reg_int_sens_0 }, 406 [GPIO_EFGH_INT_SENS_1] = { 1, gpio_reg_int_sens_1 }, 407 [GPIO_EFGH_INT_SENS_2] = { 1, gpio_reg_int_sens_2 }, 408 [GPIO_EFGH_INT_STATUS] = { 1, gpio_reg_int_status }, 409 [GPIO_EFGH_RESET_TOLERANT] = { 1, gpio_reg_reset_tolerant }, 410 [GPIO_EFGH_DEBOUNCE_1] = { 1, gpio_reg_debounce_1 }, 411 [GPIO_EFGH_DEBOUNCE_2] = { 1, gpio_reg_debounce_2 }, 412 [GPIO_EFGH_COMMAND_SRC_0] = { 1, gpio_reg_cmd_source_0 }, 413 [GPIO_EFGH_COMMAND_SRC_1] = { 1, gpio_reg_cmd_source_1 }, 414 [GPIO_EFGH_DATA_READ] = { 1, gpio_reg_data_read }, 415 [GPIO_EFGH_INPUT_MASK] = { 1, gpio_reg_input_mask }, 416 /* Set IJKL */ 417 [GPIO_IJKL_DATA_VALUE] = { 2, gpio_reg_data_value }, 418 [GPIO_IJKL_DIRECTION] = { 2, gpio_reg_direction }, 419 [GPIO_IJKL_INT_ENABLE] = { 2, gpio_reg_int_enable }, 420 [GPIO_IJKL_INT_SENS_0] = { 2, gpio_reg_int_sens_0 }, 421 [GPIO_IJKL_INT_SENS_1] = { 2, gpio_reg_int_sens_1 }, 422 [GPIO_IJKL_INT_SENS_2] = { 2, gpio_reg_int_sens_2 }, 423 [GPIO_IJKL_INT_STATUS] = { 2, gpio_reg_int_status }, 424 [GPIO_IJKL_RESET_TOLERANT] = { 2, gpio_reg_reset_tolerant }, 425 [GPIO_IJKL_DEBOUNCE_1] = { 2, gpio_reg_debounce_1 }, 426 [GPIO_IJKL_DEBOUNCE_2] = { 2, gpio_reg_debounce_2 }, 427 [GPIO_IJKL_COMMAND_SRC_0] = { 2, gpio_reg_cmd_source_0 }, 428 [GPIO_IJKL_COMMAND_SRC_1] = { 2, gpio_reg_cmd_source_1 }, 429 [GPIO_IJKL_DATA_READ] = { 2, gpio_reg_data_read }, 430 [GPIO_IJKL_INPUT_MASK] = { 2, gpio_reg_input_mask }, 431 /* Set MNOP */ 432 [GPIO_MNOP_DATA_VALUE] = { 3, gpio_reg_data_value }, 433 [GPIO_MNOP_DIRECTION] = { 3, gpio_reg_direction }, 434 [GPIO_MNOP_INT_ENABLE] = { 3, gpio_reg_int_enable }, 435 [GPIO_MNOP_INT_SENS_0] = { 3, gpio_reg_int_sens_0 }, 436 [GPIO_MNOP_INT_SENS_1] = { 3, gpio_reg_int_sens_1 }, 437 [GPIO_MNOP_INT_SENS_2] = { 3, gpio_reg_int_sens_2 }, 438 [GPIO_MNOP_INT_STATUS] = { 3, gpio_reg_int_status }, 439 [GPIO_MNOP_RESET_TOLERANT] = { 3, gpio_reg_reset_tolerant }, 440 [GPIO_MNOP_DEBOUNCE_1] = { 3, gpio_reg_debounce_1 }, 441 [GPIO_MNOP_DEBOUNCE_2] = { 3, gpio_reg_debounce_2 }, 442 [GPIO_MNOP_COMMAND_SRC_0] = { 3, gpio_reg_cmd_source_0 }, 443 [GPIO_MNOP_COMMAND_SRC_1] = { 3, gpio_reg_cmd_source_1 }, 444 [GPIO_MNOP_DATA_READ] = { 3, gpio_reg_data_read }, 445 [GPIO_MNOP_INPUT_MASK] = { 3, gpio_reg_input_mask }, 446 /* Set QRST */ 447 [GPIO_QRST_DATA_VALUE] = { 4, gpio_reg_data_value }, 448 [GPIO_QRST_DIRECTION] = { 4, gpio_reg_direction }, 449 [GPIO_QRST_INT_ENABLE] = { 4, gpio_reg_int_enable }, 450 [GPIO_QRST_INT_SENS_0] = { 4, gpio_reg_int_sens_0 }, 451 [GPIO_QRST_INT_SENS_1] = { 4, gpio_reg_int_sens_1 }, 452 [GPIO_QRST_INT_SENS_2] = { 4, gpio_reg_int_sens_2 }, 453 [GPIO_QRST_INT_STATUS] = { 4, gpio_reg_int_status }, 454 [GPIO_QRST_RESET_TOLERANT] = { 4, gpio_reg_reset_tolerant }, 455 [GPIO_QRST_DEBOUNCE_1] = { 4, gpio_reg_debounce_1 }, 456 [GPIO_QRST_DEBOUNCE_2] = { 4, gpio_reg_debounce_2 }, 457 [GPIO_QRST_COMMAND_SRC_0] = { 4, gpio_reg_cmd_source_0 }, 458 [GPIO_QRST_COMMAND_SRC_1] = { 4, gpio_reg_cmd_source_1 }, 459 [GPIO_QRST_DATA_READ] = { 4, gpio_reg_data_read }, 460 [GPIO_QRST_INPUT_MASK] = { 4, gpio_reg_input_mask }, 461 /* Set UVWX */ 462 [GPIO_UVWX_DATA_VALUE] = { 5, gpio_reg_data_value }, 463 [GPIO_UVWX_DIRECTION] = { 5, gpio_reg_direction }, 464 [GPIO_UVWX_INT_ENABLE] = { 5, gpio_reg_int_enable }, 465 [GPIO_UVWX_INT_SENS_0] = { 5, gpio_reg_int_sens_0 }, 466 [GPIO_UVWX_INT_SENS_1] = { 5, gpio_reg_int_sens_1 }, 467 [GPIO_UVWX_INT_SENS_2] = { 5, gpio_reg_int_sens_2 }, 468 [GPIO_UVWX_INT_STATUS] = { 5, gpio_reg_int_status }, 469 [GPIO_UVWX_RESET_TOLERANT] = { 5, gpio_reg_reset_tolerant }, 470 [GPIO_UVWX_DEBOUNCE_1] = { 5, gpio_reg_debounce_1 }, 471 [GPIO_UVWX_DEBOUNCE_2] = { 5, gpio_reg_debounce_2 }, 472 [GPIO_UVWX_COMMAND_SRC_0] = { 5, gpio_reg_cmd_source_0 }, 473 [GPIO_UVWX_COMMAND_SRC_1] = { 5, gpio_reg_cmd_source_1 }, 474 [GPIO_UVWX_DATA_READ] = { 5, gpio_reg_data_read }, 475 [GPIO_UVWX_INPUT_MASK] = { 5, gpio_reg_input_mask }, 476 /* Set YZAAAB */ 477 [GPIO_YZAAAB_DATA_VALUE] = { 6, gpio_reg_data_value }, 478 [GPIO_YZAAAB_DIRECTION] = { 6, gpio_reg_direction }, 479 [GPIO_YZAAAB_INT_ENABLE] = { 6, gpio_reg_int_enable }, 480 [GPIO_YZAAAB_INT_SENS_0] = { 6, gpio_reg_int_sens_0 }, 481 [GPIO_YZAAAB_INT_SENS_1] = { 6, gpio_reg_int_sens_1 }, 482 [GPIO_YZAAAB_INT_SENS_2] = { 6, gpio_reg_int_sens_2 }, 483 [GPIO_YZAAAB_INT_STATUS] = { 6, gpio_reg_int_status }, 484 [GPIO_YZAAAB_RESET_TOLERANT] = { 6, gpio_reg_reset_tolerant }, 485 [GPIO_YZAAAB_DEBOUNCE_1] = { 6, gpio_reg_debounce_1 }, 486 [GPIO_YZAAAB_DEBOUNCE_2] = { 6, gpio_reg_debounce_2 }, 487 [GPIO_YZAAAB_COMMAND_SRC_0] = { 6, gpio_reg_cmd_source_0 }, 488 [GPIO_YZAAAB_COMMAND_SRC_1] = { 6, gpio_reg_cmd_source_1 }, 489 [GPIO_YZAAAB_DATA_READ] = { 6, gpio_reg_data_read }, 490 [GPIO_YZAAAB_INPUT_MASK] = { 6, gpio_reg_input_mask }, 491 /* Set AC (ast2500 only) */ 492 [GPIO_AC_DATA_VALUE] = { 7, gpio_reg_data_value }, 493 [GPIO_AC_DIRECTION] = { 7, gpio_reg_direction }, 494 [GPIO_AC_INT_ENABLE] = { 7, gpio_reg_int_enable }, 495 [GPIO_AC_INT_SENS_0] = { 7, gpio_reg_int_sens_0 }, 496 [GPIO_AC_INT_SENS_1] = { 7, gpio_reg_int_sens_1 }, 497 [GPIO_AC_INT_SENS_2] = { 7, gpio_reg_int_sens_2 }, 498 [GPIO_AC_INT_STATUS] = { 7, gpio_reg_int_status }, 499 [GPIO_AC_RESET_TOLERANT] = { 7, gpio_reg_reset_tolerant }, 500 [GPIO_AC_DEBOUNCE_1] = { 7, gpio_reg_debounce_1 }, 501 [GPIO_AC_DEBOUNCE_2] = { 7, gpio_reg_debounce_2 }, 502 [GPIO_AC_COMMAND_SRC_0] = { 7, gpio_reg_cmd_source_0 }, 503 [GPIO_AC_COMMAND_SRC_1] = { 7, gpio_reg_cmd_source_1 }, 504 [GPIO_AC_DATA_READ] = { 7, gpio_reg_data_read }, 505 [GPIO_AC_INPUT_MASK] = { 7, gpio_reg_input_mask }, 506 }; 507 508 static const AspeedGPIOReg aspeed_1_8v_gpios[GPIO_1_8V_REG_ARRAY_SIZE] = { 509 /* 1.8V Set ABCD */ 510 [GPIO_1_8V_ABCD_DATA_VALUE] = {0, gpio_reg_data_value}, 511 [GPIO_1_8V_ABCD_DIRECTION] = {0, gpio_reg_direction}, 512 [GPIO_1_8V_ABCD_INT_ENABLE] = {0, gpio_reg_int_enable}, 513 [GPIO_1_8V_ABCD_INT_SENS_0] = {0, gpio_reg_int_sens_0}, 514 [GPIO_1_8V_ABCD_INT_SENS_1] = {0, gpio_reg_int_sens_1}, 515 [GPIO_1_8V_ABCD_INT_SENS_2] = {0, gpio_reg_int_sens_2}, 516 [GPIO_1_8V_ABCD_INT_STATUS] = {0, gpio_reg_int_status}, 517 [GPIO_1_8V_ABCD_RESET_TOLERANT] = {0, gpio_reg_reset_tolerant}, 518 [GPIO_1_8V_ABCD_DEBOUNCE_1] = {0, gpio_reg_debounce_1}, 519 [GPIO_1_8V_ABCD_DEBOUNCE_2] = {0, gpio_reg_debounce_2}, 520 [GPIO_1_8V_ABCD_COMMAND_SRC_0] = {0, gpio_reg_cmd_source_0}, 521 [GPIO_1_8V_ABCD_COMMAND_SRC_1] = {0, gpio_reg_cmd_source_1}, 522 [GPIO_1_8V_ABCD_DATA_READ] = {0, gpio_reg_data_read}, 523 [GPIO_1_8V_ABCD_INPUT_MASK] = {0, gpio_reg_input_mask}, 524 /* 1.8V Set E */ 525 [GPIO_1_8V_E_DATA_VALUE] = {1, gpio_reg_data_value}, 526 [GPIO_1_8V_E_DIRECTION] = {1, gpio_reg_direction}, 527 [GPIO_1_8V_E_INT_ENABLE] = {1, gpio_reg_int_enable}, 528 [GPIO_1_8V_E_INT_SENS_0] = {1, gpio_reg_int_sens_0}, 529 [GPIO_1_8V_E_INT_SENS_1] = {1, gpio_reg_int_sens_1}, 530 [GPIO_1_8V_E_INT_SENS_2] = {1, gpio_reg_int_sens_2}, 531 [GPIO_1_8V_E_INT_STATUS] = {1, gpio_reg_int_status}, 532 [GPIO_1_8V_E_RESET_TOLERANT] = {1, gpio_reg_reset_tolerant}, 533 [GPIO_1_8V_E_DEBOUNCE_1] = {1, gpio_reg_debounce_1}, 534 [GPIO_1_8V_E_DEBOUNCE_2] = {1, gpio_reg_debounce_2}, 535 [GPIO_1_8V_E_COMMAND_SRC_0] = {1, gpio_reg_cmd_source_0}, 536 [GPIO_1_8V_E_COMMAND_SRC_1] = {1, gpio_reg_cmd_source_1}, 537 [GPIO_1_8V_E_DATA_READ] = {1, gpio_reg_data_read}, 538 [GPIO_1_8V_E_INPUT_MASK] = {1, gpio_reg_input_mask}, 539 }; 540 541 static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size) 542 { 543 AspeedGPIOState *s = ASPEED_GPIO(opaque); 544 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); 545 uint64_t idx = -1; 546 const AspeedGPIOReg *reg; 547 GPIOSets *set; 548 549 idx = offset >> 2; 550 if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) { 551 idx -= GPIO_DEBOUNCE_TIME_1; 552 return (uint64_t) s->debounce_regs[idx]; 553 } 554 555 reg = &agc->reg_table[idx]; 556 if (reg->set_idx >= agc->nr_gpio_sets) { 557 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%" 558 HWADDR_PRIx"\n", __func__, offset); 559 return 0; 560 } 561 562 set = &s->sets[reg->set_idx]; 563 switch (reg->type) { 564 case gpio_reg_data_value: 565 return set->data_value; 566 case gpio_reg_direction: 567 return set->direction; 568 case gpio_reg_int_enable: 569 return set->int_enable; 570 case gpio_reg_int_sens_0: 571 return set->int_sens_0; 572 case gpio_reg_int_sens_1: 573 return set->int_sens_1; 574 case gpio_reg_int_sens_2: 575 return set->int_sens_2; 576 case gpio_reg_int_status: 577 return set->int_status; 578 case gpio_reg_reset_tolerant: 579 return set->reset_tol; 580 case gpio_reg_debounce_1: 581 return set->debounce_1; 582 case gpio_reg_debounce_2: 583 return set->debounce_2; 584 case gpio_reg_cmd_source_0: 585 return set->cmd_source_0; 586 case gpio_reg_cmd_source_1: 587 return set->cmd_source_1; 588 case gpio_reg_data_read: 589 return set->data_read; 590 case gpio_reg_input_mask: 591 return set->input_mask; 592 default: 593 qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%" 594 HWADDR_PRIx"\n", __func__, offset); 595 return 0; 596 }; 597 } 598 599 static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data, 600 uint32_t size) 601 { 602 AspeedGPIOState *s = ASPEED_GPIO(opaque); 603 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); 604 const GPIOSetProperties *props; 605 uint64_t idx = -1; 606 const AspeedGPIOReg *reg; 607 GPIOSets *set; 608 uint32_t cleared; 609 610 idx = offset >> 2; 611 if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) { 612 idx -= GPIO_DEBOUNCE_TIME_1; 613 s->debounce_regs[idx] = (uint32_t) data; 614 return; 615 } 616 617 reg = &agc->reg_table[idx]; 618 if (reg->set_idx >= agc->nr_gpio_sets) { 619 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%" 620 HWADDR_PRIx"\n", __func__, offset); 621 return; 622 } 623 624 set = &s->sets[reg->set_idx]; 625 props = &agc->props[reg->set_idx]; 626 627 switch (reg->type) { 628 case gpio_reg_data_value: 629 data &= props->output; 630 data = update_value_control_source(set, set->data_value, data); 631 set->data_read = data; 632 aspeed_gpio_update(s, set, data); 633 return; 634 case gpio_reg_direction: 635 /* 636 * where data is the value attempted to be written to the pin: 637 * pin type | input mask | output mask | expected value 638 * ------------------------------------------------------------ 639 * bidirectional | 1 | 1 | data 640 * input only | 1 | 0 | 0 641 * output only | 0 | 1 | 1 642 * no pin / gap | 0 | 0 | 0 643 * 644 * which is captured by: 645 * data = ( data | ~input) & output; 646 */ 647 data = (data | ~props->input) & props->output; 648 set->direction = update_value_control_source(set, set->direction, data); 649 break; 650 case gpio_reg_int_enable: 651 set->int_enable = update_value_control_source(set, set->int_enable, 652 data); 653 break; 654 case gpio_reg_int_sens_0: 655 set->int_sens_0 = update_value_control_source(set, set->int_sens_0, 656 data); 657 break; 658 case gpio_reg_int_sens_1: 659 set->int_sens_1 = update_value_control_source(set, set->int_sens_1, 660 data); 661 break; 662 case gpio_reg_int_sens_2: 663 set->int_sens_2 = update_value_control_source(set, set->int_sens_2, 664 data); 665 break; 666 case gpio_reg_int_status: 667 cleared = ctpop32(data & set->int_status); 668 if (s->pending && cleared) { 669 assert(s->pending >= cleared); 670 s->pending -= cleared; 671 } 672 set->int_status &= ~data; 673 break; 674 case gpio_reg_reset_tolerant: 675 set->reset_tol = update_value_control_source(set, set->reset_tol, 676 data); 677 return; 678 case gpio_reg_debounce_1: 679 set->debounce_1 = update_value_control_source(set, set->debounce_1, 680 data); 681 return; 682 case gpio_reg_debounce_2: 683 set->debounce_2 = update_value_control_source(set, set->debounce_2, 684 data); 685 return; 686 case gpio_reg_cmd_source_0: 687 set->cmd_source_0 = data & ASPEED_CMD_SRC_MASK; 688 return; 689 case gpio_reg_cmd_source_1: 690 set->cmd_source_1 = data & ASPEED_CMD_SRC_MASK; 691 return; 692 case gpio_reg_data_read: 693 /* Read only register */ 694 return; 695 case gpio_reg_input_mask: 696 /* 697 * feeds into interrupt generation 698 * 0: read from data value reg will be updated 699 * 1: read from data value reg will not be updated 700 */ 701 set->input_mask = data & props->input; 702 break; 703 default: 704 qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%" 705 HWADDR_PRIx"\n", __func__, offset); 706 return; 707 } 708 aspeed_gpio_update(s, set, set->data_value); 709 return; 710 } 711 712 static int get_set_idx(AspeedGPIOState *s, const char *group, int *group_idx) 713 { 714 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); 715 int set_idx, g_idx; 716 717 for (set_idx = 0; set_idx < agc->nr_gpio_sets; set_idx++) { 718 const GPIOSetProperties *set_props = &agc->props[set_idx]; 719 for (g_idx = 0; g_idx < ASPEED_GROUPS_PER_SET; g_idx++) { 720 if (!strncmp(group, set_props->group_label[g_idx], strlen(group))) { 721 *group_idx = g_idx; 722 return set_idx; 723 } 724 } 725 } 726 return -1; 727 } 728 729 static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name, 730 void *opaque, Error **errp) 731 { 732 int pin = 0xfff; 733 bool level = true; 734 char group[4]; 735 AspeedGPIOState *s = ASPEED_GPIO(obj); 736 int set_idx, group_idx = 0; 737 738 if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) { 739 /* 1.8V gpio */ 740 if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) { 741 error_setg(errp, "%s: error reading %s", __func__, name); 742 return; 743 } 744 } 745 set_idx = get_set_idx(s, group, &group_idx); 746 if (set_idx == -1) { 747 error_setg(errp, "%s: invalid group %s", __func__, group); 748 return; 749 } 750 pin = pin + group_idx * GPIOS_PER_GROUP; 751 level = aspeed_gpio_get_pin_level(s, set_idx, pin); 752 visit_type_bool(v, name, &level, errp); 753 } 754 755 static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name, 756 void *opaque, Error **errp) 757 { 758 bool level; 759 int pin = 0xfff; 760 char group[4]; 761 AspeedGPIOState *s = ASPEED_GPIO(obj); 762 int set_idx, group_idx = 0; 763 764 if (!visit_type_bool(v, name, &level, errp)) { 765 return; 766 } 767 if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) { 768 /* 1.8V gpio */ 769 if (sscanf(name, "gpio%3[18A-E]%1d", group, &pin) != 2) { 770 error_setg(errp, "%s: error reading %s", __func__, name); 771 return; 772 } 773 } 774 set_idx = get_set_idx(s, group, &group_idx); 775 if (set_idx == -1) { 776 error_setg(errp, "%s: invalid group %s", __func__, group); 777 return; 778 } 779 pin = pin + group_idx * GPIOS_PER_GROUP; 780 aspeed_gpio_set_pin_level(s, set_idx, pin, level); 781 } 782 783 /****************** Setup functions ******************/ 784 static const GPIOSetProperties ast2400_set_props[] = { 785 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} }, 786 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} }, 787 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} }, 788 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} }, 789 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} }, 790 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} }, 791 [6] = {0x0000000f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} }, 792 }; 793 794 static const GPIOSetProperties ast2500_set_props[] = { 795 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} }, 796 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} }, 797 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} }, 798 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} }, 799 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} }, 800 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} }, 801 [6] = {0xffffff0f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} }, 802 [7] = {0x000000ff, 0x000000ff, {"AC"} }, 803 }; 804 805 static GPIOSetProperties ast2600_3_6v_set_props[] = { 806 [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} }, 807 [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} }, 808 [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} }, 809 [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} }, 810 [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} }, 811 [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} }, 812 [6] = {0xffff0000, 0x0fff0000, {"Y", "Z", "", ""} }, 813 }; 814 815 static GPIOSetProperties ast2600_1_8v_set_props[] = { 816 [0] = {0xffffffff, 0xffffffff, {"18A", "18B", "18C", "18D"} }, 817 [1] = {0x0000000f, 0x0000000f, {"18E"} }, 818 }; 819 820 static const MemoryRegionOps aspeed_gpio_ops = { 821 .read = aspeed_gpio_read, 822 .write = aspeed_gpio_write, 823 .endianness = DEVICE_LITTLE_ENDIAN, 824 .valid.min_access_size = 4, 825 .valid.max_access_size = 4, 826 }; 827 828 static void aspeed_gpio_reset(DeviceState *dev) 829 { 830 AspeedGPIOState *s = ASPEED_GPIO(dev); 831 832 /* TODO: respect the reset tolerance registers */ 833 memset(s->sets, 0, sizeof(s->sets)); 834 } 835 836 static void aspeed_gpio_realize(DeviceState *dev, Error **errp) 837 { 838 AspeedGPIOState *s = ASPEED_GPIO(dev); 839 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 840 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); 841 int pin; 842 843 /* Interrupt parent line */ 844 sysbus_init_irq(sbd, &s->irq); 845 846 /* Individual GPIOs */ 847 for (pin = 0; pin < agc->nr_gpio_pins; pin++) { 848 sysbus_init_irq(sbd, &s->gpios[pin]); 849 } 850 851 memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s, 852 TYPE_ASPEED_GPIO, GPIO_MAX_MEM_SIZE); 853 854 sysbus_init_mmio(sbd, &s->iomem); 855 } 856 857 static void aspeed_gpio_init(Object *obj) 858 { 859 AspeedGPIOState *s = ASPEED_GPIO(obj); 860 AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); 861 int pin; 862 863 for (pin = 0; pin < agc->nr_gpio_pins; pin++) { 864 char *name; 865 int set_idx = pin / GPIOS_PER_SET; 866 int pin_idx = aspeed_adjust_pin(s, pin) - (set_idx * GPIOS_PER_SET); 867 int group_idx = pin_idx >> GPIO_GROUP_SHIFT; 868 const GPIOSetProperties *props = &agc->props[set_idx]; 869 870 name = g_strdup_printf("gpio%s%d", props->group_label[group_idx], 871 pin_idx % GPIOS_PER_GROUP); 872 object_property_add(obj, name, "bool", aspeed_gpio_get_pin, 873 aspeed_gpio_set_pin, NULL, NULL); 874 g_free(name); 875 } 876 } 877 878 static const VMStateDescription vmstate_gpio_regs = { 879 .name = TYPE_ASPEED_GPIO"/regs", 880 .version_id = 1, 881 .minimum_version_id = 1, 882 .fields = (VMStateField[]) { 883 VMSTATE_UINT32(data_value, GPIOSets), 884 VMSTATE_UINT32(data_read, GPIOSets), 885 VMSTATE_UINT32(direction, GPIOSets), 886 VMSTATE_UINT32(int_enable, GPIOSets), 887 VMSTATE_UINT32(int_sens_0, GPIOSets), 888 VMSTATE_UINT32(int_sens_1, GPIOSets), 889 VMSTATE_UINT32(int_sens_2, GPIOSets), 890 VMSTATE_UINT32(int_status, GPIOSets), 891 VMSTATE_UINT32(reset_tol, GPIOSets), 892 VMSTATE_UINT32(cmd_source_0, GPIOSets), 893 VMSTATE_UINT32(cmd_source_1, GPIOSets), 894 VMSTATE_UINT32(debounce_1, GPIOSets), 895 VMSTATE_UINT32(debounce_2, GPIOSets), 896 VMSTATE_UINT32(input_mask, GPIOSets), 897 VMSTATE_END_OF_LIST(), 898 } 899 }; 900 901 static const VMStateDescription vmstate_aspeed_gpio = { 902 .name = TYPE_ASPEED_GPIO, 903 .version_id = 1, 904 .minimum_version_id = 1, 905 .fields = (VMStateField[]) { 906 VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS, 907 1, vmstate_gpio_regs, GPIOSets), 908 VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState, 909 ASPEED_GPIO_NR_DEBOUNCE_REGS), 910 VMSTATE_END_OF_LIST(), 911 } 912 }; 913 914 static void aspeed_gpio_class_init(ObjectClass *klass, void *data) 915 { 916 DeviceClass *dc = DEVICE_CLASS(klass); 917 918 dc->realize = aspeed_gpio_realize; 919 dc->reset = aspeed_gpio_reset; 920 dc->desc = "Aspeed GPIO Controller"; 921 dc->vmsd = &vmstate_aspeed_gpio; 922 } 923 924 static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data) 925 { 926 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); 927 928 agc->props = ast2400_set_props; 929 agc->nr_gpio_pins = 216; 930 agc->nr_gpio_sets = 7; 931 agc->gap = 196; 932 agc->reg_table = aspeed_3_6v_gpios; 933 } 934 935 static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data) 936 { 937 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); 938 939 agc->props = ast2500_set_props; 940 agc->nr_gpio_pins = 228; 941 agc->nr_gpio_sets = 8; 942 agc->gap = 220; 943 agc->reg_table = aspeed_3_6v_gpios; 944 } 945 946 static void aspeed_gpio_ast2600_3_6v_class_init(ObjectClass *klass, void *data) 947 { 948 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); 949 950 agc->props = ast2600_3_6v_set_props; 951 agc->nr_gpio_pins = 208; 952 agc->nr_gpio_sets = 7; 953 agc->reg_table = aspeed_3_6v_gpios; 954 } 955 956 static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data) 957 { 958 AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); 959 960 agc->props = ast2600_1_8v_set_props; 961 agc->nr_gpio_pins = 36; 962 agc->nr_gpio_sets = 2; 963 agc->reg_table = aspeed_1_8v_gpios; 964 } 965 966 static const TypeInfo aspeed_gpio_info = { 967 .name = TYPE_ASPEED_GPIO, 968 .parent = TYPE_SYS_BUS_DEVICE, 969 .instance_size = sizeof(AspeedGPIOState), 970 .class_size = sizeof(AspeedGPIOClass), 971 .class_init = aspeed_gpio_class_init, 972 .abstract = true, 973 }; 974 975 static const TypeInfo aspeed_gpio_ast2400_info = { 976 .name = TYPE_ASPEED_GPIO "-ast2400", 977 .parent = TYPE_ASPEED_GPIO, 978 .class_init = aspeed_gpio_ast2400_class_init, 979 .instance_init = aspeed_gpio_init, 980 }; 981 982 static const TypeInfo aspeed_gpio_ast2500_info = { 983 .name = TYPE_ASPEED_GPIO "-ast2500", 984 .parent = TYPE_ASPEED_GPIO, 985 .class_init = aspeed_gpio_2500_class_init, 986 .instance_init = aspeed_gpio_init, 987 }; 988 989 static const TypeInfo aspeed_gpio_ast2600_3_6v_info = { 990 .name = TYPE_ASPEED_GPIO "-ast2600", 991 .parent = TYPE_ASPEED_GPIO, 992 .class_init = aspeed_gpio_ast2600_3_6v_class_init, 993 .instance_init = aspeed_gpio_init, 994 }; 995 996 static const TypeInfo aspeed_gpio_ast2600_1_8v_info = { 997 .name = TYPE_ASPEED_GPIO "-ast2600-1_8v", 998 .parent = TYPE_ASPEED_GPIO, 999 .class_init = aspeed_gpio_ast2600_1_8v_class_init, 1000 .instance_init = aspeed_gpio_init, 1001 }; 1002 1003 static void aspeed_gpio_register_types(void) 1004 { 1005 type_register_static(&aspeed_gpio_info); 1006 type_register_static(&aspeed_gpio_ast2400_info); 1007 type_register_static(&aspeed_gpio_ast2500_info); 1008 type_register_static(&aspeed_gpio_ast2600_3_6v_info); 1009 type_register_static(&aspeed_gpio_ast2600_1_8v_info); 1010 } 1011 1012 type_init(aspeed_gpio_register_types); 1013