blob: dab3ad85edc4624568ed2f95a7c4488340046d35 [file] [log] [blame]
/*
* Copyright (C) 2015 Google Inc.
* Copyright (C) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.
*/
#ifndef __DRIVERS_GPIO_SKYLAKE_H__
#define __DRIVERS_GPIO_SKYLAKE_H__
#include <stdint.h>
#include "base/cleanup.h"
/*
* There are 8 GPIO groups. GPP_A -> GPP_G and GPD. GPD is the special case
* where that group is not so generic. So most of the fixed numbers and macros
* are based on the GPP groups. The GPIO groups are accessed through register
* blocks called communities.
*/
#define GPP_A 0
#define GPP_B 1
#define GPP_C 2
#define GPP_D 3
#define GPP_E 4
#define GPP_F 5
#define GPP_G 6
#define GPD 7
#define GPIO_NUM_GROUPS 8
#define GPIO_MAX_NUM_PER_GROUP 24
/*
* GPIOs are ordered monotonically increasing to match ACPI/OS driver.
*/
/* Group A */
#define GPP_A0 0
#define GPP_A1 1
#define GPP_A2 2
#define GPP_A3 3
#define GPP_A4 4
#define GPP_A5 5
#define GPP_A6 6
#define GPP_A7 7
#define GPP_A8 8
#define GPP_A9 9
#define GPP_A10 10
#define GPP_A11 11
#define GPP_A12 12
#define GPP_A13 13
#define GPP_A14 14
#define GPP_A15 15
#define GPP_A16 16
#define GPP_A17 17
#define GPP_A18 18
#define GPP_A19 19
#define GPP_A20 20
#define GPP_A21 21
#define GPP_A22 22
#define GPP_A23 23
/* Group B */
#define GPP_B0 24
#define GPP_B1 25
#define GPP_B2 26
#define GPP_B3 27
#define GPP_B4 28
#define GPP_B5 29
#define GPP_B6 30
#define GPP_B7 31
#define GPP_B8 32
#define GPP_B9 33
#define GPP_B10 34
#define GPP_B11 35
#define GPP_B12 36
#define GPP_B13 37
#define GPP_B14 38
#define GPP_B15 39
#define GPP_B16 40
#define GPP_B17 41
#define GPP_B18 42
#define GPP_B19 43
#define GPP_B20 44
#define GPP_B21 45
#define GPP_B22 46
#define GPP_B23 47
/* Group C */
#define GPP_C0 48
#define GPP_C1 49
#define GPP_C2 50
#define GPP_C3 51
#define GPP_C4 52
#define GPP_C5 53
#define GPP_C6 54
#define GPP_C7 55
#define GPP_C8 56
#define GPP_C9 57
#define GPP_C10 58
#define GPP_C11 59
#define GPP_C12 60
#define GPP_C13 61
#define GPP_C14 62
#define GPP_C15 63
#define GPP_C16 64
#define GPP_C17 65
#define GPP_C18 66
#define GPP_C19 67
#define GPP_C20 68
#define GPP_C21 69
#define GPP_C22 70
#define GPP_C23 71
/* Group D */
#define GPP_D0 72
#define GPP_D1 73
#define GPP_D2 74
#define GPP_D3 75
#define GPP_D4 76
#define GPP_D5 77
#define GPP_D6 78
#define GPP_D7 79
#define GPP_D8 80
#define GPP_D9 81
#define GPP_D10 82
#define GPP_D11 83
#define GPP_D12 84
#define GPP_D13 85
#define GPP_D14 86
#define GPP_D15 87
#define GPP_D16 88
#define GPP_D17 89
#define GPP_D18 90
#define GPP_D19 91
#define GPP_D20 92
#define GPP_D21 93
#define GPP_D22 94
#define GPP_D23 95
/* Group E */
#define GPP_E0 96
#define GPP_E1 97
#define GPP_E2 98
#define GPP_E3 99
#define GPP_E4 100
#define GPP_E5 101
#define GPP_E6 102
#define GPP_E7 103
#define GPP_E8 104
#define GPP_E9 105
#define GPP_E10 106
#define GPP_E11 107
#define GPP_E12 108
#define GPP_E13 109
#define GPP_E14 110
#define GPP_E15 111
#define GPP_E16 112
#define GPP_E17 113
#define GPP_E18 114
#define GPP_E19 115
#define GPP_E20 116
#define GPP_E21 117
#define GPP_E22 118
#define GPP_E23 119
/* Group F */
#define GPP_F0 120
#define GPP_F1 121
#define GPP_F2 122
#define GPP_F3 123
#define GPP_F4 124
#define GPP_F5 125
#define GPP_F6 126
#define GPP_F7 127
#define GPP_F8 128
#define GPP_F9 129
#define GPP_F10 130
#define GPP_F11 131
#define GPP_F12 132
#define GPP_F13 133
#define GPP_F14 134
#define GPP_F15 135
#define GPP_F16 136
#define GPP_F17 137
#define GPP_F18 138
#define GPP_F19 139
#define GPP_F20 140
#define GPP_F21 141
#define GPP_F22 142
#define GPP_F23 143
/* Group G */
#define GPP_G0 144
#define GPP_G1 145
#define GPP_G2 146
#define GPP_G3 147
#define GPP_G4 148
#define GPP_G5 149
#define GPP_G6 150
#define GPP_G7 151
/* Group GPD */
#define GPD0 152
#define GPD1 153
#define GPD2 154
#define GPD3 155
#define GPD4 156
#define GPD5 157
#define GPD6 158
#define GPD7 159
#define GPD8 160
#define GPD9 161
#define GPD10 162
#define GPD11 163
/* Register defines. */
#define MISCCFG_OFFSET 0x10
#define GPIO_DRIVER_IRQ_ROUTE_MASK 8
#define GPIO_DRIVER_IRQ_ROUTE_IRQ14 0
#define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8
#define GPE_DW_SHIFT 8
#define GPE_DW_MASK 0xfff00
#define PAD_OWN_REG_OFFSET 0x20
#define PAD_OWN_PADS_PER 8
#define PAD_OWN_WIDTH_PER 4
#define PAD_OWN_MASK 0x03
#define PAD_OWN_HOST 0x00
#define PAD_OWN_ME 0x01
#define PAD_OWN_ISH 0x02
#define HOSTSW_OWN_REG_OFFSET 0xd0
#define HOSTSW_OWN_PADS_PER 24
#define HOSTSW_OWN_ACPI 0
#define HOSTSW_OWN_GPIO 1
#define PAD_CFG_DW_OFFSET 0x400
/* PADRSTCFG - when to reset the pad config */
#define PADRSTCFG_SHIFT 30
#define PADRSTCFG_MASK 0x3
#define PADRSTCFG_DSW_PWROK 0
#define PADRSTCFG_DEEP 1
#define PADRSTCFG_PLTRST 2
#define PADRSTCFG_RSMRST 3
/* RXPADSTSEL - raw signal or internal state */
#define RXPADSTSEL_SHIFT 29
#define RXPADSTSEL_MASK 0x1
#define RXPADSTSEL_RAW 0
#define RXPADSTSEL_INTERNAL 1
/* RXRAW1 - drive 1 instead instead of pad value */
#define RXRAW1_SHIFT 28
#define RXRAW1_MASK 0x1
#define RXRAW1_NO 0
#define RXRAW1_YES 1
/* RXEVCFG - Interrupt and wake types */
#define RXEVCFG_SHIFT 25
#define RXEVCFG_MASK 0x3
#define RXEVCFG_LEVEL 0
#define RXEVCFG_EDGE 1
#define RXEVCFG_DRIVE0 2
/* PREGFRXSEL - use filtering on Rx pad */
#define PREGFRXSEL_SHIFT 24
#define PREGFRXSEL_MASK 0x1
#define PREGFRXSEL_NO 0
#define PREGFRXSEL_YES 1
/* RXINV - invert signal to SMI, SCI, NMI, or IRQ routing. */
#define RXINV_SHIFT 23
#define RXINV_MASK 0x1
#define RXINV_NO 0
#define RXINV_YES 1
/* GPIROUTIOXAPIC - route to io-xapic or not */
#define GPIROUTIOXAPIC_SHIFT 20
#define GPIROUTIOXAPIC_MASK 0x1
#define GPIROUTIOXAPIC_NO 0
#define GPIROUTIOXAPIC_YES 1
/* GPIROUTSCI - route to SCI */
#define GPIROUTSCI_SHIFT 19
#define GPIROUTSCI_MASK 0x1
#define GPIROUTSCI_NO 0
#define GPIROUTSCI_YES 1
/* GPIROUTSMI - route to SMI */
#define GPIROUTSMI_SHIFT 18
#define GPIROUTSMI_MASK 0x1
#define GPIROUTSMI_NO 0
#define GPIROUTSMI_YES 1
/* GPIROUTNMI - route to NMI */
#define GPIROUTNMI_SHIFT 17
#define GPIROUTNMI_MASK 0x1
#define GPIROUTNMI_NO 0
#define GPIROUTNMI_YES 1
/* PMODE - mode of pad */
#define PMODE_SHIFT 10
#define PMODE_MASK 0x3
#define PMODE_GPIO 0
#define PMODE_NF1 1
#define PMODE_NF2 2
#define PMODE_NF3 3
/* GPIORXDIS - Disable Rx */
#define GPIORXDIS_SHIFT 9
#define GPIORXDIS_MASK 0x1
#define GPIORXDIS_NO 0
#define GPIORXDIS_YES 1
/* GPIOTXDIS - Disable Tx */
#define GPIOTXDIS_SHIFT 8
#define GPIOTXDIS_MASK 0x1
#define GPIOTXDIS_NO 0
#define GPIOTXDIS_YES 1
/* GPIORXSTATE - Internal state after glitch filter */
#define GPIORXSTATE_SHIFT 1
#define GPIORXSTATE_MASK 0x1
/* GPIOTXSTATE - Drive value onto pad */
#define GPIOTXSTATE_SHIFT 0
#define GPIOTXSTATE_MASK 0x1
#define PAD_CFG_DW_OFFSET 0x400
/* TERM - termination control */
#define PAD_TERM_SHIFT 10
#define PAD_TERM_MASK 0xf
#define PAD_TERM_NONE 0
#define PAD_TERM_5K_PD 2
#define PAD_TERM_1K_PU 9
#define PAD_TERM_2K_PU 11
#define PAD_TERM_5K_PU 10
#define PAD_TERM_20K_PU 12
#define PAD_TERM_667_PU 13
#define PAD_TERM_NATIVE 15
#define PAD_FIELD_VAL(field_, val_) \
(((val_) & field_ ## _MASK) << field_ ## _SHIFT)
#define PAD_FIELD(field_, setting_) \
PAD_FIELD_VAL(field_, field_ ## _ ## setting_)
/*
* This encodes all the fields found within the dw0 register for each
* pad. It directly follows the register specification:
* rst - reset type when pad configuration is reset
* rxst - native function routing: raw buffer or internal buffer
* rxraw1 - drive fixed '1' for Rx buffer
* rxev - event filtering for pad value: level, edge, drive '0'
* rxgf - glitch filter enable
* rxinv - invert the internal pad state
* gpiioapic - route to IOxAPIC
* gpisci - route for SCI
* gpismi - route for SMI
* gpinmi - route for NMI
* mode - GPIO vs native function
* rxdis - disable Rx buffer
* txdis - disable Tx buffer
*/
#define _DW0_VALS(rst, rxst, rxraw1, rxev, rxgf, rxinv, gpiioapic, gpisci, \
gpismi, gpinmi, mode, rxdis, txdis) \
(PAD_FIELD(PADRSTCFG, rst) | \
PAD_FIELD(RXPADSTSEL, rxst) | \
PAD_FIELD(RXRAW1, rxraw1) | \
PAD_FIELD(RXEVCFG, rxev) | \
PAD_FIELD(PREGFRXSEL, rxgf) | \
PAD_FIELD(RXINV, rxinv) | \
PAD_FIELD(GPIROUTIOXAPIC, gpiioapic) | \
PAD_FIELD(GPIROUTSCI, gpisci) | \
PAD_FIELD(GPIROUTSMI, gpismi) | \
PAD_FIELD(GPIROUTNMI, gpinmi) | \
PAD_FIELD(PMODE, mode) | \
PAD_FIELD(GPIORXDIS, rxdis) | \
PAD_FIELD(GPIOTXDIS, txdis))
#define _PAD_CFG_ATTRS(pad_, term_, dw0_, attrs_) \
{ \
.pad = pad_, \
.attrs = PAD_FIELD(PAD_TERM, term_) | attrs_, \
.dw0 = dw0_, \
}
/* Default to ACPI owned. Ownership only matters for GPI pads. */
#define _PAD_CFG(pad_, term_, dw0_) \
_PAD_CFG_ATTRS(pad_, term_, dw0_, PAD_FIELD(HOSTSW, ACPI))
/* Native Function - No Rx buffer manipulation */
#define PAD_CFG_NF(pad_, term_, rst_, func_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, func_, NO, NO))
/* General purpose output. By default no termination. */
#define PAD_CFG_GPO(pad_, val_, rst_) \
_PAD_CFG(pad_, NONE, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, YES, NO) \
| PAD_FIELD_VAL(GPIOTXSTATE, val_))
/* General purpose input with no special IRQ routing. */
#define PAD_CFG_GPI(pad_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, NO, NO, NO, NO, GPIO, NO, YES))
/* General purpose input passed through to IOxAPIC. Assume APIC logic can
* handle polarity/edge/level constraints. */
#define PAD_CFG_GPI_APIC(pad_, term_, rst_) \
_PAD_CFG(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, LEVEL, NO, NO, YES, NO, NO, NO, GPIO, NO, YES))
/* General purpose input routed to SCI. This assumes edge triggered events. */
#define PAD_CFG_GPI_ACPI_SCI(pad_, term_, rst_, inv_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
NO, YES, NO, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
/* General purpose input routed to SMI. This assumes edge triggered events. */
#define PAD_CFG_GPI_ACPI_SMI(pad_, term_, rst_, inv_) \
_PAD_CFG_ATTRS(pad_, term_, \
_DW0_VALS(rst_, RAW, NO, EDGE, NO, inv_, \
NO, NO, YES, NO, GPIO, NO, YES), PAD_FIELD(HOSTSW, ACPI))
/*
* The 'attrs' field carries the termination in bits 13:10 to match up with
* thd DW1 pad configuration register. Additionally, other attributes can
* be applied such as the ones below. Bit allocation matters.
*/
#define HOSTSW_SHIFT 0
#define HOSTSW_MASK 1
#define HOSTSW_ACPI HOSTSW_OWN_ACPI
#define HOSTSW_GPIO HOSTSW_OWN_GPIO
struct pad_config {
uint16_t pad;
uint16_t attrs;
uint32_t dw0;
};
/*
* Depthcharge GPIO interface.
*/
typedef struct GpioCfg {
GpioOps ops;
int gpio_num; /* GPIO number */
uint32_t *dw_regs; /* Pointer to DW regs */
uint32_t current_dw0; /* Current DW0 register value */
/* Use to save and restore GPIO configuration */
uint32_t save_dw0;
uint32_t save_dw1;
CleanupEvent cleanup;
int (*configure)(struct GpioCfg *, const struct pad_config *);
} GpioCfg;
GpioCfg *new_skylake_gpio(int gpio_num);
GpioCfg *new_skylake_gpio_input(int gpio_num);
GpioCfg *new_skylake_gpio_output(int gpio_num, unsigned value);
#endif /* __DRIVERS_GPIO_SKYLAKE_H__ */