| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| |
| #ifndef _SOC_INTELBLOCKS_GPIO_H_ |
| #define _SOC_INTELBLOCKS_GPIO_H_ |
| |
| #include <soc/gpio.h> |
| #include "gpio_defs.h" |
| |
| /* GPIO community IOSF sideband clock gating */ |
| #define MISCCFG_GPSIDEDPCGEN (1 << 5) |
| /* GPIO community RCOMP clock gating */ |
| #define MISCCFG_GPRCOMPCDLCGEN (1 << 4) |
| /* GPIO community RTC clock gating */ |
| #define MISCCFG_GPRTCDLCGEN (1 << 3) |
| /* GFX controller clock gating */ |
| #define MISCCFG_GSXSLCGEN (1 << 2) |
| /* GPIO community partition clock gating */ |
| #define MISCCFG_GPDPCGEN (1 << 1) |
| /* GPIO community local clock gating */ |
| #define MISCCFG_GPDLCGEN (1 << 0) |
| /* Enable GPIO community power management configuration */ |
| #define MISCCFG_ENABLE_GPIO_PM_CONFIG (MISCCFG_GPSIDEDPCGEN | \ |
| MISCCFG_GPRCOMPCDLCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN \ |
| | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN) |
| |
| #ifndef __ACPI__ |
| #include <types.h> |
| #include <device/device.h> |
| |
| /* |
| * GPIO numbers may not be contiguous and instead will have a different |
| * starting pin number for each pad group. |
| */ |
| #define INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ |
| group_pad_base) \ |
| { \ |
| .first_pad = (start_of_group) - (first_of_community), \ |
| .size = (end_of_group) - (start_of_group) + 1, \ |
| .acpi_pad_base = (group_pad_base), \ |
| } |
| |
| /* |
| * A pad base of -1 indicates that this group uses contiguous numbering |
| * and a pad base should not be used for this group. |
| */ |
| #define PAD_BASE_NONE -1 |
| |
| /* The common/default group numbering is contiguous */ |
| #define INTEL_GPP(first_of_community, start_of_group, end_of_group) \ |
| INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ |
| PAD_BASE_NONE) |
| |
| /* |
| * Following should be defined in soc/gpio.h |
| * GPIO_MISCCFG - offset to GPIO MISCCFG Register |
| * |
| * GPIO_NUM_PAD_CFG_REGS - number of PAD config registers in the SOC |
| * For SOCs that have DW0 and DW1, it should be 2 |
| * NUM_GPI_STATUS_REGS - total number of GPI status registers across all |
| * GPIO communities in the SOC |
| * |
| * The register offsets specific to the soc communities should be provided in |
| * struct pad_community table returned from soc_gpio_get_community |
| */ |
| |
| typedef uint32_t gpio_t; |
| |
| struct pad_config { |
| int pad;/* offset of pad within community */ |
| uint32_t pad_config[GPIO_NUM_PAD_CFG_REGS];/* |
| Pad config data corresponding to DW0, DW1,.... */ |
| }; |
| |
| /* |
| * Structure provides the logical to actual value for PADRSTCFG in DW0. Note |
| * that the values are expected to be within the field placement of the register |
| * itself. i.e. if the reset field is at 31:30 then the values within logical |
| * and chipset should occupy 31:30. |
| */ |
| struct reset_mapping { |
| uint32_t logical; |
| uint32_t chipset; |
| }; |
| |
| /* Structure describes the groups within each community */ |
| struct pad_group { |
| int first_pad; /* offset of first pad of the group relative |
| to the community */ |
| unsigned int size; /* Size of the group */ |
| /* |
| * This is the starting pin number for the pads in this group when |
| * they are used in ACPI. This is only needed if the pins are not |
| * contiguous across groups, most groups will have this set to |
| * PAD_BASE_NONE and use contiguous numbering for ACPI. |
| */ |
| int acpi_pad_base; |
| }; |
| |
| /* This structure will be used to describe a community or each group within a |
| * community when multiple groups exist inside a community |
| */ |
| struct pad_community { |
| const char *name; |
| const char *acpi_path; |
| size_t num_gpi_regs;/* number of gpi registers in community */ |
| size_t max_pads_per_group; /* number of pads in each group; |
| Number of pads bit mapped in each GPI status/en and Host Own Reg */ |
| gpio_t first_pad; /* first pad in community */ |
| gpio_t last_pad; /* last pad in community */ |
| uint16_t host_own_reg_0; /* offset to Host Ownership Reg 0 */ |
| uint16_t gpi_int_sts_reg_0; /* offset to GPI Int STS Reg 0 */ |
| uint16_t gpi_int_en_reg_0; /* offset to GPI Int Enable Reg 0 */ |
| uint16_t gpi_smi_sts_reg_0; /* offset to GPI SMI STS Reg 0 */ |
| uint16_t gpi_smi_en_reg_0; /* offset to GPI SMI EN Reg 0 */ |
| uint16_t gpi_nmi_sts_reg_0; /* offset to GPI NMI STS Reg 0 */ |
| uint16_t gpi_nmi_en_reg_0; /* offset to GPI NMI EN Reg 0 */ |
| uint16_t pad_cfg_base; /* offset to first PAD_GFG_DW0 Reg */ |
| uint8_t gpi_status_offset; /* specifies offset in struct |
| gpi_status */ |
| uint8_t port; /* PCR Port ID */ |
| const struct reset_mapping *reset_map; /* PADRSTCFG logical to |
| chipset mapping */ |
| size_t num_reset_vals; |
| const struct pad_group *groups; |
| size_t num_groups; |
| }; |
| |
| /* |
| * Provides storage for all GPI status registers from all communities |
| */ |
| struct gpi_status { |
| uint32_t grp[NUM_GPI_STATUS_REGS]; |
| }; |
| |
| /* |
| * Structure provides the pmc to gpio group mapping |
| */ |
| struct pmc_to_gpio_route { |
| int pmc; |
| int gpio; |
| }; |
| |
| /* |
| * Returns the first community in the list. This will help to iterate |
| * through the list. It also returns total number of gpio communities. |
| * The soc layer provides a table describing available gpio communities. |
| */ |
| const struct pad_community *soc_gpio_get_community(size_t *num_communities); |
| |
| /* |
| * Clear GPI SMI status and fill in the structure representing enabled |
| * and set status. |
| */ |
| void gpi_clear_get_smi_status(struct gpi_status *sts); |
| |
| /* Return 1 if gpio is set in the sts. Otherwise 0. */ |
| int gpi_status_get(const struct gpi_status *sts, gpio_t gpi); |
| |
| /* |
| * Configuration for raw pads. Some pads are designated as only special function |
| * pins, and don't have an associated GPIO number, so we need to expose the raw |
| * pad configuration functionality. |
| */ |
| void gpio_configure_pads(const struct pad_config *cfg, size_t num_pads); |
| |
| /* |
| * gpio_configure_pads_with_override accepts as input two GPIO tables: |
| * 1. Base config |
| * 2. Override config |
| * |
| * This function configures raw pads in base config and applies override in |
| * override config if any. Thus, for every GPIO_x in base config, this function |
| * looks up the GPIO in override config and if it is present there, then applies |
| * the configuration from override config. |
| */ |
| void gpio_configure_pads_with_override(const struct pad_config *base_cfg, |
| size_t base_num_pads, |
| const struct pad_config *override_cfg, |
| size_t override_num_pads); |
| |
| /* |
| * Calculate Address of DW0 register for given GPIO |
| */ |
| void *gpio_dwx_address(const gpio_t pad); |
| |
| /* |
| * Returns the pmc_gpe to gpio_gpe mapping table |
| * |
| */ |
| const struct pmc_to_gpio_route *soc_pmc_gpio_routes(size_t *num); |
| |
| /* |
| * Set the GPIO groups for the GPE blocks. The values from PMC register GPE_CFG |
| * are passed which is then mapped to proper groups for MISCCFG. This basically |
| * sets the MISCCFG register bits: |
| * dw0 = gpe0_route[11:8]. This is ACPI GPE0b. |
| * dw1 = gpe0_route[15:12]. This is ACPI GPE0c. |
| * dw2 = gpe0_route[19:16]. This is ACPI GPE0d. |
| */ |
| void gpio_route_gpe(uint8_t gpe0b, uint8_t gpe0c, uint8_t gpe0d); |
| |
| /* |
| * Function returns PCR port ID for this pad |
| */ |
| uint8_t gpio_get_pad_portid(const gpio_t pad); |
| |
| /* |
| * Function to patch GPIO settings for SoC specifically |
| * cfg = pad config contains pad number and reg value. |
| * dw_reg = pad config dword number. |
| * reg_val = the reg value need to be patched. |
| * Returns gpio setting patched for SoC specifically |
| */ |
| uint32_t soc_gpio_pad_config_fixup(const struct pad_config *cfg, |
| int dw_reg, uint32_t reg_val); |
| |
| /* |
| * Function to reset/clear the GPI Interrupt Enable & Status registers for |
| * all GPIO pad communities. |
| */ |
| void gpi_clear_int_cfg(void); |
| |
| /* The function performs GPIO Power Management programming. */ |
| void gpio_pm_configure(const uint8_t *misccfg_pm_values, size_t num); |
| |
| /* |
| * Set gpio ops of the device to gpio block ops. |
| * Shall be called by all SoCs that use intelblocks/gpio. |
| */ |
| void block_gpio_enable(struct device *dev); |
| |
| #endif |
| #endif /* _SOC_INTELBLOCKS_GPIO_H_ */ |