qemu/include/hw/gpio/aspeed_gpio.h
Jamin Lin 404e75343c hw/gpio/aspeed: Support different memory region ops
It set "aspeed_gpio_ops" struct which containing read and write callbacks
to be used when I/O is performed on the GPIO region.

Besides, in the previous design of ASPEED SOCs, one register is used for
setting one function for 32 GPIO pins.
ex: GPIO000 is used for setting data value for GPIO A, B, C and D in AST2600.
ex: GPIO004 is used for setting direction for GPIO A, B, C and D in AST2600.

However, the register set have a significant change in AST2700.
Each GPIO pin has their own control register. In other words, users are able to
set one GPIO pin’s direction, interrupt enable, input mask and so on
in one register. The aspeed_gpio_read/aspeed_gpio_write callback functions
are not compatible AST2700.

Introduce a new "const MemoryRegionOps *" attribute in AspeedGPIOClass and
use it in aspeed_gpio_realize function.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
2024-10-24 07:57:47 +02:00

113 lines
2.8 KiB
C

/*
* ASPEED GPIO Controller
*
* Copyright (C) 2017-2018 IBM Corp.
*
* This code is licensed under the GPL version 2 or later. See
* the COPYING file in the top-level directory.
*/
#ifndef ASPEED_GPIO_H
#define ASPEED_GPIO_H
#include "hw/sysbus.h"
#include "qom/object.h"
#define TYPE_ASPEED_GPIO "aspeed.gpio"
OBJECT_DECLARE_TYPE(AspeedGPIOState, AspeedGPIOClass, ASPEED_GPIO)
#define ASPEED_GPIO_MAX_NR_SETS 8
#define ASPEED_GPIOS_PER_SET 32
#define ASPEED_REGS_PER_BANK 14
#define ASPEED_GPIO_MAX_NR_REGS (ASPEED_REGS_PER_BANK * ASPEED_GPIO_MAX_NR_SETS)
#define ASPEED_GROUPS_PER_SET 4
#define ASPEED_GPIO_NR_DEBOUNCE_REGS 3
#define ASPEED_CHARS_PER_GROUP_LABEL 4
typedef struct GPIOSets GPIOSets;
typedef struct GPIOSetProperties {
uint32_t input;
uint32_t output;
char group_label[ASPEED_GROUPS_PER_SET][ASPEED_CHARS_PER_GROUP_LABEL];
} GPIOSetProperties;
enum GPIORegType {
gpio_not_a_reg,
gpio_reg_data_value,
gpio_reg_direction,
gpio_reg_int_enable,
gpio_reg_int_sens_0,
gpio_reg_int_sens_1,
gpio_reg_int_sens_2,
gpio_reg_int_status,
gpio_reg_reset_tolerant,
gpio_reg_debounce_1,
gpio_reg_debounce_2,
gpio_reg_cmd_source_0,
gpio_reg_cmd_source_1,
gpio_reg_data_read,
gpio_reg_input_mask,
};
/* GPIO index mode */
enum GPIORegIndexType {
gpio_reg_idx_data = 0,
gpio_reg_idx_direction,
gpio_reg_idx_interrupt,
gpio_reg_idx_debounce,
gpio_reg_idx_tolerance,
gpio_reg_idx_cmd_src,
gpio_reg_idx_input_mask,
gpio_reg_idx_reserved,
gpio_reg_idx_new_w_cmd_src,
gpio_reg_idx_new_r_cmd_src,
};
typedef struct AspeedGPIOReg {
uint16_t set_idx;
enum GPIORegType type;
} AspeedGPIOReg;
struct AspeedGPIOClass {
SysBusDevice parent_obj;
const GPIOSetProperties *props;
uint32_t nr_gpio_pins;
uint32_t nr_gpio_sets;
const AspeedGPIOReg *reg_table;
unsigned reg_table_count;
uint64_t mem_size;
const MemoryRegionOps *reg_ops;
};
struct AspeedGPIOState {
/* <private> */
SysBusDevice parent;
/*< public >*/
MemoryRegion iomem;
int pending;
qemu_irq irq;
qemu_irq gpios[ASPEED_GPIO_MAX_NR_SETS][ASPEED_GPIOS_PER_SET];
/* Parallel GPIO Registers */
uint32_t debounce_regs[ASPEED_GPIO_NR_DEBOUNCE_REGS];
struct GPIOSets {
uint32_t data_value; /* Reflects pin values */
uint32_t data_read; /* Contains last value written to data value */
uint32_t direction;
uint32_t int_enable;
uint32_t int_sens_0;
uint32_t int_sens_1;
uint32_t int_sens_2;
uint32_t int_status;
uint32_t reset_tol;
uint32_t cmd_source_0;
uint32_t cmd_source_1;
uint32_t debounce_1;
uint32_t debounce_2;
uint32_t input_mask;
} sets[ASPEED_GPIO_MAX_NR_SETS];
};
#endif /* ASPEED_GPIO_H */