Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* |
| 3 | * Copyright (C) 2017 Intel Corporation. |
| 4 | * Copyright 2019 Google LLC |
| 5 | * |
| 6 | * Modified from coreboot gpio.h |
| 7 | */ |
| 8 | |
| 9 | #ifndef __ASM_INTEL_PINCTRL_H |
| 10 | #define __ASM_INTEL_PINCTRL_H |
| 11 | |
| 12 | #include <dm/pinctrl.h> |
Simon Glass | 4dcacfc | 2020-05-10 11:40:13 -0600 | [diff] [blame] | 13 | #include <linux/bitops.h> |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 14 | |
| 15 | /** |
| 16 | * struct pad_config - config for a pad |
| 17 | * @pad: offset of pad within community |
| 18 | * @pad_config: Pad config data corresponding to DW0, DW1, etc. |
| 19 | */ |
| 20 | struct pad_config { |
| 21 | int pad; |
| 22 | u32 pad_config[4]; |
| 23 | }; |
| 24 | |
| 25 | #include <asm/arch/gpio.h> |
| 26 | |
| 27 | /* GPIO community IOSF sideband clock gating */ |
| 28 | #define MISCCFG_GPSIDEDPCGEN BIT(5) |
| 29 | /* GPIO community RCOMP clock gating */ |
| 30 | #define MISCCFG_GPRCOMPCDLCGEN BIT(4) |
| 31 | /* GPIO community RTC clock gating */ |
| 32 | #define MISCCFG_GPRTCDLCGEN BIT(3) |
| 33 | /* GFX controller clock gating */ |
| 34 | #define MISCCFG_GSXSLCGEN BIT(2) |
| 35 | /* GPIO community partition clock gating */ |
| 36 | #define MISCCFG_GPDPCGEN BIT(1) |
| 37 | /* GPIO community local clock gating */ |
| 38 | #define MISCCFG_GPDLCGEN BIT(0) |
| 39 | /* Enable GPIO community power management configuration */ |
| 40 | #define MISCCFG_ENABLE_GPIO_PM_CONFIG (MISCCFG_GPSIDEDPCGEN | \ |
| 41 | MISCCFG_GPRCOMPCDLCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN \ |
| 42 | | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN) |
| 43 | |
| 44 | /* |
| 45 | * GPIO numbers may not be contiguous and instead will have a different |
| 46 | * starting pin number for each pad group. |
| 47 | */ |
| 48 | #define INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ |
| 49 | group_pad_base) \ |
| 50 | { \ |
| 51 | .first_pad = (start_of_group) - (first_of_community), \ |
| 52 | .size = (end_of_group) - (start_of_group) + 1, \ |
| 53 | .acpi_pad_base = (group_pad_base), \ |
| 54 | } |
| 55 | |
| 56 | /* |
| 57 | * A pad base of -1 indicates that this group uses contiguous numbering |
| 58 | * and a pad base should not be used for this group. |
| 59 | */ |
| 60 | #define PAD_BASE_NONE -1 |
| 61 | |
| 62 | /* The common/default group numbering is contiguous */ |
| 63 | #define INTEL_GPP(first_of_community, start_of_group, end_of_group) \ |
| 64 | INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\ |
| 65 | PAD_BASE_NONE) |
| 66 | |
| 67 | /** |
| 68 | * struct reset_mapping - logical to actual value for PADRSTCFG in DW0 |
| 69 | * |
| 70 | * Note that the values are expected to be within the field placement of the |
| 71 | * register itself. i.e. if the reset field is at 31:30 then the values within |
| 72 | * logical and chipset should occupy 31:30. |
| 73 | */ |
| 74 | struct reset_mapping { |
| 75 | u32 logical; |
| 76 | u32 chipset; |
| 77 | }; |
| 78 | |
| 79 | /** |
| 80 | * struct pad_group - describes the groups within each community |
| 81 | * |
| 82 | * @first_pad: offset of first pad of the group relative to the community |
| 83 | * @size: size of the group |
| 84 | * @acpi_pad_base: starting pin number for the pads in this group when they are |
| 85 | * used in ACPI. This is only needed if the pins are not contiguous across |
| 86 | * groups. Most groups will have this set to PAD_BASE_NONE and use |
| 87 | * contiguous numbering for ACPI. |
| 88 | */ |
| 89 | struct pad_group { |
| 90 | int first_pad; |
| 91 | uint size; |
| 92 | int acpi_pad_base; |
| 93 | }; |
| 94 | |
| 95 | /** |
| 96 | * struct pad_community - community of pads |
| 97 | * |
| 98 | * This describes a community, or each group within a community when multiple |
| 99 | * groups exist inside a community |
| 100 | * |
| 101 | * @name: Community name |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 102 | * @num_gpi_regs: number of gpi registers in community |
| 103 | * @max_pads_per_group: number of pads in each group; number of pads bit-mapped |
| 104 | * in each GPI status/en and Host Own Reg |
| 105 | * @first_pad: first pad in community |
| 106 | * @last_pad: last pad in community |
| 107 | * @host_own_reg_0: offset to Host Ownership Reg 0 |
| 108 | * @gpi_int_sts_reg_0: offset to GPI Int STS Reg 0 |
| 109 | * @gpi_int_en_reg_0: offset to GPI Int Enable Reg 0 |
| 110 | * @gpi_smi_sts_reg_0: offset to GPI SMI STS Reg 0 |
| 111 | * @gpi_smi_en_reg_0: offset to GPI SMI EN Reg 0 |
| 112 | * @pad_cfg_base: offset to first PAD_GFG_DW0 Reg |
| 113 | * @gpi_status_offset: specifies offset in struct gpi_status |
| 114 | * @port: PCR Port ID |
| 115 | * @reset_map: PADRSTCFG logical to chipset mapping |
| 116 | * @num_reset_vals: number of values in @reset_map |
| 117 | * @groups; list of groups for this community |
| 118 | * @num_groups: number of groups |
| 119 | */ |
| 120 | struct pad_community { |
| 121 | const char *name; |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 122 | size_t num_gpi_regs; |
| 123 | size_t max_pads_per_group; |
| 124 | uint first_pad; |
| 125 | uint last_pad; |
| 126 | u16 host_own_reg_0; |
| 127 | u16 gpi_int_sts_reg_0; |
| 128 | u16 gpi_int_en_reg_0; |
| 129 | u16 gpi_smi_sts_reg_0; |
| 130 | u16 gpi_smi_en_reg_0; |
| 131 | u16 pad_cfg_base; |
| 132 | u8 gpi_status_offset; |
| 133 | u8 port; |
| 134 | const struct reset_mapping *reset_map; |
| 135 | size_t num_reset_vals; |
| 136 | const struct pad_group *groups; |
| 137 | size_t num_groups; |
| 138 | }; |
| 139 | |
| 140 | /** |
| 141 | * struct intel_pinctrl_priv - private data for each pinctrl device |
| 142 | * |
| 143 | * @comm: Pad community for this device |
| 144 | * @num_cfgs: Number of configuration words for each pad |
| 145 | * @itss: ITSS device (for interrupt handling) |
| 146 | * @itss_pol_cfg: Use to program Interrupt Polarity Control (IPCx) register |
| 147 | * Each bit represents IRQx Active High Polarity Disable configuration: |
| 148 | * when set to 1, the interrupt polarity associated with IRQx is inverted |
| 149 | * to appear as Active Low to IOAPIC and vice versa |
| 150 | */ |
| 151 | struct intel_pinctrl_priv { |
| 152 | const struct pad_community *comm; |
| 153 | int num_cfgs; |
| 154 | struct udevice *itss; |
| 155 | bool itss_pol_cfg; |
| 156 | }; |
| 157 | |
| 158 | /* Exported common operations for the pinctrl driver */ |
| 159 | extern const struct pinctrl_ops intel_pinctrl_ops; |
| 160 | |
| 161 | /* Exported common probe function for the pinctrl driver */ |
| 162 | int intel_pinctrl_probe(struct udevice *dev); |
| 163 | |
| 164 | /** |
Simon Glass | aad29ae | 2020-12-03 16:55:21 -0700 | [diff] [blame] | 165 | * intel_pinctrl_of_to_plat() - Handle common plat setup |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 166 | * |
| 167 | * @dev: Pinctrl device |
| 168 | * @comm: Pad community for this device |
| 169 | * @num_cfgs: Number of configuration words for each pad |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 170 | * Return: 0 if OK, -EDOM if @comm is NULL, other -ve value on other error |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 171 | */ |
Simon Glass | aad29ae | 2020-12-03 16:55:21 -0700 | [diff] [blame] | 172 | int intel_pinctrl_of_to_plat(struct udevice *dev, |
| 173 | const struct pad_community *comm, int num_cfgs); |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 174 | |
| 175 | /** |
| 176 | * pinctrl_route_gpe() - set GPIO groups for the general-purpose-event blocks |
| 177 | * |
| 178 | * The values from PMC register GPE_CFG are passed which is then mapped to |
| 179 | * proper groups for MISCCFG. This basically sets the MISCCFG register bits: |
| 180 | * dw0 = gpe0_route[11:8]. This is ACPI GPE0b. |
| 181 | * dw1 = gpe0_route[15:12]. This is ACPI GPE0c. |
| 182 | * dw2 = gpe0_route[19:16]. This is ACPI GPE0d. |
| 183 | * |
| 184 | * @dev: ITSS device |
| 185 | * @gpe0b: Value for GPE0B |
| 186 | * @gpe0c: Value for GPE0C |
| 187 | * @gpe0d: Value for GPE0D |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 188 | * Return: 0 if OK, -ve on error |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 189 | */ |
| 190 | int pinctrl_route_gpe(struct udevice *dev, uint gpe0b, uint gpe0c, uint gpe0d); |
| 191 | |
| 192 | /** |
| 193 | * pinctrl_config_pads() - Configure a list of pads |
| 194 | * |
| 195 | * Configures multiple pads using the provided data from the device tree. |
| 196 | * |
| 197 | * @dev: pinctrl device (any will do) |
| 198 | * @pads: Pad data, consisting of a pad number followed by num_cfgs entries |
| 199 | * containing the data for that pad (num_cfgs is set by the pinctrl device) |
| 200 | * @pads_count: Number of pads to configure |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 201 | * Return: 0 if OK, -ve on error |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 202 | */ |
| 203 | int pinctrl_config_pads(struct udevice *dev, u32 *pads, int pads_count); |
| 204 | |
| 205 | /** |
| 206 | * pinctrl_gpi_clear_int_cfg() - Set up the interrupts for use |
| 207 | * |
| 208 | * This enables the interrupt inputs and clears the status register bits |
| 209 | * |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 210 | * Return: 0 if OK, -ve on error |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 211 | */ |
| 212 | int pinctrl_gpi_clear_int_cfg(void); |
| 213 | |
| 214 | /** |
| 215 | * pinctrl_config_pads_for_node() - Configure pads |
| 216 | * |
| 217 | * Set up the pads using the data in a given node |
| 218 | * |
| 219 | * @dev: pinctrl device (any will do) |
| 220 | * @node: Node containing the 'pads' property with the data in it |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 221 | * Return: 0 if OK, -ve on error |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 222 | */ |
| 223 | int pinctrl_config_pads_for_node(struct udevice *dev, ofnode node); |
| 224 | |
| 225 | /** |
| 226 | * pinctrl_read_pads() - Read pad data from a node |
| 227 | * |
| 228 | * @dev: pinctrl device (any will do, it is just used to get config) |
| 229 | * @node: Node to read pad data from |
| 230 | * @prop: Property name to use (e.g. "pads") |
| 231 | * @padsp: Returns a pointer to an allocated array of pad data, in the format: |
| 232 | * <pad> |
| 233 | * <pad_config0> |
| 234 | * <pad_config1> |
| 235 | * ... |
| 236 | * |
| 237 | * The number of pad config values is set by the pinctrl controller. |
| 238 | * The caller must free this array. |
| 239 | * @pad_countp: Returns the number of pads read |
| 240 | * @ereturn 0 if OK, -ve on error |
| 241 | */ |
| 242 | int pinctrl_read_pads(struct udevice *dev, ofnode node, const char *prop, |
| 243 | u32 **padsp, int *pad_countp); |
| 244 | |
| 245 | /** |
| 246 | * pinctrl_count_pads() - Count the number of pads in a pad array |
| 247 | * |
| 248 | * This used used with of-platdata where the array may be smaller than its |
| 249 | * maximum size. This function searches for the last pad in the array by finding |
| 250 | * the first 'zero' record |
| 251 | * |
| 252 | * This works out the number of records in the array. Each record has one word |
| 253 | * for the pad and num_cfgs words for the config. |
| 254 | * |
| 255 | * @dev: pinctrl device (any will do) |
| 256 | * @pads: Array of pad data |
| 257 | * @size: Size of pad data in bytes |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 258 | * Return: number of pads represented by the data |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 259 | */ |
| 260 | int pinctrl_count_pads(struct udevice *dev, u32 *pads, int size); |
| 261 | |
| 262 | /** |
Simon Glass | 25f16c1 | 2020-07-07 21:32:19 -0600 | [diff] [blame] | 263 | * intel_pinctrl_get_config_reg_offset() - Get offset of pin config registers |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 264 | * |
Simon Glass | 25f16c1 | 2020-07-07 21:32:19 -0600 | [diff] [blame] | 265 | * This works out the register offset of a pin within the p2sb region. |
| 266 | * |
| 267 | * @dev: Pinctrl device |
| 268 | * @offset: GPIO offset within this device |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 269 | * Return: register offset of first register within the GPIO p2sb region |
Simon Glass | 25f16c1 | 2020-07-07 21:32:19 -0600 | [diff] [blame] | 270 | */ |
| 271 | u32 intel_pinctrl_get_config_reg_offset(struct udevice *dev, uint offset); |
| 272 | |
| 273 | /** |
| 274 | * intel_pinctrl_get_config_reg_addr() - Get address of pin config registers |
| 275 | * |
| 276 | * This works out the absolute address of the registers for a pin |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 277 | * @dev: Pinctrl device |
| 278 | * @offset: GPIO offset within this device |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 279 | * Return: register address of first register within the GPIO p2sb region |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 280 | */ |
| 281 | u32 intel_pinctrl_get_config_reg_addr(struct udevice *dev, uint offset); |
| 282 | |
| 283 | /** |
| 284 | * intel_pinctrl_get_config_reg() - Get the value of a GPIO register |
| 285 | * |
| 286 | * @dev: Pinctrl device |
| 287 | * @offset: GPIO offset within this device |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 288 | * Return: register value within the GPIO p2sb region |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 289 | */ |
| 290 | u32 intel_pinctrl_get_config_reg(struct udevice *dev, uint offset); |
| 291 | |
| 292 | /** |
| 293 | * intel_pinctrl_get_pad() - Get pad information for a pad |
| 294 | * |
| 295 | * This is used by the GPIO controller to find the pinctrl used by a pad. |
| 296 | * |
| 297 | * @pad: Pad to check |
| 298 | * @devp: Returns pinctrl device containing that pad |
| 299 | * @offsetp: Returns offset of pad within that pinctrl device |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 300 | * Return: 0 if OK, -ENOTBLK if pad number is invalid |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 301 | */ |
| 302 | int intel_pinctrl_get_pad(uint pad, struct udevice **devp, uint *offsetp); |
| 303 | |
| 304 | /** |
| 305 | * intel_pinctrl_get_acpi_pin() - Get the ACPI pin for a pinctrl pin |
| 306 | * |
| 307 | * Maps a pinctrl pin (in terms of its offset within the pins controlled by that |
| 308 | * pinctrl) to an ACPI GPIO pin-table entry. |
| 309 | * |
| 310 | * @dev: Pinctrl device to check |
| 311 | * @offset: Offset of pin within that device (0 = first) |
Heinrich Schuchardt | 47b4c02 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 312 | * Return: associated ACPI GPIO pin-table entry, or standard pin number if the |
Simon Glass | 837a66a | 2019-12-06 21:42:53 -0700 | [diff] [blame] | 313 | * ACPI pad base is not set |
| 314 | */ |
| 315 | int intel_pinctrl_get_acpi_pin(struct udevice *dev, uint offset); |
| 316 | |
| 317 | #endif |