/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef _SOC_INTELBLOCKS_GPIO_H_ #define _SOC_INTELBLOCKS_GPIO_H_ #include #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 /* * 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 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); #endif #endif /* _SOC_INTELBLOCKS_GPIO_H_ */