Commit 74749f1e84dfec4ba521d741db461803d465948c

Authored by Simon Glass
Committed by Bin Meng
1 parent b84d4d0932

x86: Add a generic Intel pinctrl driver

Recent Intel SoCs share a pinctrl mechanism with many common elements. Add
an implementation of this core functionality, allowing SoC-specific
drivers to avoid adding common code.

As well as a pinctrl driver this provides a GPIO driver based on the same
code.

Once other SoCs use this driver we may consider moving more properties to
the device tree (e.g. the community info and pad definitions).

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Showing 8 changed files with 1385 additions and 0 deletions Side-by-side Diff

arch/x86/include/asm/intel_pinctrl.h
  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>
  13 +
  14 +/**
  15 + * struct pad_config - config for a pad
  16 + * @pad: offset of pad within community
  17 + * @pad_config: Pad config data corresponding to DW0, DW1, etc.
  18 + */
  19 +struct pad_config {
  20 + int pad;
  21 + u32 pad_config[4];
  22 +};
  23 +
  24 +#include <asm/arch/gpio.h>
  25 +
  26 +/* GPIO community IOSF sideband clock gating */
  27 +#define MISCCFG_GPSIDEDPCGEN BIT(5)
  28 +/* GPIO community RCOMP clock gating */
  29 +#define MISCCFG_GPRCOMPCDLCGEN BIT(4)
  30 +/* GPIO community RTC clock gating */
  31 +#define MISCCFG_GPRTCDLCGEN BIT(3)
  32 +/* GFX controller clock gating */
  33 +#define MISCCFG_GSXSLCGEN BIT(2)
  34 +/* GPIO community partition clock gating */
  35 +#define MISCCFG_GPDPCGEN BIT(1)
  36 +/* GPIO community local clock gating */
  37 +#define MISCCFG_GPDLCGEN BIT(0)
  38 +/* Enable GPIO community power management configuration */
  39 +#define MISCCFG_ENABLE_GPIO_PM_CONFIG (MISCCFG_GPSIDEDPCGEN | \
  40 + MISCCFG_GPRCOMPCDLCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN \
  41 + | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN)
  42 +
  43 +/*
  44 + * GPIO numbers may not be contiguous and instead will have a different
  45 + * starting pin number for each pad group.
  46 + */
  47 +#define INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\
  48 + group_pad_base) \
  49 + { \
  50 + .first_pad = (start_of_group) - (first_of_community), \
  51 + .size = (end_of_group) - (start_of_group) + 1, \
  52 + .acpi_pad_base = (group_pad_base), \
  53 + }
  54 +
  55 +/*
  56 + * A pad base of -1 indicates that this group uses contiguous numbering
  57 + * and a pad base should not be used for this group.
  58 + */
  59 +#define PAD_BASE_NONE -1
  60 +
  61 +/* The common/default group numbering is contiguous */
  62 +#define INTEL_GPP(first_of_community, start_of_group, end_of_group) \
  63 + INTEL_GPP_BASE(first_of_community, start_of_group, end_of_group,\
  64 + PAD_BASE_NONE)
  65 +
  66 +/**
  67 + * struct reset_mapping - logical to actual value for PADRSTCFG in DW0
  68 + *
  69 + * Note that the values are expected to be within the field placement of the
  70 + * register itself. i.e. if the reset field is at 31:30 then the values within
  71 + * logical and chipset should occupy 31:30.
  72 + */
  73 +struct reset_mapping {
  74 + u32 logical;
  75 + u32 chipset;
  76 +};
  77 +
  78 +/**
  79 + * struct pad_group - describes the groups within each community
  80 + *
  81 + * @first_pad: offset of first pad of the group relative to the community
  82 + * @size: size of the group
  83 + * @acpi_pad_base: starting pin number for the pads in this group when they are
  84 + * used in ACPI. This is only needed if the pins are not contiguous across
  85 + * groups. Most groups will have this set to PAD_BASE_NONE and use
  86 + * contiguous numbering for ACPI.
  87 + */
  88 +struct pad_group {
  89 + int first_pad;
  90 + uint size;
  91 + int acpi_pad_base;
  92 +};
  93 +
  94 +/**
  95 + * struct pad_community - community of pads
  96 + *
  97 + * This describes a community, or each group within a community when multiple
  98 + * groups exist inside a community
  99 + *
  100 + * @name: Community name
  101 + * @acpi_path: ACPI path
  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;
  122 + const char *acpi_path;
  123 + size_t num_gpi_regs;
  124 + size_t max_pads_per_group;
  125 + uint first_pad;
  126 + uint last_pad;
  127 + u16 host_own_reg_0;
  128 + u16 gpi_int_sts_reg_0;
  129 + u16 gpi_int_en_reg_0;
  130 + u16 gpi_smi_sts_reg_0;
  131 + u16 gpi_smi_en_reg_0;
  132 + u16 pad_cfg_base;
  133 + u8 gpi_status_offset;
  134 + u8 port;
  135 + const struct reset_mapping *reset_map;
  136 + size_t num_reset_vals;
  137 + const struct pad_group *groups;
  138 + size_t num_groups;
  139 +};
  140 +
  141 +/**
  142 + * struct intel_pinctrl_priv - private data for each pinctrl device
  143 + *
  144 + * @comm: Pad community for this device
  145 + * @num_cfgs: Number of configuration words for each pad
  146 + * @itss: ITSS device (for interrupt handling)
  147 + * @itss_pol_cfg: Use to program Interrupt Polarity Control (IPCx) register
  148 + * Each bit represents IRQx Active High Polarity Disable configuration:
  149 + * when set to 1, the interrupt polarity associated with IRQx is inverted
  150 + * to appear as Active Low to IOAPIC and vice versa
  151 + */
  152 +struct intel_pinctrl_priv {
  153 + const struct pad_community *comm;
  154 + int num_cfgs;
  155 + struct udevice *itss;
  156 + bool itss_pol_cfg;
  157 +};
  158 +
  159 +/* Exported common operations for the pinctrl driver */
  160 +extern const struct pinctrl_ops intel_pinctrl_ops;
  161 +
  162 +/* Exported common probe function for the pinctrl driver */
  163 +int intel_pinctrl_probe(struct udevice *dev);
  164 +
  165 +/**
  166 + * intel_pinctrl_ofdata_to_platdata() - Handle common platdata setup
  167 + *
  168 + * @dev: Pinctrl device
  169 + * @comm: Pad community for this device
  170 + * @num_cfgs: Number of configuration words for each pad
  171 + * @return 0 if OK, -EDOM if @comm is NULL, other -ve value on other error
  172 + */
  173 +int intel_pinctrl_ofdata_to_platdata(struct udevice *dev,
  174 + const struct pad_community *comm,
  175 + int num_cfgs);
  176 +
  177 +/**
  178 + * pinctrl_route_gpe() - set GPIO groups for the general-purpose-event blocks
  179 + *
  180 + * The values from PMC register GPE_CFG are passed which is then mapped to
  181 + * proper groups for MISCCFG. This basically sets the MISCCFG register bits:
  182 + * dw0 = gpe0_route[11:8]. This is ACPI GPE0b.
  183 + * dw1 = gpe0_route[15:12]. This is ACPI GPE0c.
  184 + * dw2 = gpe0_route[19:16]. This is ACPI GPE0d.
  185 + *
  186 + * @dev: ITSS device
  187 + * @gpe0b: Value for GPE0B
  188 + * @gpe0c: Value for GPE0C
  189 + * @gpe0d: Value for GPE0D
  190 + * @return 0 if OK, -ve on error
  191 + */
  192 +int pinctrl_route_gpe(struct udevice *dev, uint gpe0b, uint gpe0c, uint gpe0d);
  193 +
  194 +/**
  195 + * pinctrl_config_pads() - Configure a list of pads
  196 + *
  197 + * Configures multiple pads using the provided data from the device tree.
  198 + *
  199 + * @dev: pinctrl device (any will do)
  200 + * @pads: Pad data, consisting of a pad number followed by num_cfgs entries
  201 + * containing the data for that pad (num_cfgs is set by the pinctrl device)
  202 + * @pads_count: Number of pads to configure
  203 + * @return 0 if OK, -ve on error
  204 + */
  205 +int pinctrl_config_pads(struct udevice *dev, u32 *pads, int pads_count);
  206 +
  207 +/**
  208 + * pinctrl_gpi_clear_int_cfg() - Set up the interrupts for use
  209 + *
  210 + * This enables the interrupt inputs and clears the status register bits
  211 + *
  212 + * @return 0 if OK, -ve on error
  213 + */
  214 +int pinctrl_gpi_clear_int_cfg(void);
  215 +
  216 +/**
  217 + * pinctrl_config_pads_for_node() - Configure pads
  218 + *
  219 + * Set up the pads using the data in a given node
  220 + *
  221 + * @dev: pinctrl device (any will do)
  222 + * @node: Node containing the 'pads' property with the data in it
  223 + * @return 0 if OK, -ve on error
  224 + */
  225 +int pinctrl_config_pads_for_node(struct udevice *dev, ofnode node);
  226 +
  227 +/**
  228 + * pinctrl_read_pads() - Read pad data from a node
  229 + *
  230 + * @dev: pinctrl device (any will do, it is just used to get config)
  231 + * @node: Node to read pad data from
  232 + * @prop: Property name to use (e.g. "pads")
  233 + * @padsp: Returns a pointer to an allocated array of pad data, in the format:
  234 + * <pad>
  235 + * <pad_config0>
  236 + * <pad_config1>
  237 + * ...
  238 + *
  239 + * The number of pad config values is set by the pinctrl controller.
  240 + * The caller must free this array.
  241 + * @pad_countp: Returns the number of pads read
  242 + * @ereturn 0 if OK, -ve on error
  243 + */
  244 +int pinctrl_read_pads(struct udevice *dev, ofnode node, const char *prop,
  245 + u32 **padsp, int *pad_countp);
  246 +
  247 +/**
  248 + * pinctrl_count_pads() - Count the number of pads in a pad array
  249 + *
  250 + * This used used with of-platdata where the array may be smaller than its
  251 + * maximum size. This function searches for the last pad in the array by finding
  252 + * the first 'zero' record
  253 + *
  254 + * This works out the number of records in the array. Each record has one word
  255 + * for the pad and num_cfgs words for the config.
  256 + *
  257 + * @dev: pinctrl device (any will do)
  258 + * @pads: Array of pad data
  259 + * @size: Size of pad data in bytes
  260 + * @return number of pads represented by the data
  261 + */
  262 +int pinctrl_count_pads(struct udevice *dev, u32 *pads, int size);
  263 +
  264 +/**
  265 + * intel_pinctrl_get_config_reg_addr() - Get address of the pin config registers
  266 + *
  267 + * @dev: Pinctrl device
  268 + * @offset: GPIO offset within this device
  269 + * @return register offset within the GPIO p2sb region
  270 + */
  271 +u32 intel_pinctrl_get_config_reg_addr(struct udevice *dev, uint offset);
  272 +
  273 +/**
  274 + * intel_pinctrl_get_config_reg() - Get the value of a GPIO register
  275 + *
  276 + * @dev: Pinctrl device
  277 + * @offset: GPIO offset within this device
  278 + * @return register value within the GPIO p2sb region
  279 + */
  280 +u32 intel_pinctrl_get_config_reg(struct udevice *dev, uint offset);
  281 +
  282 +/**
  283 + * intel_pinctrl_get_pad() - Get pad information for a pad
  284 + *
  285 + * This is used by the GPIO controller to find the pinctrl used by a pad.
  286 + *
  287 + * @pad: Pad to check
  288 + * @devp: Returns pinctrl device containing that pad
  289 + * @offsetp: Returns offset of pad within that pinctrl device
  290 + */
  291 +int intel_pinctrl_get_pad(uint pad, struct udevice **devp, uint *offsetp);
  292 +
  293 +/**
  294 + * intel_pinctrl_get_acpi_pin() - Get the ACPI pin for a pinctrl pin
  295 + *
  296 + * Maps a pinctrl pin (in terms of its offset within the pins controlled by that
  297 + * pinctrl) to an ACPI GPIO pin-table entry.
  298 + *
  299 + * @dev: Pinctrl device to check
  300 + * @offset: Offset of pin within that device (0 = first)
  301 + * @return associated ACPI GPIO pin-table entry, or standard pin number if the
  302 + * ACPI pad base is not set
  303 + */
  304 +int intel_pinctrl_get_acpi_pin(struct udevice *dev, uint offset);
  305 +
  306 +#endif
arch/x86/include/asm/intel_pinctrl_defs.h
  1 +/* SPDX-License-Identifier: GPL-2.0 */
  2 +/*
  3 + * This file is part of the coreboot project.
  4 + *
  5 + * Copyright (C) 2015-2016 Intel Corp.
  6 + * Copyright 2019 Google LLC
  7 + *
  8 + * Modified from coreboot gpio_defs.h
  9 + */
  10 +
  11 +#ifndef _ASM_INTEL_PINCTRL_DEFS_H_
  12 +#define _ASM_INTEL_PINCTRL_DEFS_H_
  13 +
  14 +/* This file is included by device trees, so avoid BIT() macros */
  15 +
  16 +#define PAD_CFG0_TX_STATE_BIT 0
  17 +#define PAD_CFG0_TX_STATE (1 << PAD_CFG0_TX_STATE_BIT)
  18 +#define PAD_CFG0_RX_STATE_BIT 1
  19 +#define PAD_CFG0_RX_STATE (1 << PAD_CFG0_RX_STATE_BIT)
  20 +#define PAD_CFG0_TX_DISABLE (1 << 8)
  21 +#define PAD_CFG0_RX_DISABLE (1 << 9)
  22 +
  23 +#define PAD_CFG0_MODE_SHIFT 10
  24 +#define PAD_CFG0_MODE_MASK (7 << PAD_CFG0_MODE_SHIFT)
  25 +#define PAD_CFG0_MODE_GPIO (0 << PAD_CFG0_MODE_SHIFT)
  26 +#define PAD_CFG0_MODE_NF1 (1 << PAD_CFG0_MODE_SHIFT)
  27 +#define PAD_CFG0_MODE_NF2 (2 << PAD_CFG0_MODE_SHIFT)
  28 +#define PAD_CFG0_MODE_NF3 (3 << PAD_CFG0_MODE_SHIFT)
  29 +#define PAD_CFG0_MODE_NF4 (4 << PAD_CFG0_MODE_SHIFT)
  30 +#define PAD_CFG0_MODE_NF5 (5 << PAD_CFG0_MODE_SHIFT)
  31 +#define PAD_CFG0_MODE_NF6 (6 << PAD_CFG0_MODE_SHIFT)
  32 +
  33 +#define PAD_CFG0_ROUTE_MASK (0xf << 17)
  34 +#define PAD_CFG0_ROUTE_NMI (1 << 17)
  35 +#define PAD_CFG0_ROUTE_SMI (1 << 18)
  36 +#define PAD_CFG0_ROUTE_SCI (1 << 19)
  37 +#define PAD_CFG0_ROUTE_IOAPIC (1 << 20)
  38 +#define PAD_CFG0_RXTENCFG_MASK (3 << 21)
  39 +#define PAD_CFG0_RXINV_MASK (1 << 23)
  40 +#define PAD_CFG0_RX_POL_INVERT (1 << 23)
  41 +#define PAD_CFG0_RX_POL_NONE (0 << 23)
  42 +#define PAD_CFG0_PREGFRXSEL (1 << 24)
  43 +#define PAD_CFG0_TRIG_MASK (3 << 25)
  44 +#define PAD_CFG0_TRIG_LEVEL (0 << 25)
  45 +#define PAD_CFG0_TRIG_EDGE_SINGLE (1 << 25) /* controlled by RX_INVERT*/
  46 +#define PAD_CFG0_TRIG_OFF (2 << 25)
  47 +#define PAD_CFG0_TRIG_EDGE_BOTH (3 << 25)
  48 +#define PAD_CFG0_RXRAW1_MASK (1 << 28)
  49 +#define PAD_CFG0_RXPADSTSEL_MASK (1 << 29)
  50 +#define PAD_CFG0_RESET_MASK (3 << 30)
  51 +#define PAD_CFG0_LOGICAL_RESET_PWROK (0U << 30)
  52 +#define PAD_CFG0_LOGICAL_RESET_DEEP (1U << 30)
  53 +#define PAD_CFG0_LOGICAL_RESET_PLTRST (2U << 30)
  54 +#define PAD_CFG0_LOGICAL_RESET_RSMRST (3U << 30)
  55 +
  56 +/*
  57 + * Use the fourth bit in IntSel field to indicate gpio ownership. This field is
  58 + * RO and hence not used during gpio configuration.
  59 + */
  60 +#define PAD_CFG1_GPIO_DRIVER (0x1 << 4)
  61 +#define PAD_CFG1_IRQ_MASK (0xff << 0)
  62 +#define PAD_CFG1_IOSTERM_MASK (0x3 << 8)
  63 +#define PAD_CFG1_IOSTERM_SAME (0x0 << 8)
  64 +#define PAD_CFG1_IOSTERM_DISPUPD (0x1 << 8)
  65 +#define PAD_CFG1_IOSTERM_ENPD (0x2 << 8)
  66 +#define PAD_CFG1_IOSTERM_ENPU (0x3 << 8)
  67 +#define PAD_CFG1_PULL_MASK (0xf << 10)
  68 +#define PAD_CFG1_PULL_NONE (0x0 << 10)
  69 +#define PAD_CFG1_PULL_DN_5K (0x2 << 10)
  70 +#define PAD_CFG1_PULL_DN_20K (0x4 << 10)
  71 +#define PAD_CFG1_PULL_UP_1K (0x9 << 10)
  72 +#define PAD_CFG1_PULL_UP_5K (0xa << 10)
  73 +#define PAD_CFG1_PULL_UP_2K (0xb << 10)
  74 +#define PAD_CFG1_PULL_UP_20K (0xc << 10)
  75 +#define PAD_CFG1_PULL_UP_667 (0xd << 10)
  76 +#define PAD_CFG1_PULL_NATIVE (0xf << 10)
  77 +
  78 +/* Tx enabled driving last value driven, Rx enabled */
  79 +#define PAD_CFG1_IOSSTATE_TX_LAST_RXE (0x0 << 14)
  80 +/*
  81 + * Tx enabled driving 0, Rx disabled and Rx driving 0 back to its controller
  82 + * internally
  83 + */
  84 +#define PAD_CFG1_IOSSTATE_TX0_RX_DCR_X0 (0x1 << 14)
  85 +/*
  86 + * Tx enabled driving 0, Rx disabled and Rx driving 1 back to its controller
  87 + * internally
  88 + */
  89 +#define PAD_CFG1_IOSSTATE_TX0_RX_DCR_X1 (0x2 << 14)
  90 +/*
  91 + * Tx enabled driving 1, Rx disabled and Rx driving 0 back to its controller
  92 + * internally
  93 + */
  94 +#define PAD_CFG1_IOSSTATE_TX1_RX_DCR_X0 (0x3 << 14)
  95 +/*
  96 + * Tx enabled driving 1, Rx disabled and Rx driving 1 back to its controller
  97 + * internally
  98 + */
  99 +#define PAD_CFG1_IOSSTATE_TX1_RX_DCR_X1 (0x4 << 14)
  100 +/* Tx enabled driving 0, Rx enabled */
  101 +#define PAD_CFG1_IOSSTATE_TX0_RXE (0x5 << 14)
  102 +/* Tx enabled driving 1, Rx enabled */
  103 +#define PAD_CFG1_IOSSTATE_TX1_RXE (0x6 << 14)
  104 +/* Hi-Z, Rx driving 0 back to its controller internally */
  105 +#define PAD_CFG1_IOSSTATE_HIZCRX0 (0x7 << 14)
  106 +/* Hi-Z, Rx driving 1 back to its controller internally */
  107 +#define PAD_CFG1_IOSSTATE_HIZCRX1 (0x8 << 14)
  108 +/* Tx disabled, Rx enabled */
  109 +#define PAD_CFG1_IOSSTATE_TXD_RXE (0x9 << 14)
  110 +#define PAD_CFG1_IOSSTATE_IGNORE (0xf << 14) /* Ignore Iostandby */
  111 +/* mask to extract Iostandby bits */
  112 +#define PAD_CFG1_IOSSTATE_MASK (0xf << 14)
  113 +#define PAD_CFG1_IOSSTATE_SHIFT 14 /* set Iostandby bits [17:14] */
  114 +
  115 +#define PAD_CFG2_DEBEN 1
  116 +/* Debounce Duration = (2 ^ PAD_CFG2_DEBOUNCE_x_RTC) * RTC clock duration */
  117 +#define PAD_CFG2_DEBOUNCE_8_RTC (0x3 << 1)
  118 +#define PAD_CFG2_DEBOUNCE_16_RTC (0x4 << 1)
  119 +#define PAD_CFG2_DEBOUNCE_32_RTC (0x5 << 1)
  120 +#define PAD_CFG2_DEBOUNCE_64_RTC (0x6 << 1)
  121 +#define PAD_CFG2_DEBOUNCE_128_RTC (0x7 << 1)
  122 +#define PAD_CFG2_DEBOUNCE_256_RTC (0x8 << 1)
  123 +#define PAD_CFG2_DEBOUNCE_512_RTC (0x9 << 1)
  124 +#define PAD_CFG2_DEBOUNCE_1K_RTC (0xa << 1)
  125 +#define PAD_CFG2_DEBOUNCE_2K_RTC (0xb << 1)
  126 +#define PAD_CFG2_DEBOUNCE_4K_RTC (0xc << 1)
  127 +#define PAD_CFG2_DEBOUNCE_8K_RTC (0xd << 1)
  128 +#define PAD_CFG2_DEBOUNCE_16K_RTC (0xe << 1)
  129 +#define PAD_CFG2_DEBOUNCE_32K_RTC (0xf << 1)
  130 +#define PAD_CFG2_DEBOUNCE_MASK 0x1f
  131 +
  132 +/* voltage tolerance 0=3.3V default 1=1.8V tolerant */
  133 +#if IS_ENABLED(INTEL_PINCTRL_IOSTANDBY)
  134 +#define PAD_CFG1_TOL_MASK (0x1 << 25)
  135 +#define PAD_CFG1_TOL_1V8 (0x1 << 25)
  136 +#endif
  137 +
  138 +#define PAD_FUNC(value) PAD_CFG0_MODE_##value
  139 +#define PAD_RESET(value) PAD_CFG0_LOGICAL_RESET_##value
  140 +#define PAD_PULL(value) PAD_CFG1_PULL_##value
  141 +
  142 +#define PAD_IOSSTATE(value) PAD_CFG1_IOSSTATE_##value
  143 +#define PAD_IOSTERM(value) PAD_CFG1_IOSTERM_##value
  144 +
  145 +#define PAD_IRQ_CFG(route, trig, inv) \
  146 + (PAD_CFG0_ROUTE_##route | \
  147 + PAD_CFG0_TRIG_##trig | \
  148 + PAD_CFG0_RX_POL_##inv)
  149 +
  150 +#if IS_ENABLED(INTEL_PINCTRL_DUAL_ROUTE_SUPPORT)
  151 +#define PAD_IRQ_CFG_DUAL_ROUTE(route1, route2, trig, inv) \
  152 + (PAD_CFG0_ROUTE_##route1 | \
  153 + PAD_CFG0_ROUTE_##route2 | \
  154 + PAD_CFG0_TRIG_##trig | \
  155 + PAD_CFG0_RX_POL_##inv)
  156 +#endif /* CONFIG_INTEL_PINCTRL_DUAL_ROUTE_SUPPORT */
  157 +
  158 +#define _PAD_CFG_STRUCT(__pad, __config0, __config1) \
  159 + __pad(__config0) (__config1)
  160 +
  161 +/* Native function configuration */
  162 +#define PAD_CFG_NF(pad, pull, rst, func) \
  163 + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \
  164 + PAD_IOSSTATE(TX_LAST_RXE))
  165 +
  166 +#if IS_ENABLED(CONFIG_INTEL_GPIO_PADCFG_PADTOL)
  167 +/*
  168 + * Native 1.8V tolerant pad, only applies to some pads like I2C/I2S. Not
  169 + * applicable to all SOCs. Refer EDS.
  170 + */
  171 +#define PAD_CFG_NF_1V8(pad, pull, rst, func) \
  172 + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) |\
  173 + PAD_IOSSTATE(TX_LAST_RXE) | PAD_CFG1_TOL_1V8)
  174 +#endif
  175 +
  176 +/* Native function configuration for standby state */
  177 +#define PAD_CFG_NF_IOSSTATE(pad, pull, rst, func, iosstate) \
  178 + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \
  179 + PAD_IOSSTATE(iosstate))
  180 +
  181 +/*
  182 + * Native function configuration for standby state, also configuring iostandby
  183 + * as masked
  184 + */
  185 +#define PAD_CFG_NF_IOSTANDBY_IGNORE(pad, pull, rst, func) \
  186 + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \
  187 + PAD_IOSSTATE(IGNORE))
  188 +
  189 +/*
  190 + * Native function configuration for standby state, also configuring iosstate
  191 + * and iosterm
  192 + */
  193 +#define PAD_CFG_NF_IOSSTATE_IOSTERM(pad, pull, rst, func, iosstate, iosterm) \
  194 + _PAD_CFG_STRUCT(pad, PAD_RESET(rst) | PAD_FUNC(func), PAD_PULL(pull) | \
  195 + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm))
  196 +
  197 +/* General purpose output, no pullup/down */
  198 +#define PAD_CFG_GPO(pad, val, rst) \
  199 + _PAD_CFG_STRUCT(pad, \
  200 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \
  201 + PAD_PULL(NONE) | PAD_IOSSTATE(TX_LAST_RXE))
  202 +
  203 +/* General purpose output, with termination specified */
  204 +#define PAD_CFG_TERM_GPO(pad, val, pull, rst) \
  205 + _PAD_CFG_STRUCT(pad, \
  206 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \
  207 + PAD_PULL(pull) | PAD_IOSSTATE(TX_LAST_RXE))
  208 +
  209 +/* General purpose output, no pullup/down */
  210 +#define PAD_CFG_GPO_GPIO_DRIVER(pad, val, rst, pull) \
  211 + _PAD_CFG_STRUCT(pad, \
  212 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \
  213 + PAD_PULL(pull) | PAD_IOSSTATE(TX_LAST_RXE) | \
  214 + PAD_CFG1_GPIO_DRIVER)
  215 +
  216 +/* General purpose output */
  217 +#define PAD_CFG_GPO_IOSSTATE_IOSTERM(pad, val, rst, pull, iosstate, ioterm) \
  218 + _PAD_CFG_STRUCT(pad, \
  219 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_RX_DISABLE | !!val, \
  220 + PAD_PULL(pull) | PAD_IOSSTATE(iosstate) | PAD_IOSTERM(ioterm))
  221 +
  222 +/* General purpose input */
  223 +#define PAD_CFG_GPI(pad, pull, rst) \
  224 + _PAD_CFG_STRUCT(pad, \
  225 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE, \
  226 + PAD_PULL(pull) | PAD_IOSSTATE(TXD_RXE))
  227 +
  228 +/* General purpose input. The following macro sets the
  229 + * Host Software Pad Ownership to GPIO Driver mode.
  230 + */
  231 +#define PAD_CFG_GPI_GPIO_DRIVER(pad, pull, rst) \
  232 + _PAD_CFG_STRUCT(pad, \
  233 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE, \
  234 + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TXD_RXE))
  235 +
  236 +#define PAD_CFG_GPIO_DRIVER_HI_Z(pad, pull, rst, iosstate, iosterm) \
  237 + _PAD_CFG_STRUCT(pad, \
  238 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  239 + PAD_CFG0_RX_DISABLE, \
  240 + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | \
  241 + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm))
  242 +
  243 +#define PAD_CFG_GPIO_HI_Z(pad, pull, rst, iosstate, iosterm) \
  244 + _PAD_CFG_STRUCT(pad, \
  245 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  246 + PAD_CFG0_RX_DISABLE, PAD_PULL(pull) | \
  247 + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm))
  248 +
  249 +/* GPIO Interrupt */
  250 +#define PAD_CFG_GPI_INT(pad, pull, rst, trig) \
  251 + _PAD_CFG_STRUCT(pad, \
  252 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  253 + PAD_CFG0_TRIG_##trig | PAD_CFG0_RX_POL_NONE, \
  254 + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TXD_RXE))
  255 +
  256 +/*
  257 + * No Connect configuration for unused pad.
  258 + * Both TX and RX are disabled. RX disabling is done to avoid unnecessary
  259 + * setting of GPI_STS.
  260 + */
  261 +#define PAD_NC(pad, pull) \
  262 + _PAD_CFG_STRUCT(pad, \
  263 + PAD_FUNC(GPIO) | PAD_RESET(DEEP) | \
  264 + PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE, \
  265 + PAD_PULL(pull) | PAD_IOSSTATE(TXD_RXE))
  266 +
  267 +/* General purpose input, routed to APIC */
  268 +#define PAD_CFG_GPI_APIC(pad, pull, rst, trig, inv) \
  269 + _PAD_CFG_STRUCT(pad, \
  270 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  271 + PAD_IRQ_CFG(IOAPIC, trig, inv), PAD_PULL(pull) | \
  272 + PAD_IOSSTATE(TXD_RXE))
  273 +
  274 +/* General purpose input, routed to APIC - with IOStandby Config*/
  275 +#define PAD_CFG_GPI_APIC_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \
  276 + _PAD_CFG_STRUCT(pad, \
  277 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  278 + PAD_IRQ_CFG(IOAPIC, trig, inv), PAD_PULL(pull) | \
  279 + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm))
  280 +
  281 +/*
  282 + * The following APIC macros assume the APIC will handle the filtering
  283 + * on its own end. One just needs to pass an active high message into the
  284 + * ITSS.
  285 + */
  286 +#define PAD_CFG_GPI_APIC_LOW(pad, pull, rst) \
  287 + PAD_CFG_GPI_APIC(pad, pull, rst, LEVEL, INVERT)
  288 +
  289 +#define PAD_CFG_GPI_APIC_HIGH(pad, pull, rst) \
  290 + PAD_CFG_GPI_APIC(pad, pull, rst, LEVEL, NONE)
  291 +
  292 +#define PAD_CFG_GPI_APIC_EDGE_LOW(pad, pull, rst) \
  293 + PAD_CFG_GPI_APIC(pad, pull, rst, EDGE_SINGLE, INVERT)
  294 +
  295 +/* General purpose input, routed to SMI */
  296 +#define PAD_CFG_GPI_SMI(pad, pull, rst, trig, inv) \
  297 + _PAD_CFG_STRUCT(pad, \
  298 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  299 + PAD_IRQ_CFG(SMI, trig, inv), PAD_PULL(pull) | \
  300 + PAD_IOSSTATE(TXD_RXE))
  301 +
  302 +/* General purpose input, routed to SMI */
  303 +#define PAD_CFG_GPI_SMI_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \
  304 + _PAD_CFG_STRUCT(pad, \
  305 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  306 + PAD_IRQ_CFG(SMI, trig, inv), PAD_PULL(pull) | \
  307 + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm))
  308 +
  309 +#define PAD_CFG_GPI_SMI_LOW(pad, pull, rst, trig) \
  310 + PAD_CFG_GPI_SMI(pad, pull, rst, trig, INVERT)
  311 +
  312 +#define PAD_CFG_GPI_SMI_HIGH(pad, pull, rst, trig) \
  313 + PAD_CFG_GPI_SMI(pad, pull, rst, trig, NONE)
  314 +
  315 +/* General purpose input, routed to SCI */
  316 +#define PAD_CFG_GPI_SCI(pad, pull, rst, trig, inv) \
  317 + _PAD_CFG_STRUCT(pad, \
  318 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  319 + PAD_IRQ_CFG(SCI, trig, inv), PAD_PULL(pull) | \
  320 + PAD_IOSSTATE(TXD_RXE))
  321 +
  322 +/* General purpose input, routed to SCI */
  323 +#define PAD_CFG_GPI_SCI_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) \
  324 + _PAD_CFG_STRUCT(pad, \
  325 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  326 + PAD_IRQ_CFG(SCI, trig, inv), PAD_PULL(pull) | \
  327 + PAD_IOSSTATE(iosstate) | PAD_IOSTERM(iosterm))
  328 +
  329 +#define PAD_CFG_GPI_SCI_LOW(pad, pull, rst, trig) \
  330 + PAD_CFG_GPI_SCI(pad, pull, rst, trig, INVERT)
  331 +
  332 +#define PAD_CFG_GPI_SCI_HIGH(pad, pull, rst, trig) \
  333 + PAD_CFG_GPI_SCI(pad, pull, rst, trig, NONE)
  334 +
  335 +#define PAD_CFG_GPI_SCI_DEBEN(pad, pull, rst, trig, inv, dur) \
  336 + _PAD_CFG_STRUCT_3(pad, \
  337 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  338 + PAD_IRQ_CFG(SCI, trig, inv), PAD_PULL(pull) | \
  339 + PAD_IOSSTATE(TXD_RXE), PAD_CFG2_DEBEN | PAD_CFG2_##dur)
  340 +
  341 +#define PAD_CFG_GPI_SCI_LOW_DEBEN(pad, pull, rst, trig, dur) \
  342 + PAD_CFG_GPI_SCI_DEBEN(pad, pull, rst, trig, INVERT, dur)
  343 +
  344 +#define PAD_CFG_GPI_SCI_HIGH_DEBEN(pad, pull, rst, trig, dur) \
  345 + PAD_CFG_GPI_SCI_DEBEN(pad, pull, rst, trig, NONE, dur)
  346 +
  347 +/* General purpose input, routed to NMI */
  348 +#define PAD_CFG_GPI_NMI(pad, pull, rst, trig, inv) \
  349 + _PAD_CFG_STRUCT(pad, \
  350 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  351 + PAD_IRQ_CFG(NMI, trig, inv), PAD_PULL(pull) | \
  352 + PAD_IOSSTATE(TXD_RXE))
  353 +
  354 +#if IS_ENABLED(INTEL_PINCTRL_DUAL_ROUTE_SUPPORT)
  355 +/* GPI, GPIO Driver, SCI interrupt */
  356 +#define PAD_CFG_GPI_GPIO_DRIVER_SCI(pad, pull, rst, trig, inv) \
  357 + _PAD_CFG_STRUCT(pad, \
  358 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  359 + PAD_IRQ_CFG(SCI, trig, inv), \
  360 + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TXD_RXE))
  361 +
  362 +#define PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, route1, route2) \
  363 + _PAD_CFG_STRUCT(pad, \
  364 + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \
  365 + PAD_IRQ_CFG_DUAL_ROUTE(route1, route2, trig, inv), \
  366 + PAD_PULL(pull) | PAD_IOSSTATE(TXD_RXE))
  367 +
  368 +#define PAD_CFG_GPI_IRQ_WAKE(pad, pull, rst, trig, inv) \
  369 + PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, IOAPIC, SCI)
  370 +
  371 +#endif /* CONFIG_INTEL_PINCTRL_DUAL_ROUTE_SUPPORT */
  372 +
  373 +#endif /* _ASM_INTEL_PINCTRL_DEFS_H_ */
doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt
  1 +* Intel Apollo Lake pin controller
  2 +
  3 +The Apollo Lake (APL) pin controller is used to select the function of a pin
  4 +and to configure it.
  5 +
  6 +Required properties:
  7 +- compatible: "intel,apl-pinctrl"
  8 +- intel,p2sb-port-id: Port ID number within the parent P2SB
  9 +- reg: PCI address of the controller
  10 +
  11 +Please refer to pinctrl-bindings.txt in this directory for details of the
  12 +common pinctrl bindings used by client devices.
  13 +
  14 +Optional subnodes:
  15 +
  16 +GPIO nodes may be added as children of the pinctrl nodes. See intel,apl-gpio
  17 +for the binding.
  18 +
  19 +
  20 +Example:
  21 +
  22 +...
  23 +{
  24 + p2sb: p2sb@d,0 {
  25 + reg = <0x02006810 0 0 0 0>;
  26 + compatible = "intel,apl-p2sb";
  27 + early-regs = <IOMAP_P2SB_BAR 0x100000>;
  28 +
  29 + n {
  30 + compatible = "intel,apl-pinctrl";
  31 + intel,p2sb-port-id = <PID_GPIO_N>;
  32 + gpio_n: gpio-n {
  33 + compatible = "intel,apl-gpio";
  34 + #gpio-cells = <2>;
  35 + };
  36 + };
  37 + };
  38 +};
  39 +...
drivers/pinctrl/Kconfig
... ... @@ -177,6 +177,14 @@
177 177 This option is to enable the AT91 pinctrl driver for AT91 PIO4
178 178 controller which is available on SAMA5D2 SoC.
179 179  
  180 +config PINCTRL_INTEL
  181 + bool "Standard Intel pin-control and pin-mux driver"
  182 + help
  183 + Recent Intel chips such as Apollo Lake (APL) use a common pin control
  184 + and GPIO scheme. The settings for this come from an SoC-specific
  185 + driver which must be separately enabled. The driver supports setting
  186 + pins on start-up and changing the GPIO attributes.
  187 +
180 188 config PINCTRL_PIC32
181 189 bool "Microchip PIC32 pin-control and pin-mux driver"
182 190 depends on DM && MACH_PIC32
... ... @@ -280,6 +288,7 @@
280 288  
281 289 source "drivers/pinctrl/broadcom/Kconfig"
282 290 source "drivers/pinctrl/exynos/Kconfig"
  291 +source "drivers/pinctrl/intel/Kconfig"
283 292 source "drivers/pinctrl/mediatek/Kconfig"
284 293 source "drivers/pinctrl/meson/Kconfig"
285 294 source "drivers/pinctrl/mscc/Kconfig"
drivers/pinctrl/Makefile
... ... @@ -9,6 +9,7 @@
9 9 obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/
10 10 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
11 11 obj-$(CONFIG_ARCH_ATH79) += ath79/
  12 +obj-$(CONFIG_PINCTRL_INTEL) += intel/
12 13 obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
13 14 obj-$(CONFIG_ARCH_RMOBILE) += renesas/
14 15 obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
drivers/pinctrl/intel/Kconfig
  1 +#
  2 +# Intel PINCTRL drivers
  3 +#
  4 +
  5 +if PINCTRL_INTEL
  6 +
  7 +config INTEL_PINCTRL_DUAL_ROUTE_SUPPORT
  8 + def_bool y
  9 +
  10 +config INTEL_PINCTRL_PADCFG_PADTOL
  11 + def_bool n
  12 +
  13 +config INTEL_PINCTRL_IOSTANDBY
  14 + def_bool y
  15 +
  16 +endif
drivers/pinctrl/intel/Makefile
  1 +# SPDX-License-Identifier: GPL-2.0+
  2 +#
  3 +# Copyright 2019 Google LLC
  4 +
  5 +obj-y += pinctrl.o
drivers/pinctrl/intel/pinctrl.c
  1 +// SPDX-License-Identifier: GPL-2.0
  2 +/*
  3 + * Copyright (C) 2017 Intel Corp.
  4 + * Copyright 2019 Google LLC
  5 + *
  6 + * Taken partly from coreboot gpio.c
  7 + *
  8 + * Pinctrl is modelled as a separate device-tree node and device for each
  9 + * 'community' (basically a set of GPIOs). The separate devices work together
  10 + * and many functions permit any PINCTRL device to be provided as a parameter,
  11 + * since the pad numbering is unique across all devices.
  12 + *
  13 + * Each pinctrl has a single child GPIO device to handle GPIO access and
  14 + * therefore there is a simple GPIO driver included in this file.
  15 + */
  16 +
  17 +#define LOG_CATEGORY UCLASS_GPIO
  18 +
  19 +#include <common.h>
  20 +#include <dm.h>
  21 +#include <irq.h>
  22 +#include <p2sb.h>
  23 +#include <spl.h>
  24 +#include <asm-generic/gpio.h>
  25 +#include <asm/intel_pinctrl.h>
  26 +#include <asm/intel_pinctrl_defs.h>
  27 +#include <asm/arch/gpio.h>
  28 +#include <asm/arch/itss.h>
  29 +#include <dm/device-internal.h>
  30 +#include <dt-bindings/gpio/gpio.h>
  31 +
  32 +#define GPIO_DW_SIZE(x) (sizeof(u32) * (x))
  33 +#define PAD_CFG_OFFSET(x, dw_num) ((x) + GPIO_DW_SIZE(dw_num))
  34 +#define PAD_CFG0_OFFSET(x) PAD_CFG_OFFSET(x, 0)
  35 +#define PAD_CFG1_OFFSET(x) PAD_CFG_OFFSET(x, 1)
  36 +
  37 +#define MISCCFG_GPE0_DW0_SHIFT 8
  38 +#define MISCCFG_GPE0_DW0_MASK (0xf << MISCCFG_GPE0_DW0_SHIFT)
  39 +#define MISCCFG_GPE0_DW1_SHIFT 12
  40 +#define MISCCFG_GPE0_DW1_MASK (0xf << MISCCFG_GPE0_DW1_SHIFT)
  41 +#define MISCCFG_GPE0_DW2_SHIFT 16
  42 +#define MISCCFG_GPE0_DW2_MASK (0xf << MISCCFG_GPE0_DW2_SHIFT)
  43 +
  44 +#define GPI_SMI_STS_OFFSET(comm, group) ((comm)->gpi_smi_sts_reg_0 + \
  45 + ((group) * sizeof(u32)))
  46 +#define GPI_SMI_EN_OFFSET(comm, group) ((comm)->gpi_smi_en_reg_0 + \
  47 + ((group) * sizeof(u32)))
  48 +#define GPI_IS_OFFSET(comm, group) ((comm)->gpi_int_sts_reg_0 + \
  49 + ((group) * sizeof(uint32_t)))
  50 +#define GPI_IE_OFFSET(comm, group) ((comm)->gpi_int_en_reg_0 + \
  51 + ((group) * sizeof(uint32_t)))
  52 +
  53 +/**
  54 + * relative_pad_in_comm() - Get the relative position of a GPIO
  55 + *
  56 + * This finds the position of a GPIO within a community
  57 + *
  58 + * @comm: Community to search
  59 + * @gpio: Pad number to look up (assumed to be valid)
  60 + * @return offset, 0 for first GPIO in community
  61 + */
  62 +static size_t relative_pad_in_comm(const struct pad_community *comm,
  63 + uint gpio)
  64 +{
  65 + return gpio - comm->first_pad;
  66 +}
  67 +
  68 +/**
  69 + * pinctrl_group_index() - Find group for a a pad
  70 + *
  71 + * Find the group within the community that the pad is a part of
  72 + *
  73 + * @comm: Community to search
  74 + * @relative_pad: Pad to look up
  75 + * @return group number if found (see community_n_groups, etc.), or
  76 + * -ESPIPE if no groups, or -ENOENT if not found
  77 + */
  78 +static int pinctrl_group_index(const struct pad_community *comm,
  79 + uint relative_pad)
  80 +{
  81 + int i;
  82 +
  83 + if (!comm->groups)
  84 + return -ESPIPE;
  85 +
  86 + /* find the base pad number for this pad's group */
  87 + for (i = 0; i < comm->num_groups; i++) {
  88 + if (relative_pad >= comm->groups[i].first_pad &&
  89 + relative_pad < comm->groups[i].first_pad +
  90 + comm->groups[i].size)
  91 + return i;
  92 + }
  93 +
  94 + return -ENOENT;
  95 +}
  96 +
  97 +static int pinctrl_group_index_scaled(const struct pad_community *comm,
  98 + uint relative_pad, size_t scale)
  99 +{
  100 + int ret;
  101 +
  102 + ret = pinctrl_group_index(comm, relative_pad);
  103 + if (ret < 0)
  104 + return ret;
  105 +
  106 + return ret * scale;
  107 +}
  108 +
  109 +static int pinctrl_within_group(const struct pad_community *comm,
  110 + uint relative_pad)
  111 +{
  112 + int ret;
  113 +
  114 + ret = pinctrl_group_index(comm, relative_pad);
  115 + if (ret < 0)
  116 + return ret;
  117 +
  118 + return relative_pad - comm->groups[ret].first_pad;
  119 +}
  120 +
  121 +static u32 pinctrl_bitmask_within_group(const struct pad_community *comm,
  122 + uint relative_pad)
  123 +{
  124 + return 1U << pinctrl_within_group(comm, relative_pad);
  125 +}
  126 +
  127 +/**
  128 + * pinctrl_get_device() - Find the device for a particular pad
  129 + *
  130 + * Each pinctr, device is attached to one community and this supports a number
  131 + * of pads. This function finds the device which controls a particular pad.
  132 + *
  133 + * @pad: Pad to check
  134 + * @devp: Returns the device for that pad
  135 + * @return 0 if OK, -ENOTBLK if no device was found for the given pin
  136 + */
  137 +static int pinctrl_get_device(uint pad, struct udevice **devp)
  138 +{
  139 + struct udevice *dev;
  140 +
  141 + /*
  142 + * We have to probe each one of these since the community link is only
  143 + * attached in intel_pinctrl_ofdata_to_platdata().
  144 + */
  145 + uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) {
  146 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  147 + const struct pad_community *comm = priv->comm;
  148 +
  149 + if (pad >= comm->first_pad && pad <= comm->last_pad) {
  150 + *devp = dev;
  151 + return 0;
  152 + }
  153 + }
  154 + printf("pad %d not found\n", pad);
  155 +
  156 + return -ENOTBLK;
  157 +}
  158 +
  159 +int intel_pinctrl_get_pad(uint pad, struct udevice **devp, uint *offsetp)
  160 +{
  161 + const struct pad_community *comm;
  162 + struct intel_pinctrl_priv *priv;
  163 + struct udevice *dev;
  164 + int ret;
  165 +
  166 + ret = pinctrl_get_device(pad, &dev);
  167 + if (ret)
  168 + return log_msg_ret("pad", ret);
  169 + priv = dev_get_priv(dev);
  170 + comm = priv->comm;
  171 + *devp = dev;
  172 + *offsetp = relative_pad_in_comm(comm, pad);
  173 +
  174 + return 0;
  175 +}
  176 +
  177 +static int pinctrl_configure_owner(struct udevice *dev,
  178 + const struct pad_config *cfg,
  179 + const struct pad_community *comm)
  180 +{
  181 + u32 hostsw_own;
  182 + u16 hostsw_own_offset;
  183 + int pin;
  184 + int ret;
  185 +
  186 + pin = relative_pad_in_comm(comm, cfg->pad);
  187 +
  188 + /*
  189 + * Based on the gpio pin number configure the corresponding bit in
  190 + * HOSTSW_OWN register. Value of 0x1 indicates GPIO Driver onwership.
  191 + */
  192 + hostsw_own_offset = comm->host_own_reg_0;
  193 + ret = pinctrl_group_index_scaled(comm, pin, sizeof(u32));
  194 + if (ret < 0)
  195 + return ret;
  196 + hostsw_own_offset += ret;
  197 +
  198 + hostsw_own = pcr_read32(dev, hostsw_own_offset);
  199 +
  200 + /*
  201 + *The 4th bit in pad_config 1 (RO) is used to indicate if the pad
  202 + * needs GPIO driver ownership. Set the bit if GPIO driver ownership
  203 + * requested, otherwise clear the bit.
  204 + */
  205 + if (cfg->pad_config[1] & PAD_CFG1_GPIO_DRIVER)
  206 + hostsw_own |= pinctrl_bitmask_within_group(comm, pin);
  207 + else
  208 + hostsw_own &= ~pinctrl_bitmask_within_group(comm, pin);
  209 +
  210 + pcr_write32(dev, hostsw_own_offset, hostsw_own);
  211 +
  212 + return 0;
  213 +}
  214 +
  215 +static int gpi_enable_smi(struct udevice *dev, const struct pad_config *cfg,
  216 + const struct pad_community *comm)
  217 +{
  218 + u32 value;
  219 + u16 sts_reg;
  220 + u16 en_reg;
  221 + int group;
  222 + int pin;
  223 + int ret;
  224 +
  225 + if ((cfg->pad_config[0] & PAD_CFG0_ROUTE_SMI) != PAD_CFG0_ROUTE_SMI)
  226 + return 0;
  227 +
  228 + pin = relative_pad_in_comm(comm, cfg->pad);
  229 + ret = pinctrl_group_index(comm, pin);
  230 + if (ret < 0)
  231 + return ret;
  232 + group = ret;
  233 +
  234 + sts_reg = GPI_SMI_STS_OFFSET(comm, group);
  235 + value = pcr_read32(dev, sts_reg);
  236 + /* Write back 1 to reset the sts bits */
  237 + pcr_write32(dev, sts_reg, value);
  238 +
  239 + /* Set enable bits */
  240 + en_reg = GPI_SMI_EN_OFFSET(comm, group);
  241 + pcr_setbits32(dev, en_reg, pinctrl_bitmask_within_group(comm, pin));
  242 +
  243 + return 0;
  244 +}
  245 +
  246 +static int pinctrl_configure_itss(struct udevice *dev,
  247 + const struct pad_config *cfg,
  248 + uint pad_cfg_offset)
  249 +{
  250 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  251 +
  252 + if (!priv->itss_pol_cfg)
  253 + return -ENOSYS;
  254 +
  255 + int irq;
  256 +
  257 + /*
  258 + * Set up ITSS polarity if pad is routed to APIC.
  259 + *
  260 + * The ITSS takes only active high interrupt signals. Therefore,
  261 + * if the pad configuration indicates an inversion assume the
  262 + * intent is for the ITSS polarity. Before forwarding on the
  263 + * request to the APIC there's an inversion setting for how the
  264 + * signal is forwarded to the APIC. Honor the inversion setting
  265 + * in the GPIO pad configuration so that a hardware active low
  266 + * signal looks that way to the APIC (double inversion).
  267 + */
  268 + if (!(cfg->pad_config[0] & PAD_CFG0_ROUTE_IOAPIC))
  269 + return 0;
  270 +
  271 + irq = pcr_read32(dev, PAD_CFG1_OFFSET(pad_cfg_offset));
  272 + irq &= PAD_CFG1_IRQ_MASK;
  273 + if (!irq) {
  274 + log_err("GPIO %u doesn't support APIC routing\n", cfg->pad);
  275 +
  276 + return -EPROTONOSUPPORT;
  277 + }
  278 + irq_set_polarity(priv->itss, irq,
  279 + cfg->pad_config[0] & PAD_CFG0_RX_POL_INVERT);
  280 +
  281 + return 0;
  282 +}
  283 +
  284 +/* Number of DWx config registers can be different for different SOCs */
  285 +static uint pad_config_offset(struct intel_pinctrl_priv *priv, uint pad)
  286 +{
  287 + const struct pad_community *comm = priv->comm;
  288 + size_t offset;
  289 +
  290 + offset = relative_pad_in_comm(comm, pad);
  291 + offset *= GPIO_DW_SIZE(priv->num_cfgs);
  292 +
  293 + return offset + comm->pad_cfg_base;
  294 +}
  295 +
  296 +static int pinctrl_pad_reset_config_override(const struct pad_community *comm,
  297 + u32 config_value)
  298 +{
  299 + const struct reset_mapping *rst_map = comm->reset_map;
  300 + int i;
  301 +
  302 + /* Logical reset values equal chipset values */
  303 + if (!rst_map || !comm->num_reset_vals)
  304 + return config_value;
  305 +
  306 + for (i = 0; i < comm->num_reset_vals; i++, rst_map++) {
  307 + if ((config_value & PAD_CFG0_RESET_MASK) == rst_map->logical) {
  308 + config_value &= ~PAD_CFG0_RESET_MASK;
  309 + config_value |= rst_map->chipset;
  310 +
  311 + return config_value;
  312 + }
  313 + }
  314 + log_err("Logical-to-Chipset mapping not found\n");
  315 +
  316 + return -ENOENT;
  317 +}
  318 +
  319 +static const int mask[4] = {
  320 + PAD_CFG0_TX_STATE |
  321 + PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE | PAD_CFG0_MODE_MASK |
  322 + PAD_CFG0_ROUTE_MASK | PAD_CFG0_RXTENCFG_MASK |
  323 + PAD_CFG0_RXINV_MASK | PAD_CFG0_PREGFRXSEL |
  324 + PAD_CFG0_TRIG_MASK | PAD_CFG0_RXRAW1_MASK |
  325 + PAD_CFG0_RXPADSTSEL_MASK | PAD_CFG0_RESET_MASK,
  326 +
  327 +#ifdef CONFIG_INTEL_PINCTRL_IOSTANDBY
  328 + PAD_CFG1_IOSTERM_MASK | PAD_CFG1_PULL_MASK | PAD_CFG1_IOSSTATE_MASK,
  329 +#else
  330 + PAD_CFG1_IOSTERM_MASK | PAD_CFG1_PULL_MASK,
  331 +#endif
  332 +
  333 + PAD_CFG2_DEBOUNCE_MASK,
  334 +
  335 + 0,
  336 +};
  337 +
  338 +/**
  339 + * pinctrl_configure_pad() - Configure a pad
  340 + *
  341 + * @dev: Pinctrl device containing the pad (see pinctrl_get_device())
  342 + * @cfg: Configuration to apply
  343 + * @return 0 if OK, -ve on error
  344 + */
  345 +static int pinctrl_configure_pad(struct udevice *dev,
  346 + const struct pad_config *cfg)
  347 +{
  348 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  349 + const struct pad_community *comm = priv->comm;
  350 + uint config_offset;
  351 + u32 pad_conf, soc_pad_conf;
  352 + int ret;
  353 + int i;
  354 +
  355 + if (IS_ERR(comm))
  356 + return PTR_ERR(comm);
  357 + config_offset = pad_config_offset(priv, cfg->pad);
  358 + for (i = 0; i < priv->num_cfgs; i++) {
  359 + pad_conf = pcr_read32(dev, PAD_CFG_OFFSET(config_offset, i));
  360 +
  361 + soc_pad_conf = cfg->pad_config[i];
  362 + if (i == 0) {
  363 + ret = pinctrl_pad_reset_config_override(comm,
  364 + soc_pad_conf);
  365 + if (ret < 0)
  366 + return ret;
  367 + soc_pad_conf = ret;
  368 + }
  369 + soc_pad_conf &= mask[i];
  370 + soc_pad_conf |= pad_conf & ~mask[i];
  371 +
  372 + log_debug("pinctrl_padcfg [0x%02x, %02zd] DW%d [0x%08x : 0x%08x : 0x%08x]\n",
  373 + comm->port, relative_pad_in_comm(comm, cfg->pad), i,
  374 + pad_conf,/* old value */
  375 + /* value passed from pinctrl table */
  376 + cfg->pad_config[i],
  377 + soc_pad_conf); /*new value*/
  378 + pcr_write32(dev, PAD_CFG_OFFSET(config_offset, i),
  379 + soc_pad_conf);
  380 + }
  381 + ret = pinctrl_configure_itss(dev, cfg, config_offset);
  382 + if (ret && ret != -ENOSYS)
  383 + return log_msg_ret("itss config failed", ret);
  384 + ret = pinctrl_configure_owner(dev, cfg, comm);
  385 + if (ret)
  386 + return ret;
  387 + ret = gpi_enable_smi(dev, cfg, comm);
  388 + if (ret)
  389 + return ret;
  390 +
  391 + return 0;
  392 +}
  393 +
  394 +u32 intel_pinctrl_get_config_reg_addr(struct udevice *dev, uint offset)
  395 +{
  396 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  397 + const struct pad_community *comm = priv->comm;
  398 + uint config_offset;
  399 +
  400 + assert(device_get_uclass_id(dev) == UCLASS_PINCTRL);
  401 + config_offset = comm->pad_cfg_base + offset *
  402 + GPIO_DW_SIZE(priv->num_cfgs);
  403 +
  404 + return config_offset;
  405 +}
  406 +
  407 +u32 intel_pinctrl_get_config_reg(struct udevice *dev, uint offset)
  408 +{
  409 + uint config_offset = intel_pinctrl_get_config_reg_addr(dev, offset);
  410 +
  411 + return pcr_read32(dev, config_offset);
  412 +}
  413 +
  414 +int intel_pinctrl_get_acpi_pin(struct udevice *dev, uint offset)
  415 +{
  416 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  417 + const struct pad_community *comm = priv->comm;
  418 + int group;
  419 +
  420 + group = pinctrl_group_index(comm, offset);
  421 +
  422 + /* If pad base is not set then use GPIO number as ACPI pin number */
  423 + if (comm->groups[group].acpi_pad_base == PAD_BASE_NONE)
  424 + return comm->first_pad + offset;
  425 +
  426 + /*
  427 + * If this group has a non-zero pad base then compute the ACPI pin
  428 + * number from the pad base and the relative pad in the group.
  429 + */
  430 + return comm->groups[group].acpi_pad_base +
  431 + pinctrl_within_group(comm, offset);
  432 +}
  433 +
  434 +int pinctrl_route_gpe(struct udevice *itss, uint gpe0b, uint gpe0c, uint gpe0d)
  435 +{
  436 + struct udevice *pinctrl_dev;
  437 + u32 misccfg_value;
  438 + u32 misccfg_clr;
  439 + int ret;
  440 +
  441 + /*
  442 + * Get the group here for community specific MISCCFG register.
  443 + * If any of these returns -1 then there is some error in devicetree
  444 + * where the group is probably hardcoded and does not comply with the
  445 + * PMC group defines. So we return from here and MISCFG is set to
  446 + * default.
  447 + */
  448 + ret = irq_route_pmc_gpio_gpe(itss, gpe0b);
  449 + if (ret)
  450 + return ret;
  451 + gpe0b = ret;
  452 +
  453 + ret = irq_route_pmc_gpio_gpe(itss, gpe0c);
  454 + if (ret)
  455 + return ret;
  456 + gpe0c = ret;
  457 +
  458 + ret = irq_route_pmc_gpio_gpe(itss, gpe0d);
  459 + if (ret)
  460 + return ret;
  461 + gpe0d = ret;
  462 +
  463 + misccfg_value = gpe0b << MISCCFG_GPE0_DW0_SHIFT;
  464 + misccfg_value |= gpe0c << MISCCFG_GPE0_DW1_SHIFT;
  465 + misccfg_value |= gpe0d << MISCCFG_GPE0_DW2_SHIFT;
  466 +
  467 + /* Program GPIO_MISCCFG */
  468 + misccfg_clr = MISCCFG_GPE0_DW2_MASK | MISCCFG_GPE0_DW1_MASK |
  469 + MISCCFG_GPE0_DW0_MASK;
  470 +
  471 + log_debug("misccfg_clr:%x misccfg_value:%x\n", misccfg_clr,
  472 + misccfg_value);
  473 + uclass_foreach_dev_probe(UCLASS_PINCTRL, pinctrl_dev) {
  474 + pcr_clrsetbits32(pinctrl_dev, GPIO_MISCCFG, misccfg_clr,
  475 + misccfg_value);
  476 + }
  477 +
  478 + return 0;
  479 +}
  480 +
  481 +int pinctrl_gpi_clear_int_cfg(void)
  482 +{
  483 + struct udevice *dev;
  484 + struct uclass *uc;
  485 + int ret;
  486 +
  487 + ret = uclass_get(UCLASS_PINCTRL, &uc);
  488 + if (ret)
  489 + return log_msg_ret("pinctrl uc", ret);
  490 + uclass_foreach_dev(dev, uc) {
  491 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  492 + const struct pad_community *comm = priv->comm;
  493 + uint sts_value;
  494 + int group;
  495 +
  496 + for (group = 0; group < comm->num_gpi_regs; group++) {
  497 + /* Clear the enable register */
  498 + pcr_write32(dev, GPI_IE_OFFSET(comm, group), 0);
  499 +
  500 + /* Read and clear the set status register bits*/
  501 + sts_value = pcr_read32(dev,
  502 + GPI_IS_OFFSET(comm, group));
  503 + pcr_write32(dev, GPI_IS_OFFSET(comm, group), sts_value);
  504 + }
  505 + }
  506 +
  507 + return 0;
  508 +}
  509 +
  510 +int pinctrl_config_pads(struct udevice *dev, u32 *pads, int pads_count)
  511 +{
  512 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  513 + const u32 *ptr;
  514 + int i;
  515 +
  516 + log_debug("%s: pads_count=%d\n", __func__, pads_count);
  517 + for (ptr = pads, i = 0; i < pads_count;
  518 + ptr += 1 + priv->num_cfgs, i++) {
  519 + struct udevice *pad_dev = NULL;
  520 + struct pad_config *cfg;
  521 + int ret;
  522 +
  523 + cfg = (struct pad_config *)ptr;
  524 + ret = pinctrl_get_device(cfg->pad, &pad_dev);
  525 + if (ret)
  526 + return ret;
  527 + ret = pinctrl_configure_pad(pad_dev, cfg);
  528 + if (ret)
  529 + return ret;
  530 + }
  531 +
  532 + return 0;
  533 +}
  534 +
  535 +int pinctrl_read_pads(struct udevice *dev, ofnode node, const char *prop,
  536 + u32 **padsp, int *pad_countp)
  537 +{
  538 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  539 + u32 *pads;
  540 + int size;
  541 + int ret;
  542 +
  543 + *padsp = NULL;
  544 + *pad_countp = 0;
  545 + size = ofnode_read_size(node, prop);
  546 + if (size < 0)
  547 + return 0;
  548 +
  549 + pads = malloc(size);
  550 + if (!pads)
  551 + return -ENOMEM;
  552 + size /= sizeof(fdt32_t);
  553 + ret = ofnode_read_u32_array(node, prop, pads, size);
  554 + if (ret) {
  555 + free(pads);
  556 + return ret;
  557 + }
  558 + *pad_countp = size / (1 + priv->num_cfgs);
  559 + *padsp = pads;
  560 +
  561 + return 0;
  562 +}
  563 +
  564 +int pinctrl_count_pads(struct udevice *dev, u32 *pads, int size)
  565 +{
  566 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  567 + int count = 0;
  568 + int i;
  569 +
  570 + for (i = 0; i < size;) {
  571 + u32 val;
  572 + int j;
  573 +
  574 + for (val = j = 0; j < priv->num_cfgs + 1; j++)
  575 + val |= pads[i + j];
  576 + if (!val)
  577 + break;
  578 + count++;
  579 + i += priv->num_cfgs + 1;
  580 + }
  581 +
  582 + return count;
  583 +}
  584 +
  585 +int pinctrl_config_pads_for_node(struct udevice *dev, ofnode node)
  586 +{
  587 + int pads_count;
  588 + u32 *pads;
  589 + int ret;
  590 +
  591 + if (device_get_uclass_id(dev) != UCLASS_PINCTRL)
  592 + return log_msg_ret("uclass", -EPROTONOSUPPORT);
  593 + ret = pinctrl_read_pads(dev, node, "pads", &pads, &pads_count);
  594 + if (ret)
  595 + return log_msg_ret("no pads", ret);
  596 + ret = pinctrl_config_pads(dev, pads, pads_count);
  597 + free(pads);
  598 + if (ret)
  599 + return log_msg_ret("pad config", ret);
  600 +
  601 + return 0;
  602 +}
  603 +
  604 +int intel_pinctrl_ofdata_to_platdata(struct udevice *dev,
  605 + const struct pad_community *comm,
  606 + int num_cfgs)
  607 +{
  608 + struct p2sb_child_platdata *pplat = dev_get_parent_platdata(dev);
  609 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  610 + int ret;
  611 +
  612 + if (!comm) {
  613 + log_err("Cannot find community for pid %d\n", pplat->pid);
  614 + return -EDOM;
  615 + }
  616 + ret = uclass_first_device_err(UCLASS_IRQ, &priv->itss);
  617 + if (ret)
  618 + return log_msg_ret("Cannot find ITSS", ret);
  619 + priv->comm = comm;
  620 + priv->num_cfgs = num_cfgs;
  621 +
  622 + return 0;
  623 +}
  624 +
  625 +int intel_pinctrl_probe(struct udevice *dev)
  626 +{
  627 + struct intel_pinctrl_priv *priv = dev_get_priv(dev);
  628 +
  629 + priv->itss_pol_cfg = true;
  630 +
  631 + return 0;
  632 +}
  633 +
  634 +const struct pinctrl_ops intel_pinctrl_ops = {
  635 + /* No operations are supported, but DM expects this to be present */
  636 +};