diff options
Diffstat (limited to 'drivers/pinctrl/intel')
19 files changed, 13762 insertions, 0 deletions
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig new file mode 100644 index 000000000..28e5f824b --- /dev/null +++ b/drivers/pinctrl/intel/Kconfig @@ -0,0 +1,146 @@ +# SPDX-License-Identifier: GPL-2.0 +# Intel pin control drivers + +if (X86 || COMPILE_TEST) + +config PINCTRL_BAYTRAIL + bool "Intel Baytrail GPIO pin control" + depends on ACPI + select PINCTRL_INTEL + help + driver for memory mapped GPIO functionality on Intel Baytrail + platforms. Supports 3 banks with 102, 28 and 44 gpios. + Most pins are usually muxed to some other functionality by firmware, + so only a small amount is available for gpio use. + + Requires ACPI device enumeration code to set up a platform device. + +config PINCTRL_CHERRYVIEW + tristate "Intel Cherryview/Braswell pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + Cherryview/Braswell pinctrl driver provides an interface that + allows configuring of SoC pins and using them as GPIOs. + +config PINCTRL_LYNXPOINT + tristate "Intel Lynxpoint pinctrl and GPIO driver" + depends on ACPI + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + help + Lynxpoint is the PCH of Intel Haswell. This pinctrl driver + provides an interface that allows configuring of PCH pins and + using them as GPIOs. + +config PINCTRL_MERRIFIELD + tristate "Intel Merrifield pinctrl driver" + depends on X86_INTEL_MID + select PINMUX + select PINCONF + select GENERIC_PINCONF + help + Merrifield Family-Level Interface Shim (FLIS) driver provides an + interface that allows configuring of SoC pins and using them as + GPIOs. + +config PINCTRL_INTEL + tristate + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GPIOLIB + select GPIOLIB_IRQCHIP + +config PINCTRL_BROXTON + tristate "Intel Broxton pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + Broxton pinctrl driver provides an interface that allows + configuring of SoC pins and using them as GPIOs. + +config PINCTRL_CANNONLAKE + tristate "Intel Cannon Lake PCH pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Cannon Lake PCH pins and using them as GPIOs. + +config PINCTRL_CEDARFORK + tristate "Intel Cedar Fork pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Cedar Fork PCH pins and using them as GPIOs. + +config PINCTRL_DENVERTON + tristate "Intel Denverton pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Denverton SoC pins and using them as GPIOs. + +config PINCTRL_EMMITSBURG + tristate "Intel Emmitsburg pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Emmitsburg pins and using them as GPIOs. + +config PINCTRL_GEMINILAKE + tristate "Intel Gemini Lake SoC pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Gemini Lake SoC pins and using them as GPIOs. + +config PINCTRL_ICELAKE + tristate "Intel Ice Lake PCH pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Ice Lake PCH pins and using them as GPIOs. + +config PINCTRL_JASPERLAKE + tristate "Intel Jasper Lake PCH pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Jasper Lake PCH pins and using them as GPIOs. + +config PINCTRL_LEWISBURG + tristate "Intel Lewisburg pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Lewisburg pins and using them as GPIOs. + +config PINCTRL_SUNRISEPOINT + tristate "Intel Sunrisepoint pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + Sunrisepoint is the PCH of Intel Skylake. This pinctrl driver + provides an interface that allows configuring of PCH pins and + using them as GPIOs. + +config PINCTRL_TIGERLAKE + tristate "Intel Tiger Lake pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Tiger Lake PCH pins and using them as GPIOs. +endif diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile new file mode 100644 index 000000000..1c1c316f9 --- /dev/null +++ b/drivers/pinctrl/intel/Makefile @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +# Intel pin control drivers + +obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o +obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o +obj-$(CONFIG_PINCTRL_LYNXPOINT) += pinctrl-lynxpoint.o +obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o +obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o +obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o +obj-$(CONFIG_PINCTRL_CANNONLAKE) += pinctrl-cannonlake.o +obj-$(CONFIG_PINCTRL_CEDARFORK) += pinctrl-cedarfork.o +obj-$(CONFIG_PINCTRL_DENVERTON) += pinctrl-denverton.o +obj-$(CONFIG_PINCTRL_EMMITSBURG) += pinctrl-emmitsburg.o +obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o +obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o +obj-$(CONFIG_PINCTRL_JASPERLAKE) += pinctrl-jasperlake.o +obj-$(CONFIG_PINCTRL_LEWISBURG) += pinctrl-lewisburg.o +obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o +obj-$(CONFIG_PINCTRL_TIGERLAKE) += pinctrl-tigerlake.o diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c new file mode 100644 index 000000000..394a421a1 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -0,0 +1,1800 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Pinctrl GPIO driver for Intel Baytrail + * + * Copyright (c) 2012-2013, Intel Corporation + * Author: Mathias Nyman <mathias.nyman@linux.intel.com> + */ + +#include <linux/acpi.h> +#include <linux/bitops.h> +#include <linux/gpio/driver.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/property.h> +#include <linux/seq_file.h> + +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> + +#include "pinctrl-intel.h" + +/* memory mapped register offsets */ +#define BYT_CONF0_REG 0x000 +#define BYT_CONF1_REG 0x004 +#define BYT_VAL_REG 0x008 +#define BYT_DFT_REG 0x00c +#define BYT_INT_STAT_REG 0x800 +#define BYT_DEBOUNCE_REG 0x9d0 + +/* BYT_CONF0_REG register bits */ +#define BYT_IODEN BIT(31) +#define BYT_DIRECT_IRQ_EN BIT(27) +#define BYT_TRIG_MASK GENMASK(26, 24) +#define BYT_TRIG_NEG BIT(26) +#define BYT_TRIG_POS BIT(25) +#define BYT_TRIG_LVL BIT(24) +#define BYT_DEBOUNCE_EN BIT(20) +#define BYT_GLITCH_FILTER_EN BIT(19) +#define BYT_GLITCH_F_SLOW_CLK BIT(17) +#define BYT_GLITCH_F_FAST_CLK BIT(16) +#define BYT_PULL_STR_SHIFT 9 +#define BYT_PULL_STR_MASK GENMASK(10, 9) +#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) +#define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) +#define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) +#define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) +#define BYT_PULL_ASSIGN_SHIFT 7 +#define BYT_PULL_ASSIGN_MASK GENMASK(8, 7) +#define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT) +#define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT) +#define BYT_PIN_MUX GENMASK(2, 0) + +/* BYT_VAL_REG register bits */ +#define BYT_DIR_MASK GENMASK(2, 1) +#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ +#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ +#define BYT_LEVEL BIT(0) + +#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX) +#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) + +/* BYT_DEBOUNCE_REG bits */ +#define BYT_DEBOUNCE_PULSE_MASK GENMASK(2, 0) +#define BYT_DEBOUNCE_PULSE_375US 1 +#define BYT_DEBOUNCE_PULSE_750US 2 +#define BYT_DEBOUNCE_PULSE_1500US 3 +#define BYT_DEBOUNCE_PULSE_3MS 4 +#define BYT_DEBOUNCE_PULSE_6MS 5 +#define BYT_DEBOUNCE_PULSE_12MS 6 +#define BYT_DEBOUNCE_PULSE_24MS 7 + +#define BYT_NGPIO_SCORE 102 +#define BYT_NGPIO_NCORE 28 +#define BYT_NGPIO_SUS 44 + +#define BYT_SCORE_ACPI_UID "1" +#define BYT_NCORE_ACPI_UID "2" +#define BYT_SUS_ACPI_UID "3" + +/* + * This is the function value most pins have for GPIO muxing. If the value + * differs from the default one, it must be explicitly mentioned. Otherwise, the + * pin control implementation will set the muxing value to default GPIO if it + * does not find a match for the requested function. + */ +#define BYT_DEFAULT_GPIO_MUX 0 +#define BYT_ALTER_GPIO_MUX 1 + +struct intel_pad_context { + u32 conf0; + u32 val; +}; + +#define COMMUNITY(p, n, map) \ + { \ + .pin_base = (p), \ + .npins = (n), \ + .pad_map = (map),\ + } + +/* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ +static const struct pinctrl_pin_desc byt_score_pins[] = { + PINCTRL_PIN(0, "SATA_GP0"), + PINCTRL_PIN(1, "SATA_GP1"), + PINCTRL_PIN(2, "SATA_LED#"), + PINCTRL_PIN(3, "PCIE_CLKREQ0"), + PINCTRL_PIN(4, "PCIE_CLKREQ1"), + PINCTRL_PIN(5, "PCIE_CLKREQ2"), + PINCTRL_PIN(6, "PCIE_CLKREQ3"), + PINCTRL_PIN(7, "SD3_WP"), + PINCTRL_PIN(8, "HDA_RST"), + PINCTRL_PIN(9, "HDA_SYNC"), + PINCTRL_PIN(10, "HDA_CLK"), + PINCTRL_PIN(11, "HDA_SDO"), + PINCTRL_PIN(12, "HDA_SDI0"), + PINCTRL_PIN(13, "HDA_SDI1"), + PINCTRL_PIN(14, "GPIO_S0_SC14"), + PINCTRL_PIN(15, "GPIO_S0_SC15"), + PINCTRL_PIN(16, "MMC1_CLK"), + PINCTRL_PIN(17, "MMC1_D0"), + PINCTRL_PIN(18, "MMC1_D1"), + PINCTRL_PIN(19, "MMC1_D2"), + PINCTRL_PIN(20, "MMC1_D3"), + PINCTRL_PIN(21, "MMC1_D4"), + PINCTRL_PIN(22, "MMC1_D5"), + PINCTRL_PIN(23, "MMC1_D6"), + PINCTRL_PIN(24, "MMC1_D7"), + PINCTRL_PIN(25, "MMC1_CMD"), + PINCTRL_PIN(26, "MMC1_RST"), + PINCTRL_PIN(27, "SD2_CLK"), + PINCTRL_PIN(28, "SD2_D0"), + PINCTRL_PIN(29, "SD2_D1"), + PINCTRL_PIN(30, "SD2_D2"), + PINCTRL_PIN(31, "SD2_D3_CD"), + PINCTRL_PIN(32, "SD2_CMD"), + PINCTRL_PIN(33, "SD3_CLK"), + PINCTRL_PIN(34, "SD3_D0"), + PINCTRL_PIN(35, "SD3_D1"), + PINCTRL_PIN(36, "SD3_D2"), + PINCTRL_PIN(37, "SD3_D3"), + PINCTRL_PIN(38, "SD3_CD"), + PINCTRL_PIN(39, "SD3_CMD"), + PINCTRL_PIN(40, "SD3_1P8EN"), + PINCTRL_PIN(41, "SD3_PWREN#"), + PINCTRL_PIN(42, "ILB_LPC_AD0"), + PINCTRL_PIN(43, "ILB_LPC_AD1"), + PINCTRL_PIN(44, "ILB_LPC_AD2"), + PINCTRL_PIN(45, "ILB_LPC_AD3"), + PINCTRL_PIN(46, "ILB_LPC_FRAME"), + PINCTRL_PIN(47, "ILB_LPC_CLK0"), + PINCTRL_PIN(48, "ILB_LPC_CLK1"), + PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), + PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), + PINCTRL_PIN(51, "PCU_SMB_DATA"), + PINCTRL_PIN(52, "PCU_SMB_CLK"), + PINCTRL_PIN(53, "PCU_SMB_ALERT"), + PINCTRL_PIN(54, "ILB_8254_SPKR"), + PINCTRL_PIN(55, "GPIO_S0_SC55"), + PINCTRL_PIN(56, "GPIO_S0_SC56"), + PINCTRL_PIN(57, "GPIO_S0_SC57"), + PINCTRL_PIN(58, "GPIO_S0_SC58"), + PINCTRL_PIN(59, "GPIO_S0_SC59"), + PINCTRL_PIN(60, "GPIO_S0_SC60"), + PINCTRL_PIN(61, "GPIO_S0_SC61"), + PINCTRL_PIN(62, "LPE_I2S2_CLK"), + PINCTRL_PIN(63, "LPE_I2S2_FRM"), + PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), + PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), + PINCTRL_PIN(66, "SIO_SPI_CS"), + PINCTRL_PIN(67, "SIO_SPI_MISO"), + PINCTRL_PIN(68, "SIO_SPI_MOSI"), + PINCTRL_PIN(69, "SIO_SPI_CLK"), + PINCTRL_PIN(70, "SIO_UART1_RXD"), + PINCTRL_PIN(71, "SIO_UART1_TXD"), + PINCTRL_PIN(72, "SIO_UART1_RTS"), + PINCTRL_PIN(73, "SIO_UART1_CTS"), + PINCTRL_PIN(74, "SIO_UART2_RXD"), + PINCTRL_PIN(75, "SIO_UART2_TXD"), + PINCTRL_PIN(76, "SIO_UART2_RTS"), + PINCTRL_PIN(77, "SIO_UART2_CTS"), + PINCTRL_PIN(78, "SIO_I2C0_DATA"), + PINCTRL_PIN(79, "SIO_I2C0_CLK"), + PINCTRL_PIN(80, "SIO_I2C1_DATA"), + PINCTRL_PIN(81, "SIO_I2C1_CLK"), + PINCTRL_PIN(82, "SIO_I2C2_DATA"), + PINCTRL_PIN(83, "SIO_I2C2_CLK"), + PINCTRL_PIN(84, "SIO_I2C3_DATA"), + PINCTRL_PIN(85, "SIO_I2C3_CLK"), + PINCTRL_PIN(86, "SIO_I2C4_DATA"), + PINCTRL_PIN(87, "SIO_I2C4_CLK"), + PINCTRL_PIN(88, "SIO_I2C5_DATA"), + PINCTRL_PIN(89, "SIO_I2C5_CLK"), + PINCTRL_PIN(90, "SIO_I2C6_DATA"), + PINCTRL_PIN(91, "SIO_I2C6_CLK"), + PINCTRL_PIN(92, "GPIO_S0_SC92"), + PINCTRL_PIN(93, "GPIO_S0_SC93"), + PINCTRL_PIN(94, "SIO_PWM0"), + PINCTRL_PIN(95, "SIO_PWM1"), + PINCTRL_PIN(96, "PMC_PLT_CLK0"), + PINCTRL_PIN(97, "PMC_PLT_CLK1"), + PINCTRL_PIN(98, "PMC_PLT_CLK2"), + PINCTRL_PIN(99, "PMC_PLT_CLK3"), + PINCTRL_PIN(100, "PMC_PLT_CLK4"), + PINCTRL_PIN(101, "PMC_PLT_CLK5"), +}; + +static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { + 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, + 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, + 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, + 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, + 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, + 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, + 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, + 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, + 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, + 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, + 97, 100, +}; + +/* SCORE groups */ +static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; +static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; + +static const unsigned int byt_score_pwm0_pins[] = { 94 }; +static const unsigned int byt_score_pwm1_pins[] = { 95 }; + +static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; + +static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; +static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; +static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; +static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; +static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; +static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; +static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; + +static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; +static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; +static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; + +static const unsigned int byt_score_sdcard_pins[] = { + 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, +}; +static const unsigned int byt_score_sdcard_mux_values[] = { + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; + +static const unsigned int byt_score_emmc_pins[] = { + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, +}; + +static const unsigned int byt_score_ilb_lpc_pins[] = { + 42, 43, 44, 45, 46, 47, 48, 49, 50, +}; + +static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; + +static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; +static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; +static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; +static const unsigned int byt_score_plt_clk3_pins[] = { 99 }; +static const unsigned int byt_score_plt_clk4_pins[] = { 100 }; +static const unsigned int byt_score_plt_clk5_pins[] = { 101 }; + +static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; + +static const struct intel_pingroup byt_score_groups[] = { + PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1), + PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1), + PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1), + PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1), + PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1), + PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1), + PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1), + PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1), + PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1), + PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1), + PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1), + PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1), + PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1), + PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1), + PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1), + PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), + PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1), + PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1), + PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1), + PIN_GROUP("sata_grp", byt_score_sata_pins, 1), + PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1), + PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1), + PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1), + PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1), + PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1), + PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1), + PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1), +}; + +static const char * const byt_score_uart_groups[] = { + "uart1_grp", "uart2_grp", +}; +static const char * const byt_score_pwm_groups[] = { + "pwm0_grp", "pwm1_grp", +}; +static const char * const byt_score_ssp_groups[] = { + "ssp0_grp", "ssp1_grp", "ssp2_grp", +}; +static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; +static const char * const byt_score_i2c_groups[] = { + "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", + "i2c6_grp", +}; +static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; +static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; +static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; +static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; +static const char * const byt_score_sata_groups[] = { "sata_grp" }; +static const char * const byt_score_plt_clk_groups[] = { + "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", + "plt_clk4_grp", "plt_clk5_grp", +}; +static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; +static const char * const byt_score_gpio_groups[] = { + "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", + "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", + "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", + "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", + "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", + "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", +}; + +static const struct intel_function byt_score_functions[] = { + FUNCTION("uart", byt_score_uart_groups), + FUNCTION("pwm", byt_score_pwm_groups), + FUNCTION("ssp", byt_score_ssp_groups), + FUNCTION("spi", byt_score_spi_groups), + FUNCTION("i2c", byt_score_i2c_groups), + FUNCTION("sdcard", byt_score_sdcard_groups), + FUNCTION("sdio", byt_score_sdio_groups), + FUNCTION("emmc", byt_score_emmc_groups), + FUNCTION("lpc", byt_score_lpc_groups), + FUNCTION("sata", byt_score_sata_groups), + FUNCTION("plt_clk", byt_score_plt_clk_groups), + FUNCTION("smbus", byt_score_smbus_groups), + FUNCTION("gpio", byt_score_gpio_groups), +}; + +static const struct intel_community byt_score_communities[] = { + COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), +}; + +static const struct intel_pinctrl_soc_data byt_score_soc_data = { + .uid = BYT_SCORE_ACPI_UID, + .pins = byt_score_pins, + .npins = ARRAY_SIZE(byt_score_pins), + .groups = byt_score_groups, + .ngroups = ARRAY_SIZE(byt_score_groups), + .functions = byt_score_functions, + .nfunctions = ARRAY_SIZE(byt_score_functions), + .communities = byt_score_communities, + .ncommunities = ARRAY_SIZE(byt_score_communities), +}; + +/* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ +static const struct pinctrl_pin_desc byt_sus_pins[] = { + PINCTRL_PIN(0, "GPIO_S50"), + PINCTRL_PIN(1, "GPIO_S51"), + PINCTRL_PIN(2, "GPIO_S52"), + PINCTRL_PIN(3, "GPIO_S53"), + PINCTRL_PIN(4, "GPIO_S54"), + PINCTRL_PIN(5, "GPIO_S55"), + PINCTRL_PIN(6, "GPIO_S56"), + PINCTRL_PIN(7, "GPIO_S57"), + PINCTRL_PIN(8, "GPIO_S58"), + PINCTRL_PIN(9, "GPIO_S59"), + PINCTRL_PIN(10, "GPIO_S510"), + PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), + PINCTRL_PIN(12, "PMC_SUSCLK0"), + PINCTRL_PIN(13, "GPIO_S513"), + PINCTRL_PIN(14, "USB_ULPI_RST"), + PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), + PINCTRL_PIN(16, "PMC_PWRBTN"), + PINCTRL_PIN(17, "GPIO_S517"), + PINCTRL_PIN(18, "PMC_SUS_STAT"), + PINCTRL_PIN(19, "USB_OC0"), + PINCTRL_PIN(20, "USB_OC1"), + PINCTRL_PIN(21, "PCU_SPI_CS1"), + PINCTRL_PIN(22, "GPIO_S522"), + PINCTRL_PIN(23, "GPIO_S523"), + PINCTRL_PIN(24, "GPIO_S524"), + PINCTRL_PIN(25, "GPIO_S525"), + PINCTRL_PIN(26, "GPIO_S526"), + PINCTRL_PIN(27, "GPIO_S527"), + PINCTRL_PIN(28, "GPIO_S528"), + PINCTRL_PIN(29, "GPIO_S529"), + PINCTRL_PIN(30, "GPIO_S530"), + PINCTRL_PIN(31, "USB_ULPI_CLK"), + PINCTRL_PIN(32, "USB_ULPI_DATA0"), + PINCTRL_PIN(33, "USB_ULPI_DATA1"), + PINCTRL_PIN(34, "USB_ULPI_DATA2"), + PINCTRL_PIN(35, "USB_ULPI_DATA3"), + PINCTRL_PIN(36, "USB_ULPI_DATA4"), + PINCTRL_PIN(37, "USB_ULPI_DATA5"), + PINCTRL_PIN(38, "USB_ULPI_DATA6"), + PINCTRL_PIN(39, "USB_ULPI_DATA7"), + PINCTRL_PIN(40, "USB_ULPI_DIR"), + PINCTRL_PIN(41, "USB_ULPI_NXT"), + PINCTRL_PIN(42, "USB_ULPI_STP"), + PINCTRL_PIN(43, "USB_ULPI_REFCLK"), +}; + +static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { + 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, + 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, + 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, + 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, + 52, 53, 59, 40, +}; + +static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; +static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 }; +static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 }; + +static const unsigned int byt_sus_usb_ulpi_pins[] = { + 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, +}; +static const unsigned int byt_sus_usb_ulpi_mode_values[] = { + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; +static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 }; +static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 }; + +static const struct intel_pingroup byt_sus_groups[] = { + PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values), + PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values), + PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values), + PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values), + PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values), + PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values), +}; + +static const char * const byt_sus_usb_groups[] = { + "usb_oc_grp", "usb_ulpi_grp", +}; +static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; +static const char * const byt_sus_gpio_groups[] = { + "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio", +}; + +static const struct intel_function byt_sus_functions[] = { + FUNCTION("usb", byt_sus_usb_groups), + FUNCTION("spi", byt_sus_spi_groups), + FUNCTION("gpio", byt_sus_gpio_groups), +}; + +static const struct intel_community byt_sus_communities[] = { + COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), +}; + +static const struct intel_pinctrl_soc_data byt_sus_soc_data = { + .uid = BYT_SUS_ACPI_UID, + .pins = byt_sus_pins, + .npins = ARRAY_SIZE(byt_sus_pins), + .groups = byt_sus_groups, + .ngroups = ARRAY_SIZE(byt_sus_groups), + .functions = byt_sus_functions, + .nfunctions = ARRAY_SIZE(byt_sus_functions), + .communities = byt_sus_communities, + .ncommunities = ARRAY_SIZE(byt_sus_communities), +}; + +static const struct pinctrl_pin_desc byt_ncore_pins[] = { + PINCTRL_PIN(0, "HV_DDI0_HPD"), + PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(3, "PANEL0_VDDEN"), + PINCTRL_PIN(4, "PANEL0_BKLTEN"), + PINCTRL_PIN(5, "PANEL0_BKLTCTL"), + PINCTRL_PIN(6, "HV_DDI1_HPD"), + PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"), + PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"), + PINCTRL_PIN(9, "PANEL1_VDDEN"), + PINCTRL_PIN(10, "PANEL1_BKLTEN"), + PINCTRL_PIN(11, "PANEL1_BKLTCTL"), + PINCTRL_PIN(12, "GP_INTD_DSI_TE1"), + PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"), + PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"), + PINCTRL_PIN(15, "GP_CAMERASB00"), + PINCTRL_PIN(16, "GP_CAMERASB01"), + PINCTRL_PIN(17, "GP_CAMERASB02"), + PINCTRL_PIN(18, "GP_CAMERASB03"), + PINCTRL_PIN(19, "GP_CAMERASB04"), + PINCTRL_PIN(20, "GP_CAMERASB05"), + PINCTRL_PIN(21, "GP_CAMERASB06"), + PINCTRL_PIN(22, "GP_CAMERASB07"), + PINCTRL_PIN(23, "GP_CAMERASB08"), + PINCTRL_PIN(24, "GP_CAMERASB09"), + PINCTRL_PIN(25, "GP_CAMERASB10"), + PINCTRL_PIN(26, "GP_CAMERASB11"), + PINCTRL_PIN(27, "GP_INTD_DSI_TE2"), +}; + +static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { + 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, + 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, + 3, 6, 10, 13, 2, 5, 9, 7, +}; + +static const struct intel_community byt_ncore_communities[] = { + COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), +}; + +static const struct intel_pinctrl_soc_data byt_ncore_soc_data = { + .uid = BYT_NCORE_ACPI_UID, + .pins = byt_ncore_pins, + .npins = ARRAY_SIZE(byt_ncore_pins), + .communities = byt_ncore_communities, + .ncommunities = ARRAY_SIZE(byt_ncore_communities), +}; + +static const struct intel_pinctrl_soc_data *byt_soc_data[] = { + &byt_score_soc_data, + &byt_sus_soc_data, + &byt_ncore_soc_data, + NULL +}; + +static DEFINE_RAW_SPINLOCK(byt_lock); + +static struct intel_community *byt_get_community(struct intel_pinctrl *vg, + unsigned int pin) +{ + struct intel_community *comm; + int i; + + for (i = 0; i < vg->ncommunities; i++) { + comm = vg->communities + i; + if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) + return comm; + } + + return NULL; +} + +static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset, + int reg) +{ + struct intel_community *comm = byt_get_community(vg, offset); + u32 reg_offset; + + if (!comm) + return NULL; + + offset -= comm->pin_base; + switch (reg) { + case BYT_INT_STAT_REG: + reg_offset = (offset / 32) * 4; + break; + case BYT_DEBOUNCE_REG: + reg_offset = 0; + break; + default: + reg_offset = comm->pad_map[offset] * 16; + break; + } + + return comm->pad_regs + reg_offset + reg; +} + +static int byt_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc->ngroups; +} + +static const char *byt_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc->groups[selector].name; +} + +static int byt_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + + *pins = vg->soc->groups[selector].pins; + *num_pins = vg->soc->groups[selector].npins; + + return 0; +} + +static const struct pinctrl_ops byt_pinctrl_ops = { + .get_groups_count = byt_get_groups_count, + .get_group_name = byt_get_group_name, + .get_group_pins = byt_get_group_pins, +}; + +static int byt_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc->nfunctions; +} + +static const char *byt_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + + return vg->soc->functions[selector].name; +} + +static int byt_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + + *groups = vg->soc->functions[selector].groups; + *num_groups = vg->soc->functions[selector].ngroups; + + return 0; +} + +static void byt_set_group_simple_mux(struct intel_pinctrl *vg, + const struct intel_pingroup group, + unsigned int func) +{ + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&byt_lock, flags); + + for (i = 0; i < group.npins; i++) { + void __iomem *padcfg0; + u32 value; + + padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); + if (!padcfg0) { + dev_warn(vg->dev, + "Group %s, pin %i not muxed (no padcfg0)\n", + group.name, i); + continue; + } + + value = readl(padcfg0); + value &= ~BYT_PIN_MUX; + value |= func; + writel(value, padcfg0); + } + + raw_spin_unlock_irqrestore(&byt_lock, flags); +} + +static void byt_set_group_mixed_mux(struct intel_pinctrl *vg, + const struct intel_pingroup group, + const unsigned int *func) +{ + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&byt_lock, flags); + + for (i = 0; i < group.npins; i++) { + void __iomem *padcfg0; + u32 value; + + padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); + if (!padcfg0) { + dev_warn(vg->dev, + "Group %s, pin %i not muxed (no padcfg0)\n", + group.name, i); + continue; + } + + value = readl(padcfg0); + value &= ~BYT_PIN_MUX; + value |= func[i]; + writel(value, padcfg0); + } + + raw_spin_unlock_irqrestore(&byt_lock, flags); +} + +static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, + unsigned int group_selector) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); + const struct intel_function func = vg->soc->functions[func_selector]; + const struct intel_pingroup group = vg->soc->groups[group_selector]; + + if (group.modes) + byt_set_group_mixed_mux(vg, group, group.modes); + else if (!strcmp(func.name, "gpio")) + byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); + else + byt_set_group_simple_mux(vg, group, group.mode); + + return 0; +} + +static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset) +{ + /* SCORE pin 92-93 */ + if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) && + offset >= 92 && offset <= 93) + return BYT_ALTER_GPIO_MUX; + + /* SUS pin 11-21 */ + if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) && + offset >= 11 && offset <= 21) + return BYT_ALTER_GPIO_MUX; + + return BYT_DEFAULT_GPIO_MUX; +} + +static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset) +{ + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&byt_lock, flags); + value = readl(reg); + + /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ + if (value & BYT_DIRECT_IRQ_EN) + /* nothing to do */ ; + else + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + + writel(value, reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); +} + +static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + u32 value, gpio_mux; + unsigned long flags; + + raw_spin_lock_irqsave(&byt_lock, flags); + + /* + * In most cases, func pin mux 000 means GPIO function. + * But, some pins may have func pin mux 001 represents + * GPIO function. + * + * Because there are devices out there where some pins were not + * configured correctly we allow changing the mux value from + * request (but print out warning about that). + */ + value = readl(reg) & BYT_PIN_MUX; + gpio_mux = byt_get_gpio_mux(vg, offset); + if (gpio_mux != value) { + value = readl(reg) & ~BYT_PIN_MUX; + value |= gpio_mux; + writel(value, reg); + + dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset); + } + + raw_spin_unlock_irqrestore(&byt_lock, flags); + + pm_runtime_get(vg->dev); + + return 0; +} + +static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); + + byt_gpio_clear_triggering(vg, offset); + pm_runtime_put(vg->dev); +} + +static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg, + unsigned int offset) +{ + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + + /* + * Before making any direction modifications, do a check if gpio is set + * for direct IRQ. On Bay Trail, setting GPIO to output does not make + * sense, so let's at least inform the caller before they shoot + * themselves in the foot. + */ + if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) + dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); +} + +static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, + struct pinctrl_gpio_range *range, + unsigned int offset, + bool input) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&byt_lock, flags); + + value = readl(val_reg); + value &= ~BYT_DIR_MASK; + if (input) + value |= BYT_OUTPUT_EN; + else + byt_gpio_direct_irq_check(vg, offset); + + writel(value, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + + return 0; +} + +static const struct pinmux_ops byt_pinmux_ops = { + .get_functions_count = byt_get_functions_count, + .get_function_name = byt_get_function_name, + .get_function_groups = byt_get_function_groups, + .set_mux = byt_set_mux, + .gpio_request_enable = byt_gpio_request_enable, + .gpio_disable_free = byt_gpio_disable_free, + .gpio_set_direction = byt_gpio_set_direction, +}; + +static void byt_get_pull_strength(u32 reg, u16 *strength) +{ + switch (reg & BYT_PULL_STR_MASK) { + case BYT_PULL_STR_2K: + *strength = 2000; + break; + case BYT_PULL_STR_10K: + *strength = 10000; + break; + case BYT_PULL_STR_20K: + *strength = 20000; + break; + case BYT_PULL_STR_40K: + *strength = 40000; + break; + } +} + +static int byt_set_pull_strength(u32 *reg, u16 strength) +{ + *reg &= ~BYT_PULL_STR_MASK; + + switch (strength) { + case 2000: + *reg |= BYT_PULL_STR_2K; + break; + case 10000: + *reg |= BYT_PULL_STR_10K; + break; + case 20000: + *reg |= BYT_PULL_STR_20K; + break; + case 40000: + *reg |= BYT_PULL_STR_40K; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, + unsigned long *config) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); + enum pin_config_param param = pinconf_to_config_param(*config); + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); + unsigned long flags; + u32 conf, pull, val, debounce; + u16 arg = 0; + + raw_spin_lock_irqsave(&byt_lock, flags); + conf = readl(conf_reg); + pull = conf & BYT_PULL_ASSIGN_MASK; + val = readl(val_reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (pull) + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + /* Pull assignment is only applicable in input mode */ + if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) + return -EINVAL; + + byt_get_pull_strength(conf, &arg); + + break; + case PIN_CONFIG_BIAS_PULL_UP: + /* Pull assignment is only applicable in input mode */ + if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) + return -EINVAL; + + byt_get_pull_strength(conf, &arg); + + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + if (!(conf & BYT_DEBOUNCE_EN)) + return -EINVAL; + + raw_spin_lock_irqsave(&byt_lock, flags); + debounce = readl(db_reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); + + switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { + case BYT_DEBOUNCE_PULSE_375US: + arg = 375; + break; + case BYT_DEBOUNCE_PULSE_750US: + arg = 750; + break; + case BYT_DEBOUNCE_PULSE_1500US: + arg = 1500; + break; + case BYT_DEBOUNCE_PULSE_3MS: + arg = 3000; + break; + case BYT_DEBOUNCE_PULSE_6MS: + arg = 6000; + break; + case BYT_DEBOUNCE_PULSE_12MS: + arg = 12000; + break; + case BYT_DEBOUNCE_PULSE_24MS: + arg = 24000; + break; + default: + return -EINVAL; + } + + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, + unsigned int offset, + unsigned long *configs, + unsigned int num_configs) +{ + struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); + unsigned int param, arg; + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); + unsigned long flags; + u32 conf, val, debounce; + int i, ret = 0; + + raw_spin_lock_irqsave(&byt_lock, flags); + + conf = readl(conf_reg); + val = readl(val_reg); + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + conf &= ~BYT_PULL_ASSIGN_MASK; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 2000; + + /* + * Pull assignment is only applicable in input mode. If + * chip is not in input mode, set it and warn about it. + */ + if (val & BYT_INPUT_EN) { + val &= ~BYT_INPUT_EN; + writel(val, val_reg); + dev_warn(vg->dev, + "pin %u forcibly set to input mode\n", + offset); + } + + conf &= ~BYT_PULL_ASSIGN_MASK; + conf |= BYT_PULL_ASSIGN_DOWN; + ret = byt_set_pull_strength(&conf, arg); + + break; + case PIN_CONFIG_BIAS_PULL_UP: + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 2000; + + /* + * Pull assignment is only applicable in input mode. If + * chip is not in input mode, set it and warn about it. + */ + if (val & BYT_INPUT_EN) { + val &= ~BYT_INPUT_EN; + writel(val, val_reg); + dev_warn(vg->dev, + "pin %u forcibly set to input mode\n", + offset); + } + + conf &= ~BYT_PULL_ASSIGN_MASK; + conf |= BYT_PULL_ASSIGN_UP; + ret = byt_set_pull_strength(&conf, arg); + + break; + case PIN_CONFIG_INPUT_DEBOUNCE: + debounce = readl(db_reg); + + if (arg) + conf |= BYT_DEBOUNCE_EN; + else + conf &= ~BYT_DEBOUNCE_EN; + + switch (arg) { + case 375: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_375US; + break; + case 750: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_750US; + break; + case 1500: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_1500US; + break; + case 3000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_3MS; + break; + case 6000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_6MS; + break; + case 12000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_12MS; + break; + case 24000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; + debounce |= BYT_DEBOUNCE_PULSE_24MS; + break; + default: + if (arg) + ret = -EINVAL; + break; + } + + if (!ret) + writel(debounce, db_reg); + break; + default: + ret = -ENOTSUPP; + } + + if (ret) + break; + } + + if (!ret) + writel(conf, conf_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + + return ret; +} + +static const struct pinconf_ops byt_pinconf_ops = { + .is_generic = true, + .pin_config_get = byt_pin_config_get, + .pin_config_set = byt_pin_config_set, +}; + +static const struct pinctrl_desc byt_pinctrl_desc = { + .pctlops = &byt_pinctrl_ops, + .pmxops = &byt_pinmux_ops, + .confops = &byt_pinconf_ops, + .owner = THIS_MODULE, +}; + +static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 val; + + raw_spin_lock_irqsave(&byt_lock, flags); + val = readl(reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); + + return !!(val & BYT_LEVEL); +} + +static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 old_val; + + if (!reg) + return; + + raw_spin_lock_irqsave(&byt_lock, flags); + old_val = readl(reg); + if (value) + writel(old_val | BYT_LEVEL, reg); + else + writel(old_val & ~BYT_LEVEL, reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); +} + +static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 value; + + if (!reg) + return -EINVAL; + + raw_spin_lock_irqsave(&byt_lock, flags); + value = readl(reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); + + if (!(value & BYT_OUTPUT_EN)) + return GPIO_LINE_DIRECTION_OUT; + if (!(value & BYT_INPUT_EN)) + return GPIO_LINE_DIRECTION_IN; + + return -EINVAL; +} + +static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; + + raw_spin_lock_irqsave(&byt_lock, flags); + + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + reg |= BYT_OUTPUT_EN; + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; +} + +/* + * Note despite the temptation this MUST NOT be converted into a call to + * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this + * MUST be done as a single BYT_VAL_REG register write. + * See the commit message of the commit adding this comment for details. + */ +static int byt_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; + + raw_spin_lock_irqsave(&byt_lock, flags); + + byt_gpio_direct_irq_check(vg, offset); + + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + if (value) + reg |= BYT_LEVEL; + else + reg &= ~BYT_LEVEL; + + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; +} + +static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + int i; + u32 conf0, val; + + for (i = 0; i < vg->soc->npins; i++) { + const struct intel_community *comm; + const char *pull_str = NULL; + const char *pull = NULL; + void __iomem *reg; + unsigned long flags; + const char *label; + unsigned int pin; + + raw_spin_lock_irqsave(&byt_lock, flags); + pin = vg->soc->pins[i].number; + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + seq_printf(s, + "Could not retrieve pin %i conf0 reg\n", + pin); + raw_spin_unlock_irqrestore(&byt_lock, flags); + continue; + } + conf0 = readl(reg); + + reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); + if (!reg) { + seq_printf(s, + "Could not retrieve pin %i val reg\n", pin); + raw_spin_unlock_irqrestore(&byt_lock, flags); + continue; + } + val = readl(reg); + raw_spin_unlock_irqrestore(&byt_lock, flags); + + comm = byt_get_community(vg, pin); + if (!comm) { + seq_printf(s, + "Could not get community for pin %i\n", pin); + continue; + } + label = gpiochip_is_requested(chip, i); + if (!label) + label = "Unrequested"; + + switch (conf0 & BYT_PULL_ASSIGN_MASK) { + case BYT_PULL_ASSIGN_UP: + pull = "up"; + break; + case BYT_PULL_ASSIGN_DOWN: + pull = "down"; + break; + } + + switch (conf0 & BYT_PULL_STR_MASK) { + case BYT_PULL_STR_2K: + pull_str = "2k"; + break; + case BYT_PULL_STR_10K: + pull_str = "10k"; + break; + case BYT_PULL_STR_20K: + pull_str = "20k"; + break; + case BYT_PULL_STR_40K: + pull_str = "40k"; + break; + } + + seq_printf(s, + " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", + pin, + label, + val & BYT_INPUT_EN ? " " : "in", + val & BYT_OUTPUT_EN ? " " : "out", + val & BYT_LEVEL ? "hi" : "lo", + comm->pad_map[i], comm->pad_map[i] * 16, + conf0 & 0x7, + conf0 & BYT_TRIG_NEG ? " fall" : " ", + conf0 & BYT_TRIG_POS ? " rise" : " ", + conf0 & BYT_TRIG_LVL ? " level" : " "); + + if (pull && pull_str) + seq_printf(s, " %-4s %-3s", pull, pull_str); + else + seq_puts(s, " "); + + if (conf0 & BYT_IODEN) + seq_puts(s, " open-drain"); + + seq_puts(s, "\n"); + } +} + +static const struct gpio_chip byt_gpio_chip = { + .owner = THIS_MODULE, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .get_direction = byt_gpio_get_direction, + .direction_input = byt_gpio_direction_input, + .direction_output = byt_gpio_direction_output, + .get = byt_gpio_get, + .set = byt_gpio_set, + .set_config = gpiochip_generic_config, + .dbg_show = byt_gpio_dbg_show, +}; + +static void byt_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *vg = gpiochip_get_data(gc); + unsigned int offset = irqd_to_hwirq(d); + void __iomem *reg; + + reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); + if (!reg) + return; + + raw_spin_lock(&byt_lock); + writel(BIT(offset % 32), reg); + raw_spin_unlock(&byt_lock); +} + +static void byt_irq_mask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *vg = gpiochip_get_data(gc); + + byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); +} + +static void byt_irq_unmask(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *vg = gpiochip_get_data(gc); + unsigned int offset = irqd_to_hwirq(d); + unsigned long flags; + void __iomem *reg; + u32 value; + + reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + if (!reg) + return; + + raw_spin_lock_irqsave(&byt_lock, flags); + value = readl(reg); + + switch (irqd_get_trigger_type(d)) { + case IRQ_TYPE_LEVEL_HIGH: + value |= BYT_TRIG_LVL; + fallthrough; + case IRQ_TYPE_EDGE_RISING: + value |= BYT_TRIG_POS; + break; + case IRQ_TYPE_LEVEL_LOW: + value |= BYT_TRIG_LVL; + fallthrough; + case IRQ_TYPE_EDGE_FALLING: + value |= BYT_TRIG_NEG; + break; + case IRQ_TYPE_EDGE_BOTH: + value |= (BYT_TRIG_NEG | BYT_TRIG_POS); + break; + } + + writel(value, reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); +} + +static int byt_irq_type(struct irq_data *d, unsigned int type) +{ + struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); + u32 offset = irqd_to_hwirq(d); + u32 value; + unsigned long flags; + void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + + if (!reg || offset >= vg->chip.ngpio) + return -EINVAL; + + raw_spin_lock_irqsave(&byt_lock, flags); + value = readl(reg); + + WARN(value & BYT_DIRECT_IRQ_EN, + "Bad pad config for io mode, force direct_irq_en bit clearing"); + + /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits + * are used to indicate high and low level triggering + */ + value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | + BYT_TRIG_LVL); + /* Enable glitch filtering */ + value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | + BYT_GLITCH_F_FAST_CLK; + + writel(value, reg); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + + return 0; +} + +static void byt_gpio_irq_handler(struct irq_desc *desc) +{ + struct irq_data *data = irq_desc_get_irq_data(desc); + struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc)); + struct irq_chip *chip = irq_data_get_irq_chip(data); + u32 base, pin; + void __iomem *reg; + unsigned long pending; + unsigned int virq; + + /* check from GPIO controller which pin triggered the interrupt */ + for (base = 0; base < vg->chip.ngpio; base += 32) { + reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); + + if (!reg) { + dev_warn(vg->dev, + "Pin %i: could not retrieve interrupt status register\n", + base); + continue; + } + + raw_spin_lock(&byt_lock); + pending = readl(reg); + raw_spin_unlock(&byt_lock); + for_each_set_bit(pin, &pending, 32) { + virq = irq_find_mapping(vg->chip.irq.domain, base + pin); + generic_handle_irq(virq); + } + } + chip->irq_eoi(data); +} + +static void byt_init_irq_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *reg; + u32 value; + int i; + + /* + * Clear interrupt triggers for all pins that are GPIOs and + * do not use direct IRQ mode. This will prevent spurious + * interrupts from misconfigured pins. + */ + for (i = 0; i < vg->soc->npins; i++) { + unsigned int pin = vg->soc->pins[i].number; + + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + dev_warn(vg->dev, + "Pin %i: could not retrieve conf0 register\n", + i); + continue; + } + + value = readl(reg); + if (value & BYT_DIRECT_IRQ_EN) { + clear_bit(i, valid_mask); + dev_dbg(vg->dev, "excluding GPIO %d from IRQ domain\n", i); + } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { + byt_gpio_clear_triggering(vg, i); + dev_dbg(vg->dev, "disabling GPIO %d\n", i); + } + } +} + +static int byt_gpio_irq_init_hw(struct gpio_chip *chip) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *reg; + u32 base, value; + + /* clear interrupt status trigger registers */ + for (base = 0; base < vg->soc->npins; base += 32) { + reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); + + if (!reg) { + dev_warn(vg->dev, + "Pin %i: could not retrieve irq status reg\n", + base); + continue; + } + + writel(0xffffffff, reg); + /* make sure trigger bits are cleared, if not then a pin + might be misconfigured in bios */ + value = readl(reg); + if (value) + dev_err(vg->dev, + "GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n", + base / 32, value); + } + + return 0; +} + +static int byt_gpio_add_pin_ranges(struct gpio_chip *chip) +{ + struct intel_pinctrl *vg = gpiochip_get_data(chip); + struct device *dev = vg->dev; + int ret; + + ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins); + if (ret) + dev_err(dev, "failed to add GPIO pin range\n"); + + return ret; +} + +static int byt_gpio_probe(struct intel_pinctrl *vg) +{ + struct platform_device *pdev = to_platform_device(vg->dev); + struct gpio_chip *gc; + int irq, ret; + + /* Set up gpio chip */ + vg->chip = byt_gpio_chip; + gc = &vg->chip; + gc->label = dev_name(vg->dev); + gc->base = -1; + gc->can_sleep = false; + gc->add_pin_ranges = byt_gpio_add_pin_ranges; + gc->parent = vg->dev; + gc->ngpio = vg->soc->npins; + +#ifdef CONFIG_PM_SLEEP + vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads), + GFP_KERNEL); + if (!vg->context.pads) + return -ENOMEM; +#endif + + /* set up interrupts */ + irq = platform_get_irq_optional(pdev, 0); + if (irq > 0) { + struct gpio_irq_chip *girq; + + vg->irqchip.name = "BYT-GPIO", + vg->irqchip.irq_ack = byt_irq_ack, + vg->irqchip.irq_mask = byt_irq_mask, + vg->irqchip.irq_unmask = byt_irq_unmask, + vg->irqchip.irq_set_type = byt_irq_type, + vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE, + + girq = &gc->irq; + girq->chip = &vg->irqchip; + girq->init_hw = byt_gpio_irq_init_hw; + girq->init_valid_mask = byt_init_irq_valid_mask; + girq->parent_handler = byt_gpio_irq_handler; + girq->num_parents = 1; + girq->parents = devm_kcalloc(vg->dev, girq->num_parents, + sizeof(*girq->parents), GFP_KERNEL); + if (!girq->parents) + return -ENOMEM; + girq->parents[0] = irq; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + } + + ret = devm_gpiochip_add_data(vg->dev, gc, vg); + if (ret) { + dev_err(vg->dev, "failed adding byt-gpio chip\n"); + return ret; + } + + return ret; +} + +static int byt_set_soc_data(struct intel_pinctrl *vg, + const struct intel_pinctrl_soc_data *soc) +{ + struct platform_device *pdev = to_platform_device(vg->dev); + int i; + + vg->soc = soc; + + vg->ncommunities = vg->soc->ncommunities; + vg->communities = devm_kcalloc(vg->dev, vg->ncommunities, + sizeof(*vg->communities), GFP_KERNEL); + if (!vg->communities) + return -ENOMEM; + + for (i = 0; i < vg->soc->ncommunities; i++) { + struct intel_community *comm = vg->communities + i; + + *comm = vg->soc->communities[i]; + + comm->pad_regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(comm->pad_regs)) + return PTR_ERR(comm->pad_regs); + } + + return 0; +} + +static const struct acpi_device_id byt_gpio_acpi_match[] = { + { "INT33B2", (kernel_ulong_t)byt_soc_data }, + { "INT33FC", (kernel_ulong_t)byt_soc_data }, + { } +}; + +static int byt_pinctrl_probe(struct platform_device *pdev) +{ + const struct intel_pinctrl_soc_data *soc_data; + struct device *dev = &pdev->dev; + struct intel_pinctrl *vg; + int ret; + + soc_data = intel_pinctrl_get_soc_data(pdev); + if (IS_ERR(soc_data)) + return PTR_ERR(soc_data); + + vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL); + if (!vg) + return -ENOMEM; + + vg->dev = dev; + ret = byt_set_soc_data(vg, soc_data); + if (ret) { + dev_err(dev, "failed to set soc data\n"); + return ret; + } + + vg->pctldesc = byt_pinctrl_desc; + vg->pctldesc.name = dev_name(dev); + vg->pctldesc.pins = vg->soc->pins; + vg->pctldesc.npins = vg->soc->npins; + + vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg); + if (IS_ERR(vg->pctldev)) { + dev_err(dev, "failed to register pinctrl driver\n"); + return PTR_ERR(vg->pctldev); + } + + ret = byt_gpio_probe(vg); + if (ret) + return ret; + + platform_set_drvdata(pdev, vg); + pm_runtime_enable(dev); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int byt_gpio_suspend(struct device *dev) +{ + struct intel_pinctrl *vg = dev_get_drvdata(dev); + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&byt_lock, flags); + + for (i = 0; i < vg->soc->npins; i++) { + void __iomem *reg; + u32 value; + unsigned int pin = vg->soc->pins[i].number; + + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + dev_warn(vg->dev, + "Pin %i: could not retrieve conf0 register\n", + i); + continue; + } + value = readl(reg) & BYT_CONF0_RESTORE_MASK; + vg->context.pads[i].conf0 = value; + + reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); + value = readl(reg) & BYT_VAL_RESTORE_MASK; + vg->context.pads[i].val = value; + } + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; +} + +static int byt_gpio_resume(struct device *dev) +{ + struct intel_pinctrl *vg = dev_get_drvdata(dev); + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&byt_lock, flags); + + for (i = 0; i < vg->soc->npins; i++) { + void __iomem *reg; + u32 value; + unsigned int pin = vg->soc->pins[i].number; + + reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); + if (!reg) { + dev_warn(vg->dev, + "Pin %i: could not retrieve conf0 register\n", + i); + continue; + } + value = readl(reg); + if ((value & BYT_CONF0_RESTORE_MASK) != + vg->context.pads[i].conf0) { + value &= ~BYT_CONF0_RESTORE_MASK; + value |= vg->context.pads[i].conf0; + writel(value, reg); + dev_info(dev, "restored pin %d conf0 %#08x", i, value); + } + + reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); + value = readl(reg); + if ((value & BYT_VAL_RESTORE_MASK) != + vg->context.pads[i].val) { + u32 v; + + v = value & ~BYT_VAL_RESTORE_MASK; + v |= vg->context.pads[i].val; + if (v != value) { + writel(v, reg); + dev_dbg(dev, "restored pin %d val %#08x\n", + i, v); + } + } + } + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; +} +#endif + +#ifdef CONFIG_PM +static int byt_gpio_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int byt_gpio_runtime_resume(struct device *dev) +{ + return 0; +} +#endif + +static const struct dev_pm_ops byt_gpio_pm_ops = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) + SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, + NULL) +}; + +static struct platform_driver byt_gpio_driver = { + .probe = byt_pinctrl_probe, + .driver = { + .name = "byt_gpio", + .pm = &byt_gpio_pm_ops, + .acpi_match_table = byt_gpio_acpi_match, + .suppress_bind_attrs = true, + }, +}; + +static int __init byt_gpio_init(void) +{ + return platform_driver_register(&byt_gpio_driver); +} +subsys_initcall(byt_gpio_init); diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c new file mode 100644 index 000000000..2be7e414f --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-broxton.c @@ -0,0 +1,1038 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Broxton SoC pinctrl/GPIO driver + * + * Copyright (C) 2015, 2016 Intel Corporation + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define BXT_PAD_OWN 0x020 +#define BXT_PADCFGLOCK 0x060 +#define BXT_HOSTSW_OWN 0x080 +#define BXT_GPI_IS 0x100 +#define BXT_GPI_IE 0x110 + +#define BXT_COMMUNITY(s, e) \ + { \ + .padown_offset = BXT_PAD_OWN, \ + .padcfglock_offset = BXT_PADCFGLOCK, \ + .hostown_offset = BXT_HOSTSW_OWN, \ + .is_offset = BXT_GPI_IS, \ + .ie_offset = BXT_GPI_IE, \ + .gpp_size = 32, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + } + +/* BXT */ +static const struct pinctrl_pin_desc bxt_north_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "PWM0"), + PINCTRL_PIN(35, "PWM1"), + PINCTRL_PIN(36, "PWM2"), + PINCTRL_PIN(37, "PWM3"), + PINCTRL_PIN(38, "LPSS_UART0_RXD"), + PINCTRL_PIN(39, "LPSS_UART0_TXD"), + PINCTRL_PIN(40, "LPSS_UART0_RTS_B"), + PINCTRL_PIN(41, "LPSS_UART0_CTS_B"), + PINCTRL_PIN(42, "LPSS_UART1_RXD"), + PINCTRL_PIN(43, "LPSS_UART1_TXD"), + PINCTRL_PIN(44, "LPSS_UART1_RTS_B"), + PINCTRL_PIN(45, "LPSS_UART1_CTS_B"), + PINCTRL_PIN(46, "LPSS_UART2_RXD"), + PINCTRL_PIN(47, "LPSS_UART2_TXD"), + PINCTRL_PIN(48, "LPSS_UART2_RTS_B"), + PINCTRL_PIN(49, "LPSS_UART2_CTS_B"), + PINCTRL_PIN(50, "ISH_UART0_RXD"), + PINCTRL_PIN(51, "ISH_UART0_TXT"), + PINCTRL_PIN(52, "ISH_UART0_RTS_B"), + PINCTRL_PIN(53, "ISH_UART0_CTS_B"), + PINCTRL_PIN(54, "ISH_UART1_RXD"), + PINCTRL_PIN(55, "ISH_UART1_TXT"), + PINCTRL_PIN(56, "ISH_UART1_RTS_B"), + PINCTRL_PIN(57, "ISH_UART1_CTS_B"), + PINCTRL_PIN(58, "ISH_UART2_RXD"), + PINCTRL_PIN(59, "ISH_UART2_TXD"), + PINCTRL_PIN(60, "ISH_UART2_RTS_B"), + PINCTRL_PIN(61, "ISH_UART2_CTS_B"), + PINCTRL_PIN(62, "GP_CAMERASB00"), + PINCTRL_PIN(63, "GP_CAMERASB01"), + PINCTRL_PIN(64, "GP_CAMERASB02"), + PINCTRL_PIN(65, "GP_CAMERASB03"), + PINCTRL_PIN(66, "GP_CAMERASB04"), + PINCTRL_PIN(67, "GP_CAMERASB05"), + PINCTRL_PIN(68, "GP_CAMERASB06"), + PINCTRL_PIN(69, "GP_CAMERASB07"), + PINCTRL_PIN(70, "GP_CAMERASB08"), + PINCTRL_PIN(71, "GP_CAMERASB09"), + PINCTRL_PIN(72, "GP_CAMERASB10"), + PINCTRL_PIN(73, "GP_CAMERASB11"), + PINCTRL_PIN(74, "TCK"), + PINCTRL_PIN(75, "TRST_B"), + PINCTRL_PIN(76, "TMS"), + PINCTRL_PIN(77, "TDI"), + PINCTRL_PIN(78, "CX_PMODE"), + PINCTRL_PIN(79, "CX_PREQ_B"), + PINCTRL_PIN(80, "JTAGX"), + PINCTRL_PIN(81, "CX_PRDY_B"), + PINCTRL_PIN(82, "TDO"), +}; + +static const unsigned int bxt_north_pwm0_pins[] = { 34 }; +static const unsigned int bxt_north_pwm1_pins[] = { 35 }; +static const unsigned int bxt_north_pwm2_pins[] = { 36 }; +static const unsigned int bxt_north_pwm3_pins[] = { 37 }; +static const unsigned int bxt_north_uart0_pins[] = { 38, 39, 40, 41 }; +static const unsigned int bxt_north_uart1_pins[] = { 42, 43, 44, 45 }; +static const unsigned int bxt_north_uart2_pins[] = { 46, 47, 48, 49 }; +static const unsigned int bxt_north_uart0b_pins[] = { 50, 51, 52, 53 }; +static const unsigned int bxt_north_uart1b_pins[] = { 54, 55, 56, 57 }; +static const unsigned int bxt_north_uart2b_pins[] = { 58, 59, 60, 61 }; +static const unsigned int bxt_north_uart3_pins[] = { 58, 59, 60, 61 }; + +static const struct intel_pingroup bxt_north_groups[] = { + PIN_GROUP("pwm0_grp", bxt_north_pwm0_pins, 1), + PIN_GROUP("pwm1_grp", bxt_north_pwm1_pins, 1), + PIN_GROUP("pwm2_grp", bxt_north_pwm2_pins, 1), + PIN_GROUP("pwm3_grp", bxt_north_pwm3_pins, 1), + PIN_GROUP("uart0_grp", bxt_north_uart0_pins, 1), + PIN_GROUP("uart1_grp", bxt_north_uart1_pins, 1), + PIN_GROUP("uart2_grp", bxt_north_uart2_pins, 1), + PIN_GROUP("uart0b_grp", bxt_north_uart0b_pins, 2), + PIN_GROUP("uart1b_grp", bxt_north_uart1b_pins, 2), + PIN_GROUP("uart2b_grp", bxt_north_uart2b_pins, 2), + PIN_GROUP("uart3_grp", bxt_north_uart3_pins, 3), +}; + +static const char * const bxt_north_pwm0_groups[] = { "pwm0_grp" }; +static const char * const bxt_north_pwm1_groups[] = { "pwm1_grp" }; +static const char * const bxt_north_pwm2_groups[] = { "pwm2_grp" }; +static const char * const bxt_north_pwm3_groups[] = { "pwm3_grp" }; +static const char * const bxt_north_uart0_groups[] = { + "uart0_grp", "uart0b_grp", +}; +static const char * const bxt_north_uart1_groups[] = { + "uart1_grp", "uart1b_grp", +}; +static const char * const bxt_north_uart2_groups[] = { + "uart2_grp", "uart2b_grp", +}; +static const char * const bxt_north_uart3_groups[] = { "uart3_grp" }; + +static const struct intel_function bxt_north_functions[] = { + FUNCTION("pwm0", bxt_north_pwm0_groups), + FUNCTION("pwm1", bxt_north_pwm1_groups), + FUNCTION("pwm2", bxt_north_pwm2_groups), + FUNCTION("pwm3", bxt_north_pwm3_groups), + FUNCTION("uart0", bxt_north_uart0_groups), + FUNCTION("uart1", bxt_north_uart1_groups), + FUNCTION("uart2", bxt_north_uart2_groups), + FUNCTION("uart3", bxt_north_uart3_groups), +}; + +static const struct intel_community bxt_north_communities[] = { + BXT_COMMUNITY(0, 82), +}; + +static const struct intel_pinctrl_soc_data bxt_north_soc_data = { + .uid = "1", + .pins = bxt_north_pins, + .npins = ARRAY_SIZE(bxt_north_pins), + .groups = bxt_north_groups, + .ngroups = ARRAY_SIZE(bxt_north_groups), + .functions = bxt_north_functions, + .nfunctions = ARRAY_SIZE(bxt_north_functions), + .communities = bxt_north_communities, + .ncommunities = ARRAY_SIZE(bxt_north_communities), +}; + +static const struct pinctrl_pin_desc bxt_northwest_pins[] = { + PINCTRL_PIN(0, "PMC_SPI_FS0"), + PINCTRL_PIN(1, "PMC_SPI_FS1"), + PINCTRL_PIN(2, "PMC_SPI_FS2"), + PINCTRL_PIN(3, "PMC_SPI_RXD"), + PINCTRL_PIN(4, "PMC_SPI_TXD"), + PINCTRL_PIN(5, "PMC_SPI_CLK"), + PINCTRL_PIN(6, "PMC_UART_RXD"), + PINCTRL_PIN(7, "PMC_UART_TXD"), + PINCTRL_PIN(8, "PMIC_PWRGOOD"), + PINCTRL_PIN(9, "PMIC_RESET_B"), + PINCTRL_PIN(10, "RTC_CLK"), + PINCTRL_PIN(11, "PMIC_SDWN_B"), + PINCTRL_PIN(12, "PMIC_BCUDISW2"), + PINCTRL_PIN(13, "PMIC_BCUDISCRIT"), + PINCTRL_PIN(14, "PMIC_THERMTRIP_B"), + PINCTRL_PIN(15, "PMIC_STDBY"), + PINCTRL_PIN(16, "SVID0_ALERT_B"), + PINCTRL_PIN(17, "SVID0_DATA"), + PINCTRL_PIN(18, "SVID0_CLK"), + PINCTRL_PIN(19, "PMIC_I2C_SCL"), + PINCTRL_PIN(20, "PMIC_I2C_SDA"), + PINCTRL_PIN(21, "AVS_I2S1_MCLK"), + PINCTRL_PIN(22, "AVS_I2S1_BCLK"), + PINCTRL_PIN(23, "AVS_I2S1_WS_SYNC"), + PINCTRL_PIN(24, "AVS_I2S1_SDI"), + PINCTRL_PIN(25, "AVS_I2S1_SDO"), + PINCTRL_PIN(26, "AVS_M_CLK_A1"), + PINCTRL_PIN(27, "AVS_M_CLK_B1"), + PINCTRL_PIN(28, "AVS_M_DATA_1"), + PINCTRL_PIN(29, "AVS_M_CLK_AB2"), + PINCTRL_PIN(30, "AVS_M_DATA_2"), + PINCTRL_PIN(31, "AVS_I2S2_MCLK"), + PINCTRL_PIN(32, "AVS_I2S2_BCLK"), + PINCTRL_PIN(33, "AVS_I2S2_WS_SYNC"), + PINCTRL_PIN(34, "AVS_I2S2_SDI"), + PINCTRL_PIN(35, "AVS_I2S2_SDOK"), + PINCTRL_PIN(36, "AVS_I2S3_BCLK"), + PINCTRL_PIN(37, "AVS_I2S3_WS_SYNC"), + PINCTRL_PIN(38, "AVS_I2S3_SDI"), + PINCTRL_PIN(39, "AVS_I2S3_SDO"), + PINCTRL_PIN(40, "AVS_I2S4_BCLK"), + PINCTRL_PIN(41, "AVS_I2S4_WS_SYNC"), + PINCTRL_PIN(42, "AVS_I2S4_SDI"), + PINCTRL_PIN(43, "AVS_I2S4_SDO"), + PINCTRL_PIN(44, "PROCHOT_B"), + PINCTRL_PIN(45, "FST_SPI_CS0_B"), + PINCTRL_PIN(46, "FST_SPI_CS1_B"), + PINCTRL_PIN(47, "FST_SPI_MOSI_IO0"), + PINCTRL_PIN(48, "FST_SPI_MISO_IO1"), + PINCTRL_PIN(49, "FST_SPI_IO2"), + PINCTRL_PIN(50, "FST_SPI_IO3"), + PINCTRL_PIN(51, "FST_SPI_CLK"), + PINCTRL_PIN(52, "FST_SPI_CLK_FB"), + PINCTRL_PIN(53, "GP_SSP_0_CLK"), + PINCTRL_PIN(54, "GP_SSP_0_FS0"), + PINCTRL_PIN(55, "GP_SSP_0_FS1"), + PINCTRL_PIN(56, "GP_SSP_0_FS2"), + PINCTRL_PIN(57, "GP_SSP_0_RXD"), + PINCTRL_PIN(58, "GP_SSP_0_TXD"), + PINCTRL_PIN(59, "GP_SSP_1_CLK"), + PINCTRL_PIN(60, "GP_SSP_1_FS0"), + PINCTRL_PIN(61, "GP_SSP_1_FS1"), + PINCTRL_PIN(62, "GP_SSP_1_FS2"), + PINCTRL_PIN(63, "GP_SSP_1_FS3"), + PINCTRL_PIN(64, "GP_SSP_1_RXD"), + PINCTRL_PIN(65, "GP_SSP_1_TXD"), + PINCTRL_PIN(66, "GP_SSP_2_CLK"), + PINCTRL_PIN(67, "GP_SSP_2_FS0"), + PINCTRL_PIN(68, "GP_SSP_2_FS1"), + PINCTRL_PIN(69, "GP_SSP_2_FS2"), + PINCTRL_PIN(70, "GP_SSP_2_RXD"), + PINCTRL_PIN(71, "GP_SSP_2_TXD"), +}; + +static const unsigned int bxt_northwest_ssp0_pins[] = { 53, 54, 55, 56, 57, 58 }; +static const unsigned int bxt_northwest_ssp1_pins[] = { + 59, 60, 61, 62, 63, 64, 65 +}; +static const unsigned int bxt_northwest_ssp2_pins[] = { 66, 67, 68, 69, 70, 71 }; +static const unsigned int bxt_northwest_uart3_pins[] = { 67, 68, 69, 70 }; + +static const struct intel_pingroup bxt_northwest_groups[] = { + PIN_GROUP("ssp0_grp", bxt_northwest_ssp0_pins, 1), + PIN_GROUP("ssp1_grp", bxt_northwest_ssp1_pins, 1), + PIN_GROUP("ssp2_grp", bxt_northwest_ssp2_pins, 1), + PIN_GROUP("uart3_grp", bxt_northwest_uart3_pins, 2), +}; + +static const char * const bxt_northwest_ssp0_groups[] = { "ssp0_grp" }; +static const char * const bxt_northwest_ssp1_groups[] = { "ssp1_grp" }; +static const char * const bxt_northwest_ssp2_groups[] = { "ssp2_grp" }; +static const char * const bxt_northwest_uart3_groups[] = { "uart3_grp" }; + +static const struct intel_function bxt_northwest_functions[] = { + FUNCTION("ssp0", bxt_northwest_ssp0_groups), + FUNCTION("ssp1", bxt_northwest_ssp1_groups), + FUNCTION("ssp2", bxt_northwest_ssp2_groups), + FUNCTION("uart3", bxt_northwest_uart3_groups), +}; + +static const struct intel_community bxt_northwest_communities[] = { + BXT_COMMUNITY(0, 71), +}; + +static const struct intel_pinctrl_soc_data bxt_northwest_soc_data = { + .uid = "2", + .pins = bxt_northwest_pins, + .npins = ARRAY_SIZE(bxt_northwest_pins), + .groups = bxt_northwest_groups, + .ngroups = ARRAY_SIZE(bxt_northwest_groups), + .functions = bxt_northwest_functions, + .nfunctions = ARRAY_SIZE(bxt_northwest_functions), + .communities = bxt_northwest_communities, + .ncommunities = ARRAY_SIZE(bxt_northwest_communities), +}; + +static const struct pinctrl_pin_desc bxt_west_pins[] = { + PINCTRL_PIN(0, "LPSS_I2C0_SDA"), + PINCTRL_PIN(1, "LPSS_I2C0_SCL"), + PINCTRL_PIN(2, "LPSS_I2C1_SDA"), + PINCTRL_PIN(3, "LPSS_I2C1_SCL"), + PINCTRL_PIN(4, "LPSS_I2C2_SDA"), + PINCTRL_PIN(5, "LPSS_I2C2_SCL"), + PINCTRL_PIN(6, "LPSS_I2C3_SDA"), + PINCTRL_PIN(7, "LPSS_I2C3_SCL"), + PINCTRL_PIN(8, "LPSS_I2C4_SDA"), + PINCTRL_PIN(9, "LPSS_I2C4_SCL"), + PINCTRL_PIN(10, "LPSS_I2C5_SDA"), + PINCTRL_PIN(11, "LPSS_I2C5_SCL"), + PINCTRL_PIN(12, "LPSS_I2C6_SDA"), + PINCTRL_PIN(13, "LPSS_I2C6_SCL"), + PINCTRL_PIN(14, "LPSS_I2C7_SDA"), + PINCTRL_PIN(15, "LPSS_I2C7_SCL"), + PINCTRL_PIN(16, "ISH_I2C0_SDA"), + PINCTRL_PIN(17, "ISH_I2C0_SCL"), + PINCTRL_PIN(18, "ISH_I2C1_SDA"), + PINCTRL_PIN(19, "ISH_I2C1_SCL"), + PINCTRL_PIN(20, "ISH_I2C2_SDA"), + PINCTRL_PIN(21, "ISH_I2C2_SCL"), + PINCTRL_PIN(22, "ISH_GPIO_0"), + PINCTRL_PIN(23, "ISH_GPIO_1"), + PINCTRL_PIN(24, "ISH_GPIO_2"), + PINCTRL_PIN(25, "ISH_GPIO_3"), + PINCTRL_PIN(26, "ISH_GPIO_4"), + PINCTRL_PIN(27, "ISH_GPIO_5"), + PINCTRL_PIN(28, "ISH_GPIO_6"), + PINCTRL_PIN(29, "ISH_GPIO_7"), + PINCTRL_PIN(30, "ISH_GPIO_8"), + PINCTRL_PIN(31, "ISH_GPIO_9"), + PINCTRL_PIN(32, "MODEM_CLKREQ"), + PINCTRL_PIN(33, "DGCLKDBG_PMC_0"), + PINCTRL_PIN(34, "DGCLKDBG_PMC_1"), + PINCTRL_PIN(35, "DGCLKDBG_PMC_2"), + PINCTRL_PIN(36, "DGCLKDBG_ICLK_0"), + PINCTRL_PIN(37, "DGCLKDBG_ICLK_1"), + PINCTRL_PIN(38, "OSC_CLK_OUT_0"), + PINCTRL_PIN(39, "OSC_CLK_OUT_1"), + PINCTRL_PIN(40, "OSC_CLK_OUT_2"), + PINCTRL_PIN(41, "OSC_CLK_OUT_3"), +}; + +static const unsigned int bxt_west_i2c0_pins[] = { 0, 1 }; +static const unsigned int bxt_west_i2c1_pins[] = { 2, 3 }; +static const unsigned int bxt_west_i2c2_pins[] = { 4, 5 }; +static const unsigned int bxt_west_i2c3_pins[] = { 6, 7 }; +static const unsigned int bxt_west_i2c4_pins[] = { 8, 9 }; +static const unsigned int bxt_west_i2c5_pins[] = { 10, 11 }; +static const unsigned int bxt_west_i2c6_pins[] = { 12, 13 }; +static const unsigned int bxt_west_i2c7_pins[] = { 14, 15 }; +static const unsigned int bxt_west_i2c5b_pins[] = { 16, 17 }; +static const unsigned int bxt_west_i2c6b_pins[] = { 18, 19 }; +static const unsigned int bxt_west_i2c7b_pins[] = { 20, 21 }; + +static const struct intel_pingroup bxt_west_groups[] = { + PIN_GROUP("i2c0_grp", bxt_west_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", bxt_west_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", bxt_west_i2c2_pins, 1), + PIN_GROUP("i2c3_grp", bxt_west_i2c3_pins, 1), + PIN_GROUP("i2c4_grp", bxt_west_i2c4_pins, 1), + PIN_GROUP("i2c5_grp", bxt_west_i2c5_pins, 1), + PIN_GROUP("i2c6_grp", bxt_west_i2c6_pins, 1), + PIN_GROUP("i2c7_grp", bxt_west_i2c7_pins, 1), + PIN_GROUP("i2c5b_grp", bxt_west_i2c5b_pins, 2), + PIN_GROUP("i2c6b_grp", bxt_west_i2c6b_pins, 2), + PIN_GROUP("i2c7b_grp", bxt_west_i2c7b_pins, 2), +}; + +static const char * const bxt_west_i2c0_groups[] = { "i2c0_grp" }; +static const char * const bxt_west_i2c1_groups[] = { "i2c1_grp" }; +static const char * const bxt_west_i2c2_groups[] = { "i2c2_grp" }; +static const char * const bxt_west_i2c3_groups[] = { "i2c3_grp" }; +static const char * const bxt_west_i2c4_groups[] = { "i2c4_grp" }; +static const char * const bxt_west_i2c5_groups[] = { "i2c5_grp", "i2c5b_grp" }; +static const char * const bxt_west_i2c6_groups[] = { "i2c6_grp", "i2c6b_grp" }; +static const char * const bxt_west_i2c7_groups[] = { "i2c7_grp", "i2c7b_grp" }; + +static const struct intel_function bxt_west_functions[] = { + FUNCTION("i2c0", bxt_west_i2c0_groups), + FUNCTION("i2c1", bxt_west_i2c1_groups), + FUNCTION("i2c2", bxt_west_i2c2_groups), + FUNCTION("i2c3", bxt_west_i2c3_groups), + FUNCTION("i2c4", bxt_west_i2c4_groups), + FUNCTION("i2c5", bxt_west_i2c5_groups), + FUNCTION("i2c6", bxt_west_i2c6_groups), + FUNCTION("i2c7", bxt_west_i2c7_groups), +}; + +static const struct intel_community bxt_west_communities[] = { + BXT_COMMUNITY(0, 41), +}; + +static const struct intel_pinctrl_soc_data bxt_west_soc_data = { + .uid = "3", + .pins = bxt_west_pins, + .npins = ARRAY_SIZE(bxt_west_pins), + .groups = bxt_west_groups, + .ngroups = ARRAY_SIZE(bxt_west_groups), + .functions = bxt_west_functions, + .nfunctions = ARRAY_SIZE(bxt_west_functions), + .communities = bxt_west_communities, + .ncommunities = ARRAY_SIZE(bxt_west_communities), +}; + +static const struct pinctrl_pin_desc bxt_southwest_pins[] = { + PINCTRL_PIN(0, "EMMC0_CLK"), + PINCTRL_PIN(1, "EMMC0_D0"), + PINCTRL_PIN(2, "EMMC0_D1"), + PINCTRL_PIN(3, "EMMC0_D2"), + PINCTRL_PIN(4, "EMMC0_D3"), + PINCTRL_PIN(5, "EMMC0_D4"), + PINCTRL_PIN(6, "EMMC0_D5"), + PINCTRL_PIN(7, "EMMC0_D6"), + PINCTRL_PIN(8, "EMMC0_D7"), + PINCTRL_PIN(9, "EMMC0_CMD"), + PINCTRL_PIN(10, "SDIO_CLK"), + PINCTRL_PIN(11, "SDIO_D0"), + PINCTRL_PIN(12, "SDIO_D1"), + PINCTRL_PIN(13, "SDIO_D2"), + PINCTRL_PIN(14, "SDIO_D3"), + PINCTRL_PIN(15, "SDIO_CMD"), + PINCTRL_PIN(16, "SDCARD_CLK"), + PINCTRL_PIN(17, "SDCARD_D0"), + PINCTRL_PIN(18, "SDCARD_D1"), + PINCTRL_PIN(19, "SDCARD_D2"), + PINCTRL_PIN(20, "SDCARD_D3"), + PINCTRL_PIN(21, "SDCARD_CD_B"), + PINCTRL_PIN(22, "SDCARD_CMD"), + PINCTRL_PIN(23, "SDCARD_LVL_CLK_FB"), + PINCTRL_PIN(24, "SDCARD_LVL_CMD_DIR"), + PINCTRL_PIN(25, "SDCARD_LVL_DAT_DIR"), + PINCTRL_PIN(26, "EMMC0_STROBE"), + PINCTRL_PIN(27, "SDIO_PWR_DOWN_B"), + PINCTRL_PIN(28, "SDCARD_PWR_DOWN_B"), + PINCTRL_PIN(29, "SDCARD_LVL_SEL"), + PINCTRL_PIN(30, "SDCARD_LVL_WP"), +}; + +static const unsigned int bxt_southwest_emmc0_pins[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 26, +}; +static const unsigned int bxt_southwest_sdio_pins[] = { + 10, 11, 12, 13, 14, 15, 27, +}; +static const unsigned int bxt_southwest_sdcard_pins[] = { + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, +}; + +static const struct intel_pingroup bxt_southwest_groups[] = { + PIN_GROUP("emmc0_grp", bxt_southwest_emmc0_pins, 1), + PIN_GROUP("sdio_grp", bxt_southwest_sdio_pins, 1), + PIN_GROUP("sdcard_grp", bxt_southwest_sdcard_pins, 1), +}; + +static const char * const bxt_southwest_emmc0_groups[] = { "emmc0_grp" }; +static const char * const bxt_southwest_sdio_groups[] = { "sdio_grp" }; +static const char * const bxt_southwest_sdcard_groups[] = { "sdcard_grp" }; + +static const struct intel_function bxt_southwest_functions[] = { + FUNCTION("emmc0", bxt_southwest_emmc0_groups), + FUNCTION("sdio", bxt_southwest_sdio_groups), + FUNCTION("sdcard", bxt_southwest_sdcard_groups), +}; + +static const struct intel_community bxt_southwest_communities[] = { + BXT_COMMUNITY(0, 30), +}; + +static const struct intel_pinctrl_soc_data bxt_southwest_soc_data = { + .uid = "4", + .pins = bxt_southwest_pins, + .npins = ARRAY_SIZE(bxt_southwest_pins), + .groups = bxt_southwest_groups, + .ngroups = ARRAY_SIZE(bxt_southwest_groups), + .functions = bxt_southwest_functions, + .nfunctions = ARRAY_SIZE(bxt_southwest_functions), + .communities = bxt_southwest_communities, + .ncommunities = ARRAY_SIZE(bxt_southwest_communities), +}; + +static const struct pinctrl_pin_desc bxt_south_pins[] = { + PINCTRL_PIN(0, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(1, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(2, "HV_DDI1_DDC_SDA"), + PINCTRL_PIN(3, "HV_DDI1_DDC_SCL"), + PINCTRL_PIN(4, "DBI_SDA"), + PINCTRL_PIN(5, "DBI_SCL"), + PINCTRL_PIN(6, "PANEL0_VDDEN"), + PINCTRL_PIN(7, "PANEL0_BKLTEN"), + PINCTRL_PIN(8, "PANEL0_BKLTCTL"), + PINCTRL_PIN(9, "PANEL1_VDDEN"), + PINCTRL_PIN(10, "PANEL1_BKLTEN"), + PINCTRL_PIN(11, "PANEL1_BKLTCTL"), + PINCTRL_PIN(12, "DBI_CSX"), + PINCTRL_PIN(13, "DBI_RESX"), + PINCTRL_PIN(14, "GP_INTD_DSI_TE1"), + PINCTRL_PIN(15, "GP_INTD_DSI_TE2"), + PINCTRL_PIN(16, "USB_OC0_B"), + PINCTRL_PIN(17, "USB_OC1_B"), + PINCTRL_PIN(18, "MEX_WAKE0_B"), + PINCTRL_PIN(19, "MEX_WAKE1_B"), +}; + +static const struct intel_community bxt_south_communities[] = { + BXT_COMMUNITY(0, 19), +}; + +static const struct intel_pinctrl_soc_data bxt_south_soc_data = { + .uid = "5", + .pins = bxt_south_pins, + .npins = ARRAY_SIZE(bxt_south_pins), + .communities = bxt_south_communities, + .ncommunities = ARRAY_SIZE(bxt_south_communities), +}; + +static const struct intel_pinctrl_soc_data *bxt_pinctrl_soc_data[] = { + &bxt_north_soc_data, + &bxt_northwest_soc_data, + &bxt_west_soc_data, + &bxt_southwest_soc_data, + &bxt_south_soc_data, + NULL +}; + +/* APL */ +static const struct pinctrl_pin_desc apl_north_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "PWM0"), + PINCTRL_PIN(35, "PWM1"), + PINCTRL_PIN(36, "PWM2"), + PINCTRL_PIN(37, "PWM3"), + PINCTRL_PIN(38, "LPSS_UART0_RXD"), + PINCTRL_PIN(39, "LPSS_UART0_TXD"), + PINCTRL_PIN(40, "LPSS_UART0_RTS_B"), + PINCTRL_PIN(41, "LPSS_UART0_CTS_B"), + PINCTRL_PIN(42, "LPSS_UART1_RXD"), + PINCTRL_PIN(43, "LPSS_UART1_TXD"), + PINCTRL_PIN(44, "LPSS_UART1_RTS_B"), + PINCTRL_PIN(45, "LPSS_UART1_CTS_B"), + PINCTRL_PIN(46, "LPSS_UART2_RXD"), + PINCTRL_PIN(47, "LPSS_UART2_TXD"), + PINCTRL_PIN(48, "LPSS_UART2_RTS_B"), + PINCTRL_PIN(49, "LPSS_UART2_CTS_B"), + PINCTRL_PIN(50, "GP_CAMERASB00"), + PINCTRL_PIN(51, "GP_CAMERASB01"), + PINCTRL_PIN(52, "GP_CAMERASB02"), + PINCTRL_PIN(53, "GP_CAMERASB03"), + PINCTRL_PIN(54, "GP_CAMERASB04"), + PINCTRL_PIN(55, "GP_CAMERASB05"), + PINCTRL_PIN(56, "GP_CAMERASB06"), + PINCTRL_PIN(57, "GP_CAMERASB07"), + PINCTRL_PIN(58, "GP_CAMERASB08"), + PINCTRL_PIN(59, "GP_CAMERASB09"), + PINCTRL_PIN(60, "GP_CAMERASB10"), + PINCTRL_PIN(61, "GP_CAMERASB11"), + PINCTRL_PIN(62, "TCK"), + PINCTRL_PIN(63, "TRST_B"), + PINCTRL_PIN(64, "TMS"), + PINCTRL_PIN(65, "TDI"), + PINCTRL_PIN(66, "CX_PMODE"), + PINCTRL_PIN(67, "CX_PREQ_B"), + PINCTRL_PIN(68, "JTAGX"), + PINCTRL_PIN(69, "CX_PRDY_B"), + PINCTRL_PIN(70, "TDO"), + PINCTRL_PIN(71, "CNV_BRI_DT"), + PINCTRL_PIN(72, "CNV_BRI_RSP"), + PINCTRL_PIN(73, "CNV_RGI_DT"), + PINCTRL_PIN(74, "CNV_RGI_RSP"), + PINCTRL_PIN(75, "SVID0_ALERT_B"), + PINCTRL_PIN(76, "SVID0_DATA"), + PINCTRL_PIN(77, "SVID0_CLK"), +}; + +static const unsigned int apl_north_pwm0_pins[] = { 34 }; +static const unsigned int apl_north_pwm1_pins[] = { 35 }; +static const unsigned int apl_north_pwm2_pins[] = { 36 }; +static const unsigned int apl_north_pwm3_pins[] = { 37 }; +static const unsigned int apl_north_uart0_pins[] = { 38, 39, 40, 41 }; +static const unsigned int apl_north_uart1_pins[] = { 42, 43, 44, 45 }; +static const unsigned int apl_north_uart2_pins[] = { 46, 47, 48, 49 }; + +static const struct intel_pingroup apl_north_groups[] = { + PIN_GROUP("pwm0_grp", apl_north_pwm0_pins, 1), + PIN_GROUP("pwm1_grp", apl_north_pwm1_pins, 1), + PIN_GROUP("pwm2_grp", apl_north_pwm2_pins, 1), + PIN_GROUP("pwm3_grp", apl_north_pwm3_pins, 1), + PIN_GROUP("uart0_grp", apl_north_uart0_pins, 1), + PIN_GROUP("uart1_grp", apl_north_uart1_pins, 1), + PIN_GROUP("uart2_grp", apl_north_uart2_pins, 1), +}; + +static const char * const apl_north_pwm0_groups[] = { "pwm0_grp" }; +static const char * const apl_north_pwm1_groups[] = { "pwm1_grp" }; +static const char * const apl_north_pwm2_groups[] = { "pwm2_grp" }; +static const char * const apl_north_pwm3_groups[] = { "pwm3_grp" }; +static const char * const apl_north_uart0_groups[] = { "uart0_grp" }; +static const char * const apl_north_uart1_groups[] = { "uart1_grp" }; +static const char * const apl_north_uart2_groups[] = { "uart2_grp" }; + +static const struct intel_function apl_north_functions[] = { + FUNCTION("pwm0", apl_north_pwm0_groups), + FUNCTION("pwm1", apl_north_pwm1_groups), + FUNCTION("pwm2", apl_north_pwm2_groups), + FUNCTION("pwm3", apl_north_pwm3_groups), + FUNCTION("uart0", apl_north_uart0_groups), + FUNCTION("uart1", apl_north_uart1_groups), + FUNCTION("uart2", apl_north_uart2_groups), +}; + +static const struct intel_community apl_north_communities[] = { + BXT_COMMUNITY(0, 77), +}; + +static const struct intel_pinctrl_soc_data apl_north_soc_data = { + .uid = "1", + .pins = apl_north_pins, + .npins = ARRAY_SIZE(apl_north_pins), + .groups = apl_north_groups, + .ngroups = ARRAY_SIZE(apl_north_groups), + .functions = apl_north_functions, + .nfunctions = ARRAY_SIZE(apl_north_functions), + .communities = apl_north_communities, + .ncommunities = ARRAY_SIZE(apl_north_communities), +}; + +static const struct pinctrl_pin_desc apl_northwest_pins[] = { + PINCTRL_PIN(0, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(1, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(2, "HV_DDI1_DDC_SDA"), + PINCTRL_PIN(3, "HV_DDI1_DDC_SCL"), + PINCTRL_PIN(4, "DBI_SDA"), + PINCTRL_PIN(5, "DBI_SCL"), + PINCTRL_PIN(6, "PANEL0_VDDEN"), + PINCTRL_PIN(7, "PANEL0_BKLTEN"), + PINCTRL_PIN(8, "PANEL0_BKLTCTL"), + PINCTRL_PIN(9, "PANEL1_VDDEN"), + PINCTRL_PIN(10, "PANEL1_BKLTEN"), + PINCTRL_PIN(11, "PANEL1_BKLTCTL"), + PINCTRL_PIN(12, "DBI_CSX"), + PINCTRL_PIN(13, "DBI_RESX"), + PINCTRL_PIN(14, "GP_INTD_DSI_TE1"), + PINCTRL_PIN(15, "GP_INTD_DSI_TE2"), + PINCTRL_PIN(16, "USB_OC0_B"), + PINCTRL_PIN(17, "USB_OC1_B"), + PINCTRL_PIN(18, "PMC_SPI_FS0"), + PINCTRL_PIN(19, "PMC_SPI_FS1"), + PINCTRL_PIN(20, "PMC_SPI_FS2"), + PINCTRL_PIN(21, "PMC_SPI_RXD"), + PINCTRL_PIN(22, "PMC_SPI_TXD"), + PINCTRL_PIN(23, "PMC_SPI_CLK"), + PINCTRL_PIN(24, "PMIC_PWRGOOD"), + PINCTRL_PIN(25, "PMIC_RESET_B"), + PINCTRL_PIN(26, "PMIC_SDWN_B"), + PINCTRL_PIN(27, "PMIC_BCUDISW2"), + PINCTRL_PIN(28, "PMIC_BCUDISCRIT"), + PINCTRL_PIN(29, "PMIC_THERMTRIP_B"), + PINCTRL_PIN(30, "PMIC_STDBY"), + PINCTRL_PIN(31, "PROCHOT_B"), + PINCTRL_PIN(32, "PMIC_I2C_SCL"), + PINCTRL_PIN(33, "PMIC_I2C_SDA"), + PINCTRL_PIN(34, "AVS_I2S1_MCLK"), + PINCTRL_PIN(35, "AVS_I2S1_BCLK"), + PINCTRL_PIN(36, "AVS_I2S1_WS_SYNC"), + PINCTRL_PIN(37, "AVS_I2S1_SDI"), + PINCTRL_PIN(38, "AVS_I2S1_SDO"), + PINCTRL_PIN(39, "AVS_M_CLK_A1"), + PINCTRL_PIN(40, "AVS_M_CLK_B1"), + PINCTRL_PIN(41, "AVS_M_DATA_1"), + PINCTRL_PIN(42, "AVS_M_CLK_AB2"), + PINCTRL_PIN(43, "AVS_M_DATA_2"), + PINCTRL_PIN(44, "AVS_I2S2_MCLK"), + PINCTRL_PIN(45, "AVS_I2S2_BCLK"), + PINCTRL_PIN(46, "AVS_I2S2_WS_SYNC"), + PINCTRL_PIN(47, "AVS_I2S2_SDI"), + PINCTRL_PIN(48, "AVS_I2S2_SDO"), + PINCTRL_PIN(49, "AVS_I2S3_BCLK"), + PINCTRL_PIN(50, "AVS_I2S3_WS_SYNC"), + PINCTRL_PIN(51, "AVS_I2S3_SDI"), + PINCTRL_PIN(52, "AVS_I2S3_SDO"), + PINCTRL_PIN(53, "FST_SPI_CS0_B"), + PINCTRL_PIN(54, "FST_SPI_CS1_B"), + PINCTRL_PIN(55, "FST_SPI_MOSI_IO0"), + PINCTRL_PIN(56, "FST_SPI_MISO_IO1"), + PINCTRL_PIN(57, "FST_SPI_IO2"), + PINCTRL_PIN(58, "FST_SPI_IO3"), + PINCTRL_PIN(59, "FST_SPI_CLK"), + PINCTRL_PIN(60, "FST_SPI_CLK_FB"), + PINCTRL_PIN(61, "GP_SSP_0_CLK"), + PINCTRL_PIN(62, "GP_SSP_0_FS0"), + PINCTRL_PIN(63, "GP_SSP_0_FS1"), + PINCTRL_PIN(64, "GP_SSP_0_RXD"), + PINCTRL_PIN(65, "GP_SSP_0_TXD"), + PINCTRL_PIN(66, "GP_SSP_1_CLK"), + PINCTRL_PIN(67, "GP_SSP_1_FS0"), + PINCTRL_PIN(68, "GP_SSP_1_FS1"), + PINCTRL_PIN(69, "GP_SSP_1_RXD"), + PINCTRL_PIN(70, "GP_SSP_1_TXD"), + PINCTRL_PIN(71, "GP_SSP_2_CLK"), + PINCTRL_PIN(72, "GP_SSP_2_FS0"), + PINCTRL_PIN(73, "GP_SSP_2_FS1"), + PINCTRL_PIN(74, "GP_SSP_2_FS2"), + PINCTRL_PIN(75, "GP_SSP_2_RXD"), + PINCTRL_PIN(76, "GP_SSP_2_TXD"), +}; + +static const unsigned int apl_northwest_ssp0_pins[] = { 61, 62, 63, 64, 65 }; +static const unsigned int apl_northwest_ssp1_pins[] = { 66, 67, 68, 69, 70 }; +static const unsigned int apl_northwest_ssp2_pins[] = { 71, 72, 73, 74, 75, 76 }; +static const unsigned int apl_northwest_uart3_pins[] = { 67, 68, 69, 70 }; + +static const struct intel_pingroup apl_northwest_groups[] = { + PIN_GROUP("ssp0_grp", apl_northwest_ssp0_pins, 1), + PIN_GROUP("ssp1_grp", apl_northwest_ssp1_pins, 1), + PIN_GROUP("ssp2_grp", apl_northwest_ssp2_pins, 1), + PIN_GROUP("uart3_grp", apl_northwest_uart3_pins, 2), +}; + +static const char * const apl_northwest_ssp0_groups[] = { "ssp0_grp" }; +static const char * const apl_northwest_ssp1_groups[] = { "ssp1_grp" }; +static const char * const apl_northwest_ssp2_groups[] = { "ssp2_grp" }; +static const char * const apl_northwest_uart3_groups[] = { "uart3_grp" }; + +static const struct intel_function apl_northwest_functions[] = { + FUNCTION("ssp0", apl_northwest_ssp0_groups), + FUNCTION("ssp1", apl_northwest_ssp1_groups), + FUNCTION("ssp2", apl_northwest_ssp2_groups), + FUNCTION("uart3", apl_northwest_uart3_groups), +}; + +static const struct intel_community apl_northwest_communities[] = { + BXT_COMMUNITY(0, 76), +}; + +static const struct intel_pinctrl_soc_data apl_northwest_soc_data = { + .uid = "2", + .pins = apl_northwest_pins, + .npins = ARRAY_SIZE(apl_northwest_pins), + .groups = apl_northwest_groups, + .ngroups = ARRAY_SIZE(apl_northwest_groups), + .functions = apl_northwest_functions, + .nfunctions = ARRAY_SIZE(apl_northwest_functions), + .communities = apl_northwest_communities, + .ncommunities = ARRAY_SIZE(apl_northwest_communities), +}; + +static const struct pinctrl_pin_desc apl_west_pins[] = { + PINCTRL_PIN(0, "LPSS_I2C0_SDA"), + PINCTRL_PIN(1, "LPSS_I2C0_SCL"), + PINCTRL_PIN(2, "LPSS_I2C1_SDA"), + PINCTRL_PIN(3, "LPSS_I2C1_SCL"), + PINCTRL_PIN(4, "LPSS_I2C2_SDA"), + PINCTRL_PIN(5, "LPSS_I2C2_SCL"), + PINCTRL_PIN(6, "LPSS_I2C3_SDA"), + PINCTRL_PIN(7, "LPSS_I2C3_SCL"), + PINCTRL_PIN(8, "LPSS_I2C4_SDA"), + PINCTRL_PIN(9, "LPSS_I2C4_SCL"), + PINCTRL_PIN(10, "LPSS_I2C5_SDA"), + PINCTRL_PIN(11, "LPSS_I2C5_SCL"), + PINCTRL_PIN(12, "LPSS_I2C6_SDA"), + PINCTRL_PIN(13, "LPSS_I2C6_SCL"), + PINCTRL_PIN(14, "LPSS_I2C7_SDA"), + PINCTRL_PIN(15, "LPSS_I2C7_SCL"), + PINCTRL_PIN(16, "ISH_GPIO_0"), + PINCTRL_PIN(17, "ISH_GPIO_1"), + PINCTRL_PIN(18, "ISH_GPIO_2"), + PINCTRL_PIN(19, "ISH_GPIO_3"), + PINCTRL_PIN(20, "ISH_GPIO_4"), + PINCTRL_PIN(21, "ISH_GPIO_5"), + PINCTRL_PIN(22, "ISH_GPIO_6"), + PINCTRL_PIN(23, "ISH_GPIO_7"), + PINCTRL_PIN(24, "ISH_GPIO_8"), + PINCTRL_PIN(25, "ISH_GPIO_9"), + PINCTRL_PIN(26, "PCIE_CLKREQ0_B"), + PINCTRL_PIN(27, "PCIE_CLKREQ1_B"), + PINCTRL_PIN(28, "PCIE_CLKREQ2_B"), + PINCTRL_PIN(29, "PCIE_CLKREQ3_B"), + PINCTRL_PIN(30, "OSC_CLK_OUT_0"), + PINCTRL_PIN(31, "OSC_CLK_OUT_1"), + PINCTRL_PIN(32, "OSC_CLK_OUT_2"), + PINCTRL_PIN(33, "OSC_CLK_OUT_3"), + PINCTRL_PIN(34, "OSC_CLK_OUT_4"), + PINCTRL_PIN(35, "PMU_AC_PRESENT"), + PINCTRL_PIN(36, "PMU_BATLOW_B"), + PINCTRL_PIN(37, "PMU_PLTRST_B"), + PINCTRL_PIN(38, "PMU_PWRBTN_B"), + PINCTRL_PIN(39, "PMU_RESETBUTTON_B"), + PINCTRL_PIN(40, "PMU_SLP_S0_B"), + PINCTRL_PIN(41, "PMU_SLP_S3_B"), + PINCTRL_PIN(42, "PMU_SLP_S4_B"), + PINCTRL_PIN(43, "PMU_SUSCLK"), + PINCTRL_PIN(44, "PMU_WAKE_B"), + PINCTRL_PIN(45, "SUS_STAT_B"), + PINCTRL_PIN(46, "SUSPWRDNACK"), +}; + +static const unsigned int apl_west_i2c0_pins[] = { 0, 1 }; +static const unsigned int apl_west_i2c1_pins[] = { 2, 3 }; +static const unsigned int apl_west_i2c2_pins[] = { 4, 5 }; +static const unsigned int apl_west_i2c3_pins[] = { 6, 7 }; +static const unsigned int apl_west_i2c4_pins[] = { 8, 9 }; +static const unsigned int apl_west_i2c5_pins[] = { 10, 11 }; +static const unsigned int apl_west_i2c6_pins[] = { 12, 13 }; +static const unsigned int apl_west_i2c7_pins[] = { 14, 15 }; +static const unsigned int apl_west_uart2_pins[] = { 20, 21, 22, 34 }; + +static const struct intel_pingroup apl_west_groups[] = { + PIN_GROUP("i2c0_grp", apl_west_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", apl_west_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", apl_west_i2c2_pins, 1), + PIN_GROUP("i2c3_grp", apl_west_i2c3_pins, 1), + PIN_GROUP("i2c4_grp", apl_west_i2c4_pins, 1), + PIN_GROUP("i2c5_grp", apl_west_i2c5_pins, 1), + PIN_GROUP("i2c6_grp", apl_west_i2c6_pins, 1), + PIN_GROUP("i2c7_grp", apl_west_i2c7_pins, 1), + PIN_GROUP("uart2_grp", apl_west_uart2_pins, 3), +}; + +static const char * const apl_west_i2c0_groups[] = { "i2c0_grp" }; +static const char * const apl_west_i2c1_groups[] = { "i2c1_grp" }; +static const char * const apl_west_i2c2_groups[] = { "i2c2_grp" }; +static const char * const apl_west_i2c3_groups[] = { "i2c3_grp" }; +static const char * const apl_west_i2c4_groups[] = { "i2c4_grp" }; +static const char * const apl_west_i2c5_groups[] = { "i2c5_grp" }; +static const char * const apl_west_i2c6_groups[] = { "i2c6_grp" }; +static const char * const apl_west_i2c7_groups[] = { "i2c7_grp" }; +static const char * const apl_west_uart2_groups[] = { "uart2_grp" }; + +static const struct intel_function apl_west_functions[] = { + FUNCTION("i2c0", apl_west_i2c0_groups), + FUNCTION("i2c1", apl_west_i2c1_groups), + FUNCTION("i2c2", apl_west_i2c2_groups), + FUNCTION("i2c3", apl_west_i2c3_groups), + FUNCTION("i2c4", apl_west_i2c4_groups), + FUNCTION("i2c5", apl_west_i2c5_groups), + FUNCTION("i2c6", apl_west_i2c6_groups), + FUNCTION("i2c7", apl_west_i2c7_groups), + FUNCTION("uart2", apl_west_uart2_groups), +}; + +static const struct intel_community apl_west_communities[] = { + BXT_COMMUNITY(0, 46), +}; + +static const struct intel_pinctrl_soc_data apl_west_soc_data = { + .uid = "3", + .pins = apl_west_pins, + .npins = ARRAY_SIZE(apl_west_pins), + .groups = apl_west_groups, + .ngroups = ARRAY_SIZE(apl_west_groups), + .functions = apl_west_functions, + .nfunctions = ARRAY_SIZE(apl_west_functions), + .communities = apl_west_communities, + .ncommunities = ARRAY_SIZE(apl_west_communities), +}; + +static const struct pinctrl_pin_desc apl_southwest_pins[] = { + PINCTRL_PIN(0, "PCIE_WAKE0_B"), + PINCTRL_PIN(1, "PCIE_WAKE1_B"), + PINCTRL_PIN(2, "PCIE_WAKE2_B"), + PINCTRL_PIN(3, "PCIE_WAKE3_B"), + PINCTRL_PIN(4, "EMMC0_CLK"), + PINCTRL_PIN(5, "EMMC0_D0"), + PINCTRL_PIN(6, "EMMC0_D1"), + PINCTRL_PIN(7, "EMMC0_D2"), + PINCTRL_PIN(8, "EMMC0_D3"), + PINCTRL_PIN(9, "EMMC0_D4"), + PINCTRL_PIN(10, "EMMC0_D5"), + PINCTRL_PIN(11, "EMMC0_D6"), + PINCTRL_PIN(12, "EMMC0_D7"), + PINCTRL_PIN(13, "EMMC0_CMD"), + PINCTRL_PIN(14, "SDIO_CLK"), + PINCTRL_PIN(15, "SDIO_D0"), + PINCTRL_PIN(16, "SDIO_D1"), + PINCTRL_PIN(17, "SDIO_D2"), + PINCTRL_PIN(18, "SDIO_D3"), + PINCTRL_PIN(19, "SDIO_CMD"), + PINCTRL_PIN(20, "SDCARD_CLK"), + PINCTRL_PIN(21, "SDCARD_CLK_FB"), + PINCTRL_PIN(22, "SDCARD_D0"), + PINCTRL_PIN(23, "SDCARD_D1"), + PINCTRL_PIN(24, "SDCARD_D2"), + PINCTRL_PIN(25, "SDCARD_D3"), + PINCTRL_PIN(26, "SDCARD_CD_B"), + PINCTRL_PIN(27, "SDCARD_CMD"), + PINCTRL_PIN(28, "SDCARD_LVL_WP"), + PINCTRL_PIN(29, "EMMC0_STROBE"), + PINCTRL_PIN(30, "SDIO_PWR_DOWN_B"), + PINCTRL_PIN(31, "SMB_ALERTB"), + PINCTRL_PIN(32, "SMB_CLK"), + PINCTRL_PIN(33, "SMB_DATA"), + PINCTRL_PIN(34, "LPC_ILB_SERIRQ"), + PINCTRL_PIN(35, "LPC_CLKOUT0"), + PINCTRL_PIN(36, "LPC_CLKOUT1"), + PINCTRL_PIN(37, "LPC_AD0"), + PINCTRL_PIN(38, "LPC_AD1"), + PINCTRL_PIN(39, "LPC_AD2"), + PINCTRL_PIN(40, "LPC_AD3"), + PINCTRL_PIN(41, "LPC_CLKRUNB"), + PINCTRL_PIN(42, "LPC_FRAMEB"), +}; + +static const unsigned int apl_southwest_emmc0_pins[] = { + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 29, +}; +static const unsigned int apl_southwest_sdio_pins[] = { + 14, 15, 16, 17, 18, 19, 30, +}; +static const unsigned int apl_southwest_sdcard_pins[] = { + 20, 21, 22, 23, 24, 25, 26, 27, 28, +}; +static const unsigned int apl_southwest_i2c7_pins[] = { 32, 33 }; + +static const struct intel_pingroup apl_southwest_groups[] = { + PIN_GROUP("emmc0_grp", apl_southwest_emmc0_pins, 1), + PIN_GROUP("sdio_grp", apl_southwest_sdio_pins, 1), + PIN_GROUP("sdcard_grp", apl_southwest_sdcard_pins, 1), + PIN_GROUP("i2c7_grp", apl_southwest_i2c7_pins, 2), +}; + +static const char * const apl_southwest_emmc0_groups[] = { "emmc0_grp" }; +static const char * const apl_southwest_sdio_groups[] = { "sdio_grp" }; +static const char * const apl_southwest_sdcard_groups[] = { "sdcard_grp" }; +static const char * const apl_southwest_i2c7_groups[] = { "i2c7_grp" }; + +static const struct intel_function apl_southwest_functions[] = { + FUNCTION("emmc0", apl_southwest_emmc0_groups), + FUNCTION("sdio", apl_southwest_sdio_groups), + FUNCTION("sdcard", apl_southwest_sdcard_groups), + FUNCTION("i2c7", apl_southwest_i2c7_groups), +}; + +static const struct intel_community apl_southwest_communities[] = { + BXT_COMMUNITY(0, 42), +}; + +static const struct intel_pinctrl_soc_data apl_southwest_soc_data = { + .uid = "4", + .pins = apl_southwest_pins, + .npins = ARRAY_SIZE(apl_southwest_pins), + .groups = apl_southwest_groups, + .ngroups = ARRAY_SIZE(apl_southwest_groups), + .functions = apl_southwest_functions, + .nfunctions = ARRAY_SIZE(apl_southwest_functions), + .communities = apl_southwest_communities, + .ncommunities = ARRAY_SIZE(apl_southwest_communities), +}; + +static const struct intel_pinctrl_soc_data *apl_pinctrl_soc_data[] = { + &apl_north_soc_data, + &apl_northwest_soc_data, + &apl_west_soc_data, + &apl_southwest_soc_data, + NULL +}; + +static const struct acpi_device_id bxt_pinctrl_acpi_match[] = { + { "INT3452", (kernel_ulong_t)apl_pinctrl_soc_data }, + { "INT34D1", (kernel_ulong_t)bxt_pinctrl_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match); + +static const struct platform_device_id bxt_pinctrl_platform_ids[] = { + { "apollolake-pinctrl", (kernel_ulong_t)apl_pinctrl_soc_data }, + { "broxton-pinctrl", (kernel_ulong_t)bxt_pinctrl_soc_data }, + { } +}; + +static INTEL_PINCTRL_PM_OPS(bxt_pinctrl_pm_ops); + +static struct platform_driver bxt_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_uid, + .driver = { + .name = "broxton-pinctrl", + .acpi_match_table = bxt_pinctrl_acpi_match, + .pm = &bxt_pinctrl_pm_ops, + }, + .id_table = bxt_pinctrl_platform_ids, +}; + +static int __init bxt_pinctrl_init(void) +{ + return platform_driver_register(&bxt_pinctrl_driver); +} +subsys_initcall(bxt_pinctrl_init); + +static void __exit bxt_pinctrl_exit(void) +{ + platform_driver_unregister(&bxt_pinctrl_driver); +} +module_exit(bxt_pinctrl_exit); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:broxton-pinctrl"); diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c new file mode 100644 index 000000000..8078c7739 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c @@ -0,0 +1,851 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Cannon Lake PCH pinctrl/GPIO driver + * + * Copyright (C) 2017, Intel Corporation + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define CNL_PAD_OWN 0x020 +#define CNL_PADCFGLOCK 0x080 +#define CNL_LP_HOSTSW_OWN 0x0b0 +#define CNL_H_HOSTSW_OWN 0x0c0 +#define CNL_GPI_IS 0x100 +#define CNL_GPI_IE 0x120 + +#define CNL_GPP(r, s, e, g) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ + } + +#define CNL_COMMUNITY(b, s, e, ho, g) \ + { \ + .barno = (b), \ + .padown_offset = CNL_PAD_OWN, \ + .padcfglock_offset = CNL_PADCFGLOCK, \ + .hostown_offset = (ho), \ + .is_offset = CNL_GPI_IS, \ + .ie_offset = CNL_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +#define CNL_LP_COMMUNITY(b, s, e, g) \ + CNL_COMMUNITY(b, s, e, CNL_LP_HOSTSW_OWN, g) + +#define CNL_H_COMMUNITY(b, s, e, g) \ + CNL_COMMUNITY(b, s, e, CNL_H_HOSTSW_OWN, g) + +/* Cannon Lake-H */ +static const struct pinctrl_pin_desc cnlh_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "RCINB"), + PINCTRL_PIN(1, "LAD_0"), + PINCTRL_PIN(2, "LAD_1"), + PINCTRL_PIN(3, "LAD_2"), + PINCTRL_PIN(4, "LAD_3"), + PINCTRL_PIN(5, "LFRAMEB"), + PINCTRL_PIN(6, "SERIRQ"), + PINCTRL_PIN(7, "PIRQAB"), + PINCTRL_PIN(8, "CLKRUNB"), + PINCTRL_PIN(9, "CLKOUT_LPC_0"), + PINCTRL_PIN(10, "CLKOUT_LPC_1"), + PINCTRL_PIN(11, "PMEB"), + PINCTRL_PIN(12, "BM_BUSYB"), + PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(14, "SUS_STATB"), + PINCTRL_PIN(15, "SUSACKB"), + PINCTRL_PIN(16, "CLKOUT_48"), + PINCTRL_PIN(17, "SD_VDD1_PWR_EN_B"), + PINCTRL_PIN(18, "ISH_GP_0"), + PINCTRL_PIN(19, "ISH_GP_1"), + PINCTRL_PIN(20, "ISH_GP_2"), + PINCTRL_PIN(21, "ISH_GP_3"), + PINCTRL_PIN(22, "ISH_GP_4"), + PINCTRL_PIN(23, "ISH_GP_5"), + PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"), + /* GPP_B */ + PINCTRL_PIN(25, "GSPI0_CS1B"), + PINCTRL_PIN(26, "GSPI1_CS1B"), + PINCTRL_PIN(27, "VRALERTB"), + PINCTRL_PIN(28, "CPU_GP_2"), + PINCTRL_PIN(29, "CPU_GP_3"), + PINCTRL_PIN(30, "SRCCLKREQB_0"), + PINCTRL_PIN(31, "SRCCLKREQB_1"), + PINCTRL_PIN(32, "SRCCLKREQB_2"), + PINCTRL_PIN(33, "SRCCLKREQB_3"), + PINCTRL_PIN(34, "SRCCLKREQB_4"), + PINCTRL_PIN(35, "SRCCLKREQB_5"), + PINCTRL_PIN(36, "SSP_MCLK"), + PINCTRL_PIN(37, "SLP_S0B"), + PINCTRL_PIN(38, "PLTRSTB"), + PINCTRL_PIN(39, "SPKR"), + PINCTRL_PIN(40, "GSPI0_CS0B"), + PINCTRL_PIN(41, "GSPI0_CLK"), + PINCTRL_PIN(42, "GSPI0_MISO"), + PINCTRL_PIN(43, "GSPI0_MOSI"), + PINCTRL_PIN(44, "GSPI1_CS0B"), + PINCTRL_PIN(45, "GSPI1_CLK"), + PINCTRL_PIN(46, "GSPI1_MISO"), + PINCTRL_PIN(47, "GSPI1_MOSI"), + PINCTRL_PIN(48, "SML1ALERTB"), + PINCTRL_PIN(49, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(50, "GSPI1_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(51, "SMBCLK"), + PINCTRL_PIN(52, "SMBDATA"), + PINCTRL_PIN(53, "SMBALERTB"), + PINCTRL_PIN(54, "SML0CLK"), + PINCTRL_PIN(55, "SML0DATA"), + PINCTRL_PIN(56, "SML0ALERTB"), + PINCTRL_PIN(57, "SML1CLK"), + PINCTRL_PIN(58, "SML1DATA"), + PINCTRL_PIN(59, "UART0_RXD"), + PINCTRL_PIN(60, "UART0_TXD"), + PINCTRL_PIN(61, "UART0_RTSB"), + PINCTRL_PIN(62, "UART0_CTSB"), + PINCTRL_PIN(63, "UART1_RXD"), + PINCTRL_PIN(64, "UART1_TXD"), + PINCTRL_PIN(65, "UART1_RTSB"), + PINCTRL_PIN(66, "UART1_CTSB"), + PINCTRL_PIN(67, "I2C0_SDA"), + PINCTRL_PIN(68, "I2C0_SCL"), + PINCTRL_PIN(69, "I2C1_SDA"), + PINCTRL_PIN(70, "I2C1_SCL"), + PINCTRL_PIN(71, "UART2_RXD"), + PINCTRL_PIN(72, "UART2_TXD"), + PINCTRL_PIN(73, "UART2_RTSB"), + PINCTRL_PIN(74, "UART2_CTSB"), + /* GPP_D */ + PINCTRL_PIN(75, "SPI1_CSB"), + PINCTRL_PIN(76, "SPI1_CLK"), + PINCTRL_PIN(77, "SPI1_MISO_IO_1"), + PINCTRL_PIN(78, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(79, "ISH_I2C2_SDA"), + PINCTRL_PIN(80, "SSP2_SFRM"), + PINCTRL_PIN(81, "SSP2_TXD"), + PINCTRL_PIN(82, "SSP2_RXD"), + PINCTRL_PIN(83, "SSP2_SCLK"), + PINCTRL_PIN(84, "ISH_SPI_CSB"), + PINCTRL_PIN(85, "ISH_SPI_CLK"), + PINCTRL_PIN(86, "ISH_SPI_MISO"), + PINCTRL_PIN(87, "ISH_SPI_MOSI"), + PINCTRL_PIN(88, "ISH_UART0_RXD"), + PINCTRL_PIN(89, "ISH_UART0_TXD"), + PINCTRL_PIN(90, "ISH_UART0_RTSB"), + PINCTRL_PIN(91, "ISH_UART0_CTSB"), + PINCTRL_PIN(92, "DMIC_CLK_1"), + PINCTRL_PIN(93, "DMIC_DATA_1"), + PINCTRL_PIN(94, "DMIC_CLK_0"), + PINCTRL_PIN(95, "DMIC_DATA_0"), + PINCTRL_PIN(96, "SPI1_IO_2"), + PINCTRL_PIN(97, "SPI1_IO_3"), + PINCTRL_PIN(98, "ISH_I2C2_SCL"), + /* GPP_G */ + PINCTRL_PIN(99, "SD3_CMD"), + PINCTRL_PIN(100, "SD3_D0"), + PINCTRL_PIN(101, "SD3_D1"), + PINCTRL_PIN(102, "SD3_D2"), + PINCTRL_PIN(103, "SD3_D3"), + PINCTRL_PIN(104, "SD3_CDB"), + PINCTRL_PIN(105, "SD3_CLK"), + PINCTRL_PIN(106, "SD3_WP"), + /* AZA */ + PINCTRL_PIN(107, "HDA_BCLK"), + PINCTRL_PIN(108, "HDA_RSTB"), + PINCTRL_PIN(109, "HDA_SYNC"), + PINCTRL_PIN(110, "HDA_SDO"), + PINCTRL_PIN(111, "HDA_SDI_0"), + PINCTRL_PIN(112, "HDA_SDI_1"), + PINCTRL_PIN(113, "SSP1_SFRM"), + PINCTRL_PIN(114, "SSP1_TXD"), + /* vGPIO */ + PINCTRL_PIN(115, "CNV_BTEN"), + PINCTRL_PIN(116, "CNV_GNEN"), + PINCTRL_PIN(117, "CNV_WFEN"), + PINCTRL_PIN(118, "CNV_WCEN"), + PINCTRL_PIN(119, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(120, "vCNV_GNSS_HOST_WAKEB"), + PINCTRL_PIN(121, "vSD3_CD_B"), + PINCTRL_PIN(122, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(123, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(124, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(125, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(126, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(127, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(128, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(129, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(130, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(131, "vCNV_GNSS_UART_TXD"), + PINCTRL_PIN(132, "vCNV_GNSS_UART_RXD"), + PINCTRL_PIN(133, "vCNV_GNSS_UART_CTS_B"), + PINCTRL_PIN(134, "vCNV_GNSS_UART_RTS_B"), + PINCTRL_PIN(135, "vUART0_TXD"), + PINCTRL_PIN(136, "vUART0_RXD"), + PINCTRL_PIN(137, "vUART0_CTS_B"), + PINCTRL_PIN(138, "vUART0_RTSB"), + PINCTRL_PIN(139, "vISH_UART0_TXD"), + PINCTRL_PIN(140, "vISH_UART0_RXD"), + PINCTRL_PIN(141, "vISH_UART0_CTS_B"), + PINCTRL_PIN(142, "vISH_UART0_RTSB"), + PINCTRL_PIN(143, "vISH_UART1_TXD"), + PINCTRL_PIN(144, "vISH_UART1_RXD"), + PINCTRL_PIN(145, "vISH_UART1_CTS_B"), + PINCTRL_PIN(146, "vISH_UART1_RTS_B"), + PINCTRL_PIN(147, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(148, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(149, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(150, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(151, "vSSP2_SCLK"), + PINCTRL_PIN(152, "vSSP2_SFRM"), + PINCTRL_PIN(153, "vSSP2_TXD"), + PINCTRL_PIN(154, "vSSP2_RXD"), + /* GPP_K */ + PINCTRL_PIN(155, "FAN_TACH_0"), + PINCTRL_PIN(156, "FAN_TACH_1"), + PINCTRL_PIN(157, "FAN_TACH_2"), + PINCTRL_PIN(158, "FAN_TACH_3"), + PINCTRL_PIN(159, "FAN_TACH_4"), + PINCTRL_PIN(160, "FAN_TACH_5"), + PINCTRL_PIN(161, "FAN_TACH_6"), + PINCTRL_PIN(162, "FAN_TACH_7"), + PINCTRL_PIN(163, "FAN_PWM_0"), + PINCTRL_PIN(164, "FAN_PWM_1"), + PINCTRL_PIN(165, "FAN_PWM_2"), + PINCTRL_PIN(166, "FAN_PWM_3"), + PINCTRL_PIN(167, "GSXDOUT"), + PINCTRL_PIN(168, "GSXSLOAD"), + PINCTRL_PIN(169, "GSXDIN"), + PINCTRL_PIN(170, "GSXSRESETB"), + PINCTRL_PIN(171, "GSXCLK"), + PINCTRL_PIN(172, "ADR_COMPLETE"), + PINCTRL_PIN(173, "NMIB"), + PINCTRL_PIN(174, "SMIB"), + PINCTRL_PIN(175, "CORE_VID_0"), + PINCTRL_PIN(176, "CORE_VID_1"), + PINCTRL_PIN(177, "IMGCLKOUT_0"), + PINCTRL_PIN(178, "IMGCLKOUT_1"), + /* GPP_H */ + PINCTRL_PIN(179, "SRCCLKREQB_6"), + PINCTRL_PIN(180, "SRCCLKREQB_7"), + PINCTRL_PIN(181, "SRCCLKREQB_8"), + PINCTRL_PIN(182, "SRCCLKREQB_9"), + PINCTRL_PIN(183, "SRCCLKREQB_10"), + PINCTRL_PIN(184, "SRCCLKREQB_11"), + PINCTRL_PIN(185, "SRCCLKREQB_12"), + PINCTRL_PIN(186, "SRCCLKREQB_13"), + PINCTRL_PIN(187, "SRCCLKREQB_14"), + PINCTRL_PIN(188, "SRCCLKREQB_15"), + PINCTRL_PIN(189, "SML2CLK"), + PINCTRL_PIN(190, "SML2DATA"), + PINCTRL_PIN(191, "SML2ALERTB"), + PINCTRL_PIN(192, "SML3CLK"), + PINCTRL_PIN(193, "SML3DATA"), + PINCTRL_PIN(194, "SML3ALERTB"), + PINCTRL_PIN(195, "SML4CLK"), + PINCTRL_PIN(196, "SML4DATA"), + PINCTRL_PIN(197, "SML4ALERTB"), + PINCTRL_PIN(198, "ISH_I2C0_SDA"), + PINCTRL_PIN(199, "ISH_I2C0_SCL"), + PINCTRL_PIN(200, "ISH_I2C1_SDA"), + PINCTRL_PIN(201, "ISH_I2C1_SCL"), + PINCTRL_PIN(202, "TIME_SYNC_0"), + /* GPP_E */ + PINCTRL_PIN(203, "SATAXPCIE_0"), + PINCTRL_PIN(204, "SATAXPCIE_1"), + PINCTRL_PIN(205, "SATAXPCIE_2"), + PINCTRL_PIN(206, "CPU_GP_0"), + PINCTRL_PIN(207, "SATA_DEVSLP_0"), + PINCTRL_PIN(208, "SATA_DEVSLP_1"), + PINCTRL_PIN(209, "SATA_DEVSLP_2"), + PINCTRL_PIN(210, "CPU_GP_1"), + PINCTRL_PIN(211, "SATA_LEDB"), + PINCTRL_PIN(212, "USB2_OCB_0"), + PINCTRL_PIN(213, "USB2_OCB_1"), + PINCTRL_PIN(214, "USB2_OCB_2"), + PINCTRL_PIN(215, "USB2_OCB_3"), + /* GPP_F */ + PINCTRL_PIN(216, "SATAXPCIE_3"), + PINCTRL_PIN(217, "SATAXPCIE_4"), + PINCTRL_PIN(218, "SATAXPCIE_5"), + PINCTRL_PIN(219, "SATAXPCIE_6"), + PINCTRL_PIN(220, "SATAXPCIE_7"), + PINCTRL_PIN(221, "SATA_DEVSLP_3"), + PINCTRL_PIN(222, "SATA_DEVSLP_4"), + PINCTRL_PIN(223, "SATA_DEVSLP_5"), + PINCTRL_PIN(224, "SATA_DEVSLP_6"), + PINCTRL_PIN(225, "SATA_DEVSLP_7"), + PINCTRL_PIN(226, "SATA_SCLOCK"), + PINCTRL_PIN(227, "SATA_SLOAD"), + PINCTRL_PIN(228, "SATA_SDATAOUT1"), + PINCTRL_PIN(229, "SATA_SDATAOUT0"), + PINCTRL_PIN(230, "EXT_PWR_GATEB"), + PINCTRL_PIN(231, "USB2_OCB_4"), + PINCTRL_PIN(232, "USB2_OCB_5"), + PINCTRL_PIN(233, "USB2_OCB_6"), + PINCTRL_PIN(234, "USB2_OCB_7"), + PINCTRL_PIN(235, "L_VDDEN"), + PINCTRL_PIN(236, "L_BKLTEN"), + PINCTRL_PIN(237, "L_BKLTCTL"), + PINCTRL_PIN(238, "DDPF_CTRLCLK"), + PINCTRL_PIN(239, "DDPF_CTRLDATA"), + /* SPI */ + PINCTRL_PIN(240, "SPI0_IO_2"), + PINCTRL_PIN(241, "SPI0_IO_3"), + PINCTRL_PIN(242, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(243, "SPI0_MISO_IO_1"), + PINCTRL_PIN(244, "SPI0_TPM_CSB"), + PINCTRL_PIN(245, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(246, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(247, "SPI0_CLK"), + PINCTRL_PIN(248, "SPI0_CLK_LOOPBK"), + /* CPU */ + PINCTRL_PIN(249, "HDACPU_SDI"), + PINCTRL_PIN(250, "HDACPU_SDO"), + PINCTRL_PIN(251, "HDACPU_SCLK"), + PINCTRL_PIN(252, "PM_SYNC"), + PINCTRL_PIN(253, "PECI"), + PINCTRL_PIN(254, "CPUPWRGD"), + PINCTRL_PIN(255, "THRMTRIPB"), + PINCTRL_PIN(256, "PLTRST_CPUB"), + PINCTRL_PIN(257, "PM_DOWN"), + PINCTRL_PIN(258, "TRIGGER_IN"), + PINCTRL_PIN(259, "TRIGGER_OUT"), + /* JTAG */ + PINCTRL_PIN(260, "JTAG_TDO"), + PINCTRL_PIN(261, "JTAGX"), + PINCTRL_PIN(262, "PRDYB"), + PINCTRL_PIN(263, "PREQB"), + PINCTRL_PIN(264, "CPU_TRSTB"), + PINCTRL_PIN(265, "JTAG_TDI"), + PINCTRL_PIN(266, "JTAG_TMS"), + PINCTRL_PIN(267, "JTAG_TCK"), + PINCTRL_PIN(268, "ITP_PMODE"), + /* GPP_I */ + PINCTRL_PIN(269, "DDSP_HPD_0"), + PINCTRL_PIN(270, "DDSP_HPD_1"), + PINCTRL_PIN(271, "DDSP_HPD_2"), + PINCTRL_PIN(272, "DDSP_HPD_3"), + PINCTRL_PIN(273, "EDP_HPD"), + PINCTRL_PIN(274, "DDPB_CTRLCLK"), + PINCTRL_PIN(275, "DDPB_CTRLDATA"), + PINCTRL_PIN(276, "DDPC_CTRLCLK"), + PINCTRL_PIN(277, "DDPC_CTRLDATA"), + PINCTRL_PIN(278, "DDPD_CTRLCLK"), + PINCTRL_PIN(279, "DDPD_CTRLDATA"), + PINCTRL_PIN(280, "M2_SKT2_CFG_0"), + PINCTRL_PIN(281, "M2_SKT2_CFG_1"), + PINCTRL_PIN(282, "M2_SKT2_CFG_2"), + PINCTRL_PIN(283, "M2_SKT2_CFG_3"), + PINCTRL_PIN(284, "SYS_PWROK"), + PINCTRL_PIN(285, "SYS_RESETB"), + PINCTRL_PIN(286, "MLK_RSTB"), + /* GPP_J */ + PINCTRL_PIN(287, "CNV_PA_BLANKING"), + PINCTRL_PIN(288, "CNV_GNSS_FTA"), + PINCTRL_PIN(289, "CNV_GNSS_SYSCK"), + PINCTRL_PIN(290, "CNV_RF_RESET_B"), + PINCTRL_PIN(291, "CNV_BRI_DT"), + PINCTRL_PIN(292, "CNV_BRI_RSP"), + PINCTRL_PIN(293, "CNV_RGI_DT"), + PINCTRL_PIN(294, "CNV_RGI_RSP"), + PINCTRL_PIN(295, "CNV_MFUART2_RXD"), + PINCTRL_PIN(296, "CNV_MFUART2_TXD"), + PINCTRL_PIN(297, "CNV_MODEM_CLKREQ"), + PINCTRL_PIN(298, "A4WP_PRESENT"), +}; + +static const struct intel_padgroup cnlh_community0_gpps[] = { + CNL_GPP(0, 0, 24, 0), /* GPP_A */ + CNL_GPP(1, 25, 50, 32), /* GPP_B */ +}; + +static const struct intel_padgroup cnlh_community1_gpps[] = { + CNL_GPP(0, 51, 74, 64), /* GPP_C */ + CNL_GPP(1, 75, 98, 96), /* GPP_D */ + CNL_GPP(2, 99, 106, 128), /* GPP_G */ + CNL_GPP(3, 107, 114, INTEL_GPIO_BASE_NOMAP), /* AZA */ + CNL_GPP(4, 115, 146, 160), /* vGPIO_0 */ + CNL_GPP(5, 147, 154, INTEL_GPIO_BASE_NOMAP), /* vGPIO_1 */ +}; + +static const struct intel_padgroup cnlh_community3_gpps[] = { + CNL_GPP(0, 155, 178, 192), /* GPP_K */ + CNL_GPP(1, 179, 202, 224), /* GPP_H */ + CNL_GPP(2, 203, 215, 256), /* GPP_E */ + CNL_GPP(3, 216, 239, 288), /* GPP_F */ + CNL_GPP(4, 240, 248, INTEL_GPIO_BASE_NOMAP), /* SPI */ +}; + +static const struct intel_padgroup cnlh_community4_gpps[] = { + CNL_GPP(0, 249, 259, INTEL_GPIO_BASE_NOMAP), /* CPU */ + CNL_GPP(1, 260, 268, INTEL_GPIO_BASE_NOMAP), /* JTAG */ + CNL_GPP(2, 269, 286, 320), /* GPP_I */ + CNL_GPP(3, 287, 298, 352), /* GPP_J */ +}; + +static const unsigned int cnlh_spi0_pins[] = { 40, 41, 42, 43 }; +static const unsigned int cnlh_spi1_pins[] = { 44, 45, 46, 47 }; +static const unsigned int cnlh_spi2_pins[] = { 84, 85, 86, 87 }; + +static const unsigned int cnlh_uart0_pins[] = { 59, 60, 61, 62 }; +static const unsigned int cnlh_uart1_pins[] = { 63, 64, 65, 66 }; +static const unsigned int cnlh_uart2_pins[] = { 71, 72, 73, 74 }; + +static const unsigned int cnlh_i2c0_pins[] = { 67, 68 }; +static const unsigned int cnlh_i2c1_pins[] = { 69, 70 }; +static const unsigned int cnlh_i2c2_pins[] = { 88, 89 }; +static const unsigned int cnlh_i2c3_pins[] = { 79, 98 }; + +static const struct intel_pingroup cnlh_groups[] = { + PIN_GROUP("spi0_grp", cnlh_spi0_pins, 1), + PIN_GROUP("spi1_grp", cnlh_spi1_pins, 1), + PIN_GROUP("spi2_grp", cnlh_spi2_pins, 3), + PIN_GROUP("uart0_grp", cnlh_uart0_pins, 1), + PIN_GROUP("uart1_grp", cnlh_uart1_pins, 1), + PIN_GROUP("uart2_grp", cnlh_uart2_pins, 1), + PIN_GROUP("i2c0_grp", cnlh_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", cnlh_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", cnlh_i2c2_pins, 3), + PIN_GROUP("i2c3_grp", cnlh_i2c3_pins, 2), +}; + +static const char * const cnlh_spi0_groups[] = { "spi0_grp" }; +static const char * const cnlh_spi1_groups[] = { "spi1_grp" }; +static const char * const cnlh_spi2_groups[] = { "spi2_grp" }; +static const char * const cnlh_uart0_groups[] = { "uart0_grp" }; +static const char * const cnlh_uart1_groups[] = { "uart1_grp" }; +static const char * const cnlh_uart2_groups[] = { "uart2_grp" }; +static const char * const cnlh_i2c0_groups[] = { "i2c0_grp" }; +static const char * const cnlh_i2c1_groups[] = { "i2c1_grp" }; +static const char * const cnlh_i2c2_groups[] = { "i2c2_grp" }; +static const char * const cnlh_i2c3_groups[] = { "i2c3_grp" }; + +static const struct intel_function cnlh_functions[] = { + FUNCTION("spi0", cnlh_spi0_groups), + FUNCTION("spi1", cnlh_spi1_groups), + FUNCTION("spi2", cnlh_spi2_groups), + FUNCTION("uart0", cnlh_uart0_groups), + FUNCTION("uart1", cnlh_uart1_groups), + FUNCTION("uart2", cnlh_uart2_groups), + FUNCTION("i2c0", cnlh_i2c0_groups), + FUNCTION("i2c1", cnlh_i2c1_groups), + FUNCTION("i2c2", cnlh_i2c2_groups), + FUNCTION("i2c3", cnlh_i2c3_groups), +}; + +static const struct intel_community cnlh_communities[] = { + CNL_H_COMMUNITY(0, 0, 50, cnlh_community0_gpps), + CNL_H_COMMUNITY(1, 51, 154, cnlh_community1_gpps), + CNL_H_COMMUNITY(2, 155, 248, cnlh_community3_gpps), + CNL_H_COMMUNITY(3, 249, 298, cnlh_community4_gpps), +}; + +static const struct intel_pinctrl_soc_data cnlh_soc_data = { + .pins = cnlh_pins, + .npins = ARRAY_SIZE(cnlh_pins), + .groups = cnlh_groups, + .ngroups = ARRAY_SIZE(cnlh_groups), + .functions = cnlh_functions, + .nfunctions = ARRAY_SIZE(cnlh_functions), + .communities = cnlh_communities, + .ncommunities = ARRAY_SIZE(cnlh_communities), +}; + +/* Cannon Lake-LP */ +static const struct pinctrl_pin_desc cnllp_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "RCINB"), + PINCTRL_PIN(1, "LAD_0"), + PINCTRL_PIN(2, "LAD_1"), + PINCTRL_PIN(3, "LAD_2"), + PINCTRL_PIN(4, "LAD_3"), + PINCTRL_PIN(5, "LFRAMEB"), + PINCTRL_PIN(6, "SERIRQ"), + PINCTRL_PIN(7, "PIRQAB"), + PINCTRL_PIN(8, "CLKRUNB"), + PINCTRL_PIN(9, "CLKOUT_LPC_0"), + PINCTRL_PIN(10, "CLKOUT_LPC_1"), + PINCTRL_PIN(11, "PMEB"), + PINCTRL_PIN(12, "BM_BUSYB"), + PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(14, "SUS_STATB"), + PINCTRL_PIN(15, "SUSACKB"), + PINCTRL_PIN(16, "SD_1P8_SEL"), + PINCTRL_PIN(17, "SD_PWR_EN_B"), + PINCTRL_PIN(18, "ISH_GP_0"), + PINCTRL_PIN(19, "ISH_GP_1"), + PINCTRL_PIN(20, "ISH_GP_2"), + PINCTRL_PIN(21, "ISH_GP_3"), + PINCTRL_PIN(22, "ISH_GP_4"), + PINCTRL_PIN(23, "ISH_GP_5"), + PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"), + /* GPP_B */ + PINCTRL_PIN(25, "CORE_VID_0"), + PINCTRL_PIN(26, "CORE_VID_1"), + PINCTRL_PIN(27, "VRALERTB"), + PINCTRL_PIN(28, "CPU_GP_2"), + PINCTRL_PIN(29, "CPU_GP_3"), + PINCTRL_PIN(30, "SRCCLKREQB_0"), + PINCTRL_PIN(31, "SRCCLKREQB_1"), + PINCTRL_PIN(32, "SRCCLKREQB_2"), + PINCTRL_PIN(33, "SRCCLKREQB_3"), + PINCTRL_PIN(34, "SRCCLKREQB_4"), + PINCTRL_PIN(35, "SRCCLKREQB_5"), + PINCTRL_PIN(36, "EXT_PWR_GATEB"), + PINCTRL_PIN(37, "SLP_S0B"), + PINCTRL_PIN(38, "PLTRSTB"), + PINCTRL_PIN(39, "SPKR"), + PINCTRL_PIN(40, "GSPI0_CS0B"), + PINCTRL_PIN(41, "GSPI0_CLK"), + PINCTRL_PIN(42, "GSPI0_MISO"), + PINCTRL_PIN(43, "GSPI0_MOSI"), + PINCTRL_PIN(44, "GSPI1_CS0B"), + PINCTRL_PIN(45, "GSPI1_CLK"), + PINCTRL_PIN(46, "GSPI1_MISO"), + PINCTRL_PIN(47, "GSPI1_MOSI"), + PINCTRL_PIN(48, "SML1ALERTB"), + PINCTRL_PIN(49, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(50, "GSPI1_CLK_LOOPBK"), + /* GPP_G */ + PINCTRL_PIN(51, "SD3_CMD"), + PINCTRL_PIN(52, "SD3_D0_SD4_RCLK_P"), + PINCTRL_PIN(53, "SD3_D1_SD4_RCLK_N"), + PINCTRL_PIN(54, "SD3_D2"), + PINCTRL_PIN(55, "SD3_D3"), + PINCTRL_PIN(56, "SD3_CDB"), + PINCTRL_PIN(57, "SD3_CLK"), + PINCTRL_PIN(58, "SD3_WP"), + /* SPI */ + PINCTRL_PIN(59, "SPI0_IO_2"), + PINCTRL_PIN(60, "SPI0_IO_3"), + PINCTRL_PIN(61, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(62, "SPI0_MISO_IO_1"), + PINCTRL_PIN(63, "SPI0_TPM_CSB"), + PINCTRL_PIN(64, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(65, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(66, "SPI0_CLK"), + PINCTRL_PIN(67, "SPI0_CLK_LOOPBK"), + /* GPP_D */ + PINCTRL_PIN(68, "SPI1_CSB"), + PINCTRL_PIN(69, "SPI1_CLK"), + PINCTRL_PIN(70, "SPI1_MISO_IO_1"), + PINCTRL_PIN(71, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(72, "IMGCLKOUT_0"), + PINCTRL_PIN(73, "ISH_I2C0_SDA"), + PINCTRL_PIN(74, "ISH_I2C0_SCL"), + PINCTRL_PIN(75, "ISH_I2C1_SDA"), + PINCTRL_PIN(76, "ISH_I2C1_SCL"), + PINCTRL_PIN(77, "ISH_SPI_CSB"), + PINCTRL_PIN(78, "ISH_SPI_CLK"), + PINCTRL_PIN(79, "ISH_SPI_MISO"), + PINCTRL_PIN(80, "ISH_SPI_MOSI"), + PINCTRL_PIN(81, "ISH_UART0_RXD"), + PINCTRL_PIN(82, "ISH_UART0_TXD"), + PINCTRL_PIN(83, "ISH_UART0_RTSB"), + PINCTRL_PIN(84, "ISH_UART0_CTSB"), + PINCTRL_PIN(85, "DMIC_CLK_1"), + PINCTRL_PIN(86, "DMIC_DATA_1"), + PINCTRL_PIN(87, "DMIC_CLK_0"), + PINCTRL_PIN(88, "DMIC_DATA_0"), + PINCTRL_PIN(89, "SPI1_IO_2"), + PINCTRL_PIN(90, "SPI1_IO_3"), + PINCTRL_PIN(91, "SSP_MCLK"), + PINCTRL_PIN(92, "GSPI2_CLK_LOOPBK"), + /* GPP_F */ + PINCTRL_PIN(93, "CNV_GNSS_PA_BLANKING"), + PINCTRL_PIN(94, "CNV_GNSS_FTA"), + PINCTRL_PIN(95, "CNV_GNSS_SYSCK"), + PINCTRL_PIN(96, "EMMC_HIP_MON"), + PINCTRL_PIN(97, "CNV_BRI_DT"), + PINCTRL_PIN(98, "CNV_BRI_RSP"), + PINCTRL_PIN(99, "CNV_RGI_DT"), + PINCTRL_PIN(100, "CNV_RGI_RSP"), + PINCTRL_PIN(101, "CNV_MFUART2_RXD"), + PINCTRL_PIN(102, "CNV_MFUART2_TXD"), + PINCTRL_PIN(103, "GPP_F_10"), + PINCTRL_PIN(104, "EMMC_CMD"), + PINCTRL_PIN(105, "EMMC_DATA_0"), + PINCTRL_PIN(106, "EMMC_DATA_1"), + PINCTRL_PIN(107, "EMMC_DATA_2"), + PINCTRL_PIN(108, "EMMC_DATA_3"), + PINCTRL_PIN(109, "EMMC_DATA_4"), + PINCTRL_PIN(110, "EMMC_DATA_5"), + PINCTRL_PIN(111, "EMMC_DATA_6"), + PINCTRL_PIN(112, "EMMC_DATA_7"), + PINCTRL_PIN(113, "EMMC_RCLK"), + PINCTRL_PIN(114, "EMMC_CLK"), + PINCTRL_PIN(115, "EMMC_RESETB"), + PINCTRL_PIN(116, "A4WP_PRESENT"), + /* GPP_H */ + PINCTRL_PIN(117, "SSP2_SCLK"), + PINCTRL_PIN(118, "SSP2_SFRM"), + PINCTRL_PIN(119, "SSP2_TXD"), + PINCTRL_PIN(120, "SSP2_RXD"), + PINCTRL_PIN(121, "I2C2_SDA"), + PINCTRL_PIN(122, "I2C2_SCL"), + PINCTRL_PIN(123, "I2C3_SDA"), + PINCTRL_PIN(124, "I2C3_SCL"), + PINCTRL_PIN(125, "I2C4_SDA"), + PINCTRL_PIN(126, "I2C4_SCL"), + PINCTRL_PIN(127, "I2C5_SDA"), + PINCTRL_PIN(128, "I2C5_SCL"), + PINCTRL_PIN(129, "M2_SKT2_CFG_0"), + PINCTRL_PIN(130, "M2_SKT2_CFG_1"), + PINCTRL_PIN(131, "M2_SKT2_CFG_2"), + PINCTRL_PIN(132, "M2_SKT2_CFG_3"), + PINCTRL_PIN(133, "DDPF_CTRLCLK"), + PINCTRL_PIN(134, "DDPF_CTRLDATA"), + PINCTRL_PIN(135, "CPU_VCCIO_PWR_GATEB"), + PINCTRL_PIN(136, "TIMESYNC_0"), + PINCTRL_PIN(137, "IMGCLKOUT_1"), + PINCTRL_PIN(138, "GPPC_H_21"), + PINCTRL_PIN(139, "GPPC_H_22"), + PINCTRL_PIN(140, "GPPC_H_23"), + /* vGPIO */ + PINCTRL_PIN(141, "CNV_BTEN"), + PINCTRL_PIN(142, "CNV_GNEN"), + PINCTRL_PIN(143, "CNV_WFEN"), + PINCTRL_PIN(144, "CNV_WCEN"), + PINCTRL_PIN(145, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(146, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(147, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(148, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(149, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(150, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(151, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(152, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(153, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(154, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(155, "vCNV_GNSS_UART_TXD"), + PINCTRL_PIN(156, "vCNV_GNSS_UART_RXD"), + PINCTRL_PIN(157, "vCNV_GNSS_UART_CTS_B"), + PINCTRL_PIN(158, "vCNV_GNSS_UART_RTS_B"), + PINCTRL_PIN(159, "vUART0_TXD"), + PINCTRL_PIN(160, "vUART0_RXD"), + PINCTRL_PIN(161, "vUART0_CTS_B"), + PINCTRL_PIN(162, "vUART0_RTS_B"), + PINCTRL_PIN(163, "vISH_UART0_TXD"), + PINCTRL_PIN(164, "vISH_UART0_RXD"), + PINCTRL_PIN(165, "vISH_UART0_CTS_B"), + PINCTRL_PIN(166, "vISH_UART0_RTS_B"), + PINCTRL_PIN(167, "vISH_UART1_TXD"), + PINCTRL_PIN(168, "vISH_UART1_RXD"), + PINCTRL_PIN(169, "vISH_UART1_CTS_B"), + PINCTRL_PIN(170, "vISH_UART1_RTS_B"), + PINCTRL_PIN(171, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(172, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(173, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(174, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(175, "vSSP2_SCLK"), + PINCTRL_PIN(176, "vSSP2_SFRM"), + PINCTRL_PIN(177, "vSSP2_TXD"), + PINCTRL_PIN(178, "vSSP2_RXD"), + PINCTRL_PIN(179, "vCNV_GNSS_HOST_WAKEB"), + PINCTRL_PIN(180, "vSD3_CD_B"), + /* GPP_C */ + PINCTRL_PIN(181, "SMBCLK"), + PINCTRL_PIN(182, "SMBDATA"), + PINCTRL_PIN(183, "SMBALERTB"), + PINCTRL_PIN(184, "SML0CLK"), + PINCTRL_PIN(185, "SML0DATA"), + PINCTRL_PIN(186, "SML0ALERTB"), + PINCTRL_PIN(187, "SML1CLK"), + PINCTRL_PIN(188, "SML1DATA"), + PINCTRL_PIN(189, "UART0_RXD"), + PINCTRL_PIN(190, "UART0_TXD"), + PINCTRL_PIN(191, "UART0_RTSB"), + PINCTRL_PIN(192, "UART0_CTSB"), + PINCTRL_PIN(193, "UART1_RXD"), + PINCTRL_PIN(194, "UART1_TXD"), + PINCTRL_PIN(195, "UART1_RTSB"), + PINCTRL_PIN(196, "UART1_CTSB"), + PINCTRL_PIN(197, "I2C0_SDA"), + PINCTRL_PIN(198, "I2C0_SCL"), + PINCTRL_PIN(199, "I2C1_SDA"), + PINCTRL_PIN(200, "I2C1_SCL"), + PINCTRL_PIN(201, "UART2_RXD"), + PINCTRL_PIN(202, "UART2_TXD"), + PINCTRL_PIN(203, "UART2_RTSB"), + PINCTRL_PIN(204, "UART2_CTSB"), + /* GPP_E */ + PINCTRL_PIN(205, "SATAXPCIE_0"), + PINCTRL_PIN(206, "SATAXPCIE_1"), + PINCTRL_PIN(207, "SATAXPCIE_2"), + PINCTRL_PIN(208, "CPU_GP_0"), + PINCTRL_PIN(209, "SATA_DEVSLP_0"), + PINCTRL_PIN(210, "SATA_DEVSLP_1"), + PINCTRL_PIN(211, "SATA_DEVSLP_2"), + PINCTRL_PIN(212, "CPU_GP_1"), + PINCTRL_PIN(213, "SATA_LEDB"), + PINCTRL_PIN(214, "USB2_OCB_0"), + PINCTRL_PIN(215, "USB2_OCB_1"), + PINCTRL_PIN(216, "USB2_OCB_2"), + PINCTRL_PIN(217, "USB2_OCB_3"), + PINCTRL_PIN(218, "DDSP_HPD_0"), + PINCTRL_PIN(219, "DDSP_HPD_1"), + PINCTRL_PIN(220, "DDSP_HPD_2"), + PINCTRL_PIN(221, "DDSP_HPD_3"), + PINCTRL_PIN(222, "EDP_HPD"), + PINCTRL_PIN(223, "DDPB_CTRLCLK"), + PINCTRL_PIN(224, "DDPB_CTRLDATA"), + PINCTRL_PIN(225, "DDPC_CTRLCLK"), + PINCTRL_PIN(226, "DDPC_CTRLDATA"), + PINCTRL_PIN(227, "DDPD_CTRLCLK"), + PINCTRL_PIN(228, "DDPD_CTRLDATA"), + /* JTAG */ + PINCTRL_PIN(229, "JTAG_TDO"), + PINCTRL_PIN(230, "JTAGX"), + PINCTRL_PIN(231, "PRDYB"), + PINCTRL_PIN(232, "PREQB"), + PINCTRL_PIN(233, "CPU_TRSTB"), + PINCTRL_PIN(234, "JTAG_TDI"), + PINCTRL_PIN(235, "JTAG_TMS"), + PINCTRL_PIN(236, "JTAG_TCK"), + PINCTRL_PIN(237, "ITP_PMODE"), + /* HVCMOS */ + PINCTRL_PIN(238, "L_BKLTEN"), + PINCTRL_PIN(239, "L_BKLTCTL"), + PINCTRL_PIN(240, "L_VDDEN"), + PINCTRL_PIN(241, "SYS_PWROK"), + PINCTRL_PIN(242, "SYS_RESETB"), + PINCTRL_PIN(243, "MLK_RSTB"), +}; + +static const unsigned int cnllp_spi0_pins[] = { 40, 41, 42, 43, 7 }; +static const unsigned int cnllp_spi0_modes[] = { 1, 1, 1, 1, 2 }; +static const unsigned int cnllp_spi1_pins[] = { 44, 45, 46, 47, 11 }; +static const unsigned int cnllp_spi1_modes[] = { 1, 1, 1, 1, 2 }; +static const unsigned int cnllp_spi2_pins[] = { 77, 78, 79, 80, 83 }; +static const unsigned int cnllp_spi2_modes[] = { 3, 3, 3, 3, 2 }; + +static const unsigned int cnllp_i2c0_pins[] = { 197, 198 }; +static const unsigned int cnllp_i2c1_pins[] = { 199, 200 }; +static const unsigned int cnllp_i2c2_pins[] = { 121, 122 }; +static const unsigned int cnllp_i2c3_pins[] = { 123, 124 }; +static const unsigned int cnllp_i2c4_pins[] = { 125, 126 }; +static const unsigned int cnllp_i2c5_pins[] = { 127, 128 }; + +static const unsigned int cnllp_uart0_pins[] = { 189, 190, 191, 192 }; +static const unsigned int cnllp_uart1_pins[] = { 193, 194, 195, 196 }; +static const unsigned int cnllp_uart2_pins[] = { 201, 202, 203, 204 }; + +static const struct intel_pingroup cnllp_groups[] = { + PIN_GROUP("spi0_grp", cnllp_spi0_pins, cnllp_spi0_modes), + PIN_GROUP("spi1_grp", cnllp_spi1_pins, cnllp_spi1_modes), + PIN_GROUP("spi2_grp", cnllp_spi2_pins, cnllp_spi2_modes), + PIN_GROUP("i2c0_grp", cnllp_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", cnllp_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", cnllp_i2c2_pins, 1), + PIN_GROUP("i2c3_grp", cnllp_i2c3_pins, 1), + PIN_GROUP("i2c4_grp", cnllp_i2c4_pins, 1), + PIN_GROUP("i2c5_grp", cnllp_i2c5_pins, 1), + PIN_GROUP("uart0_grp", cnllp_uart0_pins, 1), + PIN_GROUP("uart1_grp", cnllp_uart1_pins, 1), + PIN_GROUP("uart2_grp", cnllp_uart2_pins, 1), +}; + +static const char * const cnllp_spi0_groups[] = { "spi0_grp" }; +static const char * const cnllp_spi1_groups[] = { "spi1_grp" }; +static const char * const cnllp_spi2_groups[] = { "spi2_grp" }; +static const char * const cnllp_i2c0_groups[] = { "i2c0_grp" }; +static const char * const cnllp_i2c1_groups[] = { "i2c1_grp" }; +static const char * const cnllp_i2c2_groups[] = { "i2c2_grp" }; +static const char * const cnllp_i2c3_groups[] = { "i2c3_grp" }; +static const char * const cnllp_i2c4_groups[] = { "i2c4_grp" }; +static const char * const cnllp_i2c5_groups[] = { "i2c5_grp" }; +static const char * const cnllp_uart0_groups[] = { "uart0_grp" }; +static const char * const cnllp_uart1_groups[] = { "uart1_grp" }; +static const char * const cnllp_uart2_groups[] = { "uart2_grp" }; + +static const struct intel_function cnllp_functions[] = { + FUNCTION("spi0", cnllp_spi0_groups), + FUNCTION("spi1", cnllp_spi1_groups), + FUNCTION("spi2", cnllp_spi2_groups), + FUNCTION("i2c0", cnllp_i2c0_groups), + FUNCTION("i2c1", cnllp_i2c1_groups), + FUNCTION("i2c2", cnllp_i2c2_groups), + FUNCTION("i2c3", cnllp_i2c3_groups), + FUNCTION("i2c4", cnllp_i2c4_groups), + FUNCTION("i2c5", cnllp_i2c5_groups), + FUNCTION("uart0", cnllp_uart0_groups), + FUNCTION("uart1", cnllp_uart1_groups), + FUNCTION("uart2", cnllp_uart2_groups), +}; + +static const struct intel_padgroup cnllp_community0_gpps[] = { + CNL_GPP(0, 0, 24, 0), /* GPP_A */ + CNL_GPP(1, 25, 50, 32), /* GPP_B */ + CNL_GPP(2, 51, 58, 64), /* GPP_G */ + CNL_GPP(3, 59, 67, INTEL_GPIO_BASE_NOMAP), /* SPI */ +}; + +static const struct intel_padgroup cnllp_community1_gpps[] = { + CNL_GPP(0, 68, 92, 96), /* GPP_D */ + CNL_GPP(1, 93, 116, 128), /* GPP_F */ + CNL_GPP(2, 117, 140, 160), /* GPP_H */ + CNL_GPP(3, 141, 172, 192), /* vGPIO */ + CNL_GPP(4, 173, 180, 224), /* vGPIO */ +}; + +static const struct intel_padgroup cnllp_community4_gpps[] = { + CNL_GPP(0, 181, 204, 256), /* GPP_C */ + CNL_GPP(1, 205, 228, 288), /* GPP_E */ + CNL_GPP(2, 229, 237, INTEL_GPIO_BASE_NOMAP), /* JTAG */ + CNL_GPP(3, 238, 243, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */ +}; + +static const struct intel_community cnllp_communities[] = { + CNL_LP_COMMUNITY(0, 0, 67, cnllp_community0_gpps), + CNL_LP_COMMUNITY(1, 68, 180, cnllp_community1_gpps), + CNL_LP_COMMUNITY(2, 181, 243, cnllp_community4_gpps), +}; + +static const struct intel_pinctrl_soc_data cnllp_soc_data = { + .pins = cnllp_pins, + .npins = ARRAY_SIZE(cnllp_pins), + .groups = cnllp_groups, + .ngroups = ARRAY_SIZE(cnllp_groups), + .functions = cnllp_functions, + .nfunctions = ARRAY_SIZE(cnllp_functions), + .communities = cnllp_communities, + .ncommunities = ARRAY_SIZE(cnllp_communities), +}; + +static const struct acpi_device_id cnl_pinctrl_acpi_match[] = { + { "INT3450", (kernel_ulong_t)&cnlh_soc_data }, + { "INT34BB", (kernel_ulong_t)&cnllp_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, cnl_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(cnl_pinctrl_pm_ops); + +static struct platform_driver cnl_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "cannonlake-pinctrl", + .acpi_match_table = cnl_pinctrl_acpi_match, + .pm = &cnl_pinctrl_pm_ops, + }, +}; + +module_platform_driver(cnl_pinctrl_driver); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Cannon Lake PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-cedarfork.c b/drivers/pinctrl/intel/pinctrl-cedarfork.c new file mode 100644 index 000000000..aa6f9040d --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-cedarfork.c @@ -0,0 +1,364 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Cedar Fork PCH pinctrl/GPIO driver + * + * Copyright (C) 2017, Intel Corporation + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define CDF_PAD_OWN 0x020 +#define CDF_PADCFGLOCK 0x0c0 +#define CDF_HOSTSW_OWN 0x120 +#define CDF_GPI_IS 0x200 +#define CDF_GPI_IE 0x230 + +#define CDF_GPP(r, s, e) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + } + +#define CDF_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = CDF_PAD_OWN, \ + .padcfglock_offset = CDF_PADCFGLOCK, \ + .hostown_offset = CDF_HOSTSW_OWN, \ + .is_offset = CDF_GPI_IS, \ + .ie_offset = CDF_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Cedar Fork PCH */ +static const struct pinctrl_pin_desc cdf_pins[] = { + /* WEST2 */ + PINCTRL_PIN(0, "GBE_SDP_TIMESYNC0_S2N"), + PINCTRL_PIN(1, "GBE_SDP_TIMESYNC1_S2N"), + PINCTRL_PIN(2, "GBE_SDP_TIMESYNC2_S2N"), + PINCTRL_PIN(3, "GBE_SDP_TIMESYNC3_S2N"), + PINCTRL_PIN(4, "GBE0_I2C_CLK"), + PINCTRL_PIN(5, "GBE0_I2C_DATA"), + PINCTRL_PIN(6, "GBE1_I2C_CLK"), + PINCTRL_PIN(7, "GBE1_I2C_DATA"), + PINCTRL_PIN(8, "GBE2_I2C_CLK"), + PINCTRL_PIN(9, "GBE2_I2C_DATA"), + PINCTRL_PIN(10, "GBE3_I2C_CLK"), + PINCTRL_PIN(11, "GBE3_I2C_DATA"), + PINCTRL_PIN(12, "GBE0_LED0"), + PINCTRL_PIN(13, "GBE0_LED1"), + PINCTRL_PIN(14, "GBE0_LED2"), + PINCTRL_PIN(15, "GBE1_LED0"), + PINCTRL_PIN(16, "GBE1_LED1"), + PINCTRL_PIN(17, "GBE1_LED2"), + PINCTRL_PIN(18, "GBE2_LED0"), + PINCTRL_PIN(19, "GBE2_LED1"), + PINCTRL_PIN(20, "GBE2_LED2"), + PINCTRL_PIN(21, "GBE3_LED0"), + PINCTRL_PIN(22, "GBE3_LED1"), + PINCTRL_PIN(23, "GBE3_LED2"), + /* WEST3 */ + PINCTRL_PIN(24, "NCSI_RXD0"), + PINCTRL_PIN(25, "NCSI_CLK_IN"), + PINCTRL_PIN(26, "NCSI_RXD1"), + PINCTRL_PIN(27, "NCSI_CRS_DV"), + PINCTRL_PIN(28, "NCSI_ARB_IN"), + PINCTRL_PIN(29, "NCSI_TX_EN"), + PINCTRL_PIN(30, "NCSI_TXD0"), + PINCTRL_PIN(31, "NCSI_TXD1"), + PINCTRL_PIN(32, "NCSI_ARB_OUT"), + PINCTRL_PIN(33, "GBE_SMB_CLK"), + PINCTRL_PIN(34, "GBE_SMB_DATA"), + PINCTRL_PIN(35, "GBE_SMB_ALRT_N"), + PINCTRL_PIN(36, "THERMTRIP_N"), + PINCTRL_PIN(37, "PCHHOT_N"), + PINCTRL_PIN(38, "ERROR0_N"), + PINCTRL_PIN(39, "ERROR1_N"), + PINCTRL_PIN(40, "ERROR2_N"), + PINCTRL_PIN(41, "MSMI_N"), + PINCTRL_PIN(42, "CATERR_N"), + PINCTRL_PIN(43, "MEMTRIP_N"), + PINCTRL_PIN(44, "UART0_RXD"), + PINCTRL_PIN(45, "UART0_TXD"), + PINCTRL_PIN(46, "GBE_UART_RXD"), + PINCTRL_PIN(47, "GBE_UART_TXD"), + /* WEST01 */ + PINCTRL_PIN(48, "GBE_GPIO13"), + PINCTRL_PIN(49, "AUX_PWR"), + PINCTRL_PIN(50, "UART0_RTS"), + PINCTRL_PIN(51, "UART0_CTS"), + PINCTRL_PIN(52, "FAN_PWM_0"), + PINCTRL_PIN(53, "FAN_PWM_1"), + PINCTRL_PIN(54, "FAN_PWM_2"), + PINCTRL_PIN(55, "FAN_PWM_3"), + PINCTRL_PIN(56, "FAN_TACH_0"), + PINCTRL_PIN(57, "FAN_TACH_1"), + PINCTRL_PIN(58, "FAN_TACH_2"), + PINCTRL_PIN(59, "FAN_TACH_3"), + PINCTRL_PIN(60, "ME_SMB0_CLK"), + PINCTRL_PIN(61, "ME_SMB0_DATA"), + PINCTRL_PIN(62, "ME_SMB0_ALRT_N"), + PINCTRL_PIN(63, "ME_SMB1_CLK"), + PINCTRL_PIN(64, "ME_SMB1_DATA"), + PINCTRL_PIN(65, "ME_SMB1_ALRT_N"), + PINCTRL_PIN(66, "ME_SMB2_CLK"), + PINCTRL_PIN(67, "ME_SMB2_DATA"), + PINCTRL_PIN(68, "ME_SMB2_ALRT_N"), + PINCTRL_PIN(69, "GBE_MNG_I2C_CLK"), + PINCTRL_PIN(70, "GBE_MNG_I2C_DATA"), + /* WEST5 */ + PINCTRL_PIN(71, "IE_UART_RXD"), + PINCTRL_PIN(72, "IE_UART_TXD"), + PINCTRL_PIN(73, "VPP_SMB_CLK"), + PINCTRL_PIN(74, "VPP_SMB_DATA"), + PINCTRL_PIN(75, "VPP_SMB_ALRT_N"), + PINCTRL_PIN(76, "PCIE_CLKREQ0_N"), + PINCTRL_PIN(77, "PCIE_CLKREQ1_N"), + PINCTRL_PIN(78, "PCIE_CLKREQ2_N"), + PINCTRL_PIN(79, "PCIE_CLKREQ3_N"), + PINCTRL_PIN(80, "PCIE_CLKREQ4_N"), + PINCTRL_PIN(81, "PCIE_CLKREQ5_N"), + PINCTRL_PIN(82, "PCIE_CLKREQ6_N"), + PINCTRL_PIN(83, "PCIE_CLKREQ7_N"), + PINCTRL_PIN(84, "PCIE_CLKREQ8_N"), + PINCTRL_PIN(85, "PCIE_CLKREQ9_N"), + PINCTRL_PIN(86, "FLEX_CLK_SE0"), + PINCTRL_PIN(87, "FLEX_CLK_SE1"), + PINCTRL_PIN(88, "FLEX_CLK1_50"), + PINCTRL_PIN(89, "FLEX_CLK2_50"), + PINCTRL_PIN(90, "FLEX_CLK_125"), + /* WESTC */ + PINCTRL_PIN(91, "TCK_PCH"), + PINCTRL_PIN(92, "JTAGX_PCH"), + PINCTRL_PIN(93, "TRST_N_PCH"), + PINCTRL_PIN(94, "TMS_PCH"), + PINCTRL_PIN(95, "TDI_PCH"), + PINCTRL_PIN(96, "TDO_PCH"), + /* WESTC_DFX */ + PINCTRL_PIN(97, "CX_PRDY_N"), + PINCTRL_PIN(98, "CX_PREQ_N"), + PINCTRL_PIN(99, "CPU_FBREAK_OUT_N"), + PINCTRL_PIN(100, "TRIGGER0_N"), + PINCTRL_PIN(101, "TRIGGER1_N"), + /* WESTA */ + PINCTRL_PIN(102, "DBG_PTI_CLK0"), + PINCTRL_PIN(103, "DBG_PTI_CLK3"), + PINCTRL_PIN(104, "DBG_PTI_DATA0"), + PINCTRL_PIN(105, "DBG_PTI_DATA1"), + PINCTRL_PIN(106, "DBG_PTI_DATA2"), + PINCTRL_PIN(107, "DBG_PTI_DATA3"), + PINCTRL_PIN(108, "DBG_PTI_DATA4"), + PINCTRL_PIN(109, "DBG_PTI_DATA5"), + PINCTRL_PIN(110, "DBG_PTI_DATA6"), + PINCTRL_PIN(111, "DBG_PTI_DATA7"), + /* WESTB */ + PINCTRL_PIN(112, "DBG_PTI_DATA8"), + PINCTRL_PIN(113, "DBG_PTI_DATA9"), + PINCTRL_PIN(114, "DBG_PTI_DATA10"), + PINCTRL_PIN(115, "DBG_PTI_DATA11"), + PINCTRL_PIN(116, "DBG_PTI_DATA12"), + PINCTRL_PIN(117, "DBG_PTI_DATA13"), + PINCTRL_PIN(118, "DBG_PTI_DATA14"), + PINCTRL_PIN(119, "DBG_PTI_DATA15"), + PINCTRL_PIN(120, "DBG_SPARE0"), + PINCTRL_PIN(121, "DBG_SPARE1"), + PINCTRL_PIN(122, "DBG_SPARE2"), + PINCTRL_PIN(123, "DBG_SPARE3"), + /* WESTD */ + PINCTRL_PIN(124, "CPU_PWR_GOOD"), + PINCTRL_PIN(125, "PLTRST_CPU_N"), + PINCTRL_PIN(126, "NAC_RESET_NAC_N"), + PINCTRL_PIN(127, "PCH_SBLINK_RX"), + PINCTRL_PIN(128, "PCH_SBLINK_TX"), + PINCTRL_PIN(129, "PMSYNC_CLK"), + PINCTRL_PIN(130, "CPU_ERR0_N"), + PINCTRL_PIN(131, "CPU_ERR1_N"), + PINCTRL_PIN(132, "CPU_ERR2_N"), + PINCTRL_PIN(133, "CPU_THERMTRIP_N"), + PINCTRL_PIN(134, "CPU_MSMI_N"), + PINCTRL_PIN(135, "CPU_CATERR_N"), + PINCTRL_PIN(136, "CPU_MEMTRIP_N"), + PINCTRL_PIN(137, "NAC_GR_N"), + PINCTRL_PIN(138, "NAC_XTAL_VALID"), + PINCTRL_PIN(139, "NAC_WAKE_N"), + PINCTRL_PIN(140, "NAC_SBLINK_CLK_S2N"), + PINCTRL_PIN(141, "NAC_SBLINK_N2S"), + PINCTRL_PIN(142, "NAC_SBLINK_S2N"), + PINCTRL_PIN(143, "NAC_SBLINK_CLK_N2S"), + /* WESTD_PECI */ + PINCTRL_PIN(144, "ME_PECI"), + /* WESTF */ + PINCTRL_PIN(145, "NAC_RMII_CLK"), + PINCTRL_PIN(146, "NAC_RGMII_CLK"), + PINCTRL_PIN(147, "NAC_GBE_SMB_CLK_TX_N2S"), + PINCTRL_PIN(148, "NAC_GBE_SMB_DATA_TX_N2S"), + PINCTRL_PIN(149, "NAC_SPARE2"), + PINCTRL_PIN(150, "NAC_INIT_SX_WAKE_N"), + PINCTRL_PIN(151, "NAC_GBE_GPIO0_S2N"), + PINCTRL_PIN(152, "NAC_GBE_GPIO1_S2N"), + PINCTRL_PIN(153, "NAC_GBE_GPIO2_S2N"), + PINCTRL_PIN(154, "NAC_GBE_GPIO3_S2N"), + PINCTRL_PIN(155, "NAC_NCSI_RXD0"), + PINCTRL_PIN(156, "NAC_NCSI_CLK_IN"), + PINCTRL_PIN(157, "NAC_NCSI_RXD1"), + PINCTRL_PIN(158, "NAC_NCSI_CRS_DV"), + PINCTRL_PIN(159, "NAC_NCSI_ARB_IN"), + PINCTRL_PIN(160, "NAC_NCSI_TX_EN"), + PINCTRL_PIN(161, "NAC_NCSI_TXD0"), + PINCTRL_PIN(162, "NAC_NCSI_TXD1"), + PINCTRL_PIN(163, "NAC_NCSI_ARB_OUT"), + PINCTRL_PIN(164, "NAC_NCSI_OE_N"), + PINCTRL_PIN(165, "NAC_GBE_SMB_CLK_RX_S2N"), + PINCTRL_PIN(166, "NAC_GBE_SMB_DATA_RX_S2N"), + PINCTRL_PIN(167, "NAC_GBE_SMB_ALRT_N"), + /* EAST2 */ + PINCTRL_PIN(168, "USB_OC0_N"), + PINCTRL_PIN(169, "GBE_GPIO0"), + PINCTRL_PIN(170, "GBE_GPIO1"), + PINCTRL_PIN(171, "GBE_GPIO2"), + PINCTRL_PIN(172, "GBE_GPIO3"), + PINCTRL_PIN(173, "GBE_GPIO4"), + PINCTRL_PIN(174, "GBE_GPIO5"), + PINCTRL_PIN(175, "GBE_GPIO6"), + PINCTRL_PIN(176, "GBE_GPIO7"), + PINCTRL_PIN(177, "SPI_TPM_CS_N"), + PINCTRL_PIN(178, "GBE_GPIO9"), + PINCTRL_PIN(179, "GBE_GPIO10"), + PINCTRL_PIN(180, "GBE_GPIO11"), + PINCTRL_PIN(181, "GBE_GPIO12"), + PINCTRL_PIN(182, "PECI_SMB_DATA"), + PINCTRL_PIN(183, "SATA0_LED_N"), + PINCTRL_PIN(184, "SATA1_LED_N"), + PINCTRL_PIN(185, "SATA_PDETECT0"), + PINCTRL_PIN(186, "SATA_PDETECT1"), + PINCTRL_PIN(187, "SATA0_SDOUT"), + PINCTRL_PIN(188, "SATA1_SDOUT"), + PINCTRL_PIN(189, "SATA2_LED_N"), + PINCTRL_PIN(190, "SATA_PDETECT2"), + PINCTRL_PIN(191, "SATA2_SDOUT"), + /* EAST3 */ + PINCTRL_PIN(192, "ESPI_IO0"), + PINCTRL_PIN(193, "ESPI_IO1"), + PINCTRL_PIN(194, "ESPI_IO2"), + PINCTRL_PIN(195, "ESPI_IO3"), + PINCTRL_PIN(196, "ESPI_CLK"), + PINCTRL_PIN(197, "ESPI_RST_N"), + PINCTRL_PIN(198, "ESPI_CS0_N"), + PINCTRL_PIN(199, "ESPI_ALRT0_N"), + PINCTRL_PIN(200, "ESPI_CS1_N"), + PINCTRL_PIN(201, "ESPI_ALRT1_N"), + PINCTRL_PIN(202, "ESPI_CLK_LOOPBK"), + /* EAST0 */ + PINCTRL_PIN(203, "SPI_CS0_N"), + PINCTRL_PIN(204, "SPI_CS1_N"), + PINCTRL_PIN(205, "SPI_MOSI_IO0"), + PINCTRL_PIN(206, "SPI_MISO_IO1"), + PINCTRL_PIN(207, "SPI_IO2"), + PINCTRL_PIN(208, "SPI_IO3"), + PINCTRL_PIN(209, "SPI_CLK"), + PINCTRL_PIN(210, "SPI_CLK_LOOPBK"), + PINCTRL_PIN(211, "SUSPWRDNACK"), + PINCTRL_PIN(212, "PMU_SUSCLK"), + PINCTRL_PIN(213, "ADR_COMPLETE"), + PINCTRL_PIN(214, "ADR_TRIGGER_N"), + PINCTRL_PIN(215, "PMU_SLP_S45_N"), + PINCTRL_PIN(216, "PMU_SLP_S3_N"), + PINCTRL_PIN(217, "PMU_WAKE_N"), + PINCTRL_PIN(218, "PMU_PWRBTN_N"), + PINCTRL_PIN(219, "PMU_RESETBUTTON_N"), + PINCTRL_PIN(220, "PMU_PLTRST_N"), + PINCTRL_PIN(221, "SUS_STAT_N"), + PINCTRL_PIN(222, "PMU_I2C_CLK"), + PINCTRL_PIN(223, "PMU_I2C_DATA"), + PINCTRL_PIN(224, "PECI_SMB_CLK"), + PINCTRL_PIN(225, "PECI_SMB_ALRT_N"), + /* EMMC */ + PINCTRL_PIN(226, "EMMC_CMD"), + PINCTRL_PIN(227, "EMMC_STROBE"), + PINCTRL_PIN(228, "EMMC_CLK"), + PINCTRL_PIN(229, "EMMC_D0"), + PINCTRL_PIN(230, "EMMC_D1"), + PINCTRL_PIN(231, "EMMC_D2"), + PINCTRL_PIN(232, "EMMC_D3"), + PINCTRL_PIN(233, "EMMC_D4"), + PINCTRL_PIN(234, "EMMC_D5"), + PINCTRL_PIN(235, "EMMC_D6"), + PINCTRL_PIN(236, "EMMC_D7"), +}; + +static const struct intel_padgroup cdf_community0_gpps[] = { + CDF_GPP(0, 0, 23), /* WEST2 */ + CDF_GPP(1, 24, 47), /* WEST3 */ + CDF_GPP(2, 48, 70), /* WEST01 */ + CDF_GPP(3, 71, 90), /* WEST5 */ + CDF_GPP(4, 91, 96), /* WESTC */ + CDF_GPP(5, 97, 101), /* WESTC_DFX */ + CDF_GPP(6, 102, 111), /* WESTA */ + CDF_GPP(7, 112, 123), /* WESTB */ + CDF_GPP(8, 124, 143), /* WESTD */ + CDF_GPP(9, 144, 144), /* WESTD_PECI */ + CDF_GPP(10, 145, 167), /* WESTF */ +}; + +static const struct intel_padgroup cdf_community1_gpps[] = { + CDF_GPP(0, 168, 191), /* EAST2 */ + CDF_GPP(1, 192, 202), /* EAST3 */ + CDF_GPP(2, 203, 225), /* EAST0 */ + CDF_GPP(3, 226, 236), /* EMMC */ +}; + +static const struct intel_community cdf_communities[] = { + CDF_COMMUNITY(0, 0, 167, cdf_community0_gpps), /* West */ + CDF_COMMUNITY(1, 168, 236, cdf_community1_gpps), /* East */ +}; + +static const struct intel_pinctrl_soc_data cdf_soc_data = { + .pins = cdf_pins, + .npins = ARRAY_SIZE(cdf_pins), + .communities = cdf_communities, + .ncommunities = ARRAY_SIZE(cdf_communities), +}; + +static INTEL_PINCTRL_PM_OPS(cdf_pinctrl_pm_ops); + +static const struct acpi_device_id cdf_pinctrl_acpi_match[] = { + { "INTC3001", (kernel_ulong_t)&cdf_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, cdf_pinctrl_acpi_match); + +static struct platform_driver cdf_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "cedarfork-pinctrl", + .acpi_match_table = cdf_pinctrl_acpi_match, + .pm = &cdf_pinctrl_pm_ops, + }, +}; + +static int __init cdf_pinctrl_init(void) +{ + return platform_driver_register(&cdf_pinctrl_driver); +} +subsys_initcall(cdf_pinctrl_init); + +static void __exit cdf_pinctrl_exit(void) +{ + platform_driver_unregister(&cdf_pinctrl_driver); +} +module_exit(cdf_pinctrl_exit); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Cedar Fork PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c new file mode 100644 index 000000000..18b85ae84 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -0,0 +1,1835 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Cherryview/Braswell pinctrl driver + * + * Copyright (C) 2014, 2020 Intel Corporation + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> + * + * This driver is based on the original Cherryview GPIO driver by + * Ning Li <ning.li@intel.com> + * Alan Cox <alan@linux.intel.com> + */ + +#include <linux/acpi.h> +#include <linux/dmi.h> +#include <linux/gpio/driver.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/types.h> + +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> + +#include "pinctrl-intel.h" + +#define CHV_INTSTAT 0x300 +#define CHV_INTMASK 0x380 + +#define FAMILY_PAD_REGS_OFF 0x4400 +#define FAMILY_PAD_REGS_SIZE 0x400 +#define MAX_FAMILY_PAD_GPIO_NO 15 +#define GPIO_REGS_SIZE 8 + +#define CHV_PADCTRL0 0x000 +#define CHV_PADCTRL0_INTSEL_SHIFT 28 +#define CHV_PADCTRL0_INTSEL_MASK GENMASK(31, 28) +#define CHV_PADCTRL0_TERM_UP BIT(23) +#define CHV_PADCTRL0_TERM_SHIFT 20 +#define CHV_PADCTRL0_TERM_MASK GENMASK(22, 20) +#define CHV_PADCTRL0_TERM_20K 1 +#define CHV_PADCTRL0_TERM_5K 2 +#define CHV_PADCTRL0_TERM_1K 4 +#define CHV_PADCTRL0_PMODE_SHIFT 16 +#define CHV_PADCTRL0_PMODE_MASK GENMASK(19, 16) +#define CHV_PADCTRL0_GPIOEN BIT(15) +#define CHV_PADCTRL0_GPIOCFG_SHIFT 8 +#define CHV_PADCTRL0_GPIOCFG_MASK GENMASK(10, 8) +#define CHV_PADCTRL0_GPIOCFG_GPIO 0 +#define CHV_PADCTRL0_GPIOCFG_GPO 1 +#define CHV_PADCTRL0_GPIOCFG_GPI 2 +#define CHV_PADCTRL0_GPIOCFG_HIZ 3 +#define CHV_PADCTRL0_GPIOTXSTATE BIT(1) +#define CHV_PADCTRL0_GPIORXSTATE BIT(0) + +#define CHV_PADCTRL1 0x004 +#define CHV_PADCTRL1_CFGLOCK BIT(31) +#define CHV_PADCTRL1_INVRXTX_SHIFT 4 +#define CHV_PADCTRL1_INVRXTX_MASK GENMASK(7, 4) +#define CHV_PADCTRL1_INVRXTX_TXDATA BIT(7) +#define CHV_PADCTRL1_INVRXTX_RXDATA BIT(6) +#define CHV_PADCTRL1_INVRXTX_TXENABLE BIT(5) +#define CHV_PADCTRL1_ODEN BIT(3) +#define CHV_PADCTRL1_INTWAKECFG_MASK GENMASK(2, 0) +#define CHV_PADCTRL1_INTWAKECFG_FALLING 1 +#define CHV_PADCTRL1_INTWAKECFG_RISING 2 +#define CHV_PADCTRL1_INTWAKECFG_BOTH 3 +#define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 + +struct intel_pad_context { + u32 padctrl0; + u32 padctrl1; +}; + +/** + * struct intel_community_context - community context for Cherryview + * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space) + * @saved_intmask: Interrupt mask saved for system sleep + */ +struct intel_community_context { + unsigned int intr_lines[16]; + u32 saved_intmask; +}; + +#define PINMODE_INVERT_OE BIT(15) + +#define PINMODE(m, i) ((m) | ((i) * PINMODE_INVERT_OE)) + +#define CHV_GPP(start, end) \ + { \ + .base = (start), \ + .size = (end) - (start) + 1, \ + } + +#define CHV_COMMUNITY(g, i, a) \ + { \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + .nirqs = (i), \ + .acpi_space_id = (a), \ + } + +static const struct pinctrl_pin_desc southwest_pins[] = { + PINCTRL_PIN(0, "FST_SPI_D2"), + PINCTRL_PIN(1, "FST_SPI_D0"), + PINCTRL_PIN(2, "FST_SPI_CLK"), + PINCTRL_PIN(3, "FST_SPI_D3"), + PINCTRL_PIN(4, "FST_SPI_CS1_B"), + PINCTRL_PIN(5, "FST_SPI_D1"), + PINCTRL_PIN(6, "FST_SPI_CS0_B"), + PINCTRL_PIN(7, "FST_SPI_CS2_B"), + + PINCTRL_PIN(15, "UART1_RTS_B"), + PINCTRL_PIN(16, "UART1_RXD"), + PINCTRL_PIN(17, "UART2_RXD"), + PINCTRL_PIN(18, "UART1_CTS_B"), + PINCTRL_PIN(19, "UART2_RTS_B"), + PINCTRL_PIN(20, "UART1_TXD"), + PINCTRL_PIN(21, "UART2_TXD"), + PINCTRL_PIN(22, "UART2_CTS_B"), + + PINCTRL_PIN(30, "MF_HDA_CLK"), + PINCTRL_PIN(31, "MF_HDA_RSTB"), + PINCTRL_PIN(32, "MF_HDA_SDIO"), + PINCTRL_PIN(33, "MF_HDA_SDO"), + PINCTRL_PIN(34, "MF_HDA_DOCKRSTB"), + PINCTRL_PIN(35, "MF_HDA_SYNC"), + PINCTRL_PIN(36, "MF_HDA_SDI1"), + PINCTRL_PIN(37, "MF_HDA_DOCKENB"), + + PINCTRL_PIN(45, "I2C5_SDA"), + PINCTRL_PIN(46, "I2C4_SDA"), + PINCTRL_PIN(47, "I2C6_SDA"), + PINCTRL_PIN(48, "I2C5_SCL"), + PINCTRL_PIN(49, "I2C_NFC_SDA"), + PINCTRL_PIN(50, "I2C4_SCL"), + PINCTRL_PIN(51, "I2C6_SCL"), + PINCTRL_PIN(52, "I2C_NFC_SCL"), + + PINCTRL_PIN(60, "I2C1_SDA"), + PINCTRL_PIN(61, "I2C0_SDA"), + PINCTRL_PIN(62, "I2C2_SDA"), + PINCTRL_PIN(63, "I2C1_SCL"), + PINCTRL_PIN(64, "I2C3_SDA"), + PINCTRL_PIN(65, "I2C0_SCL"), + PINCTRL_PIN(66, "I2C2_SCL"), + PINCTRL_PIN(67, "I2C3_SCL"), + + PINCTRL_PIN(75, "SATA_GP0"), + PINCTRL_PIN(76, "SATA_GP1"), + PINCTRL_PIN(77, "SATA_LEDN"), + PINCTRL_PIN(78, "SATA_GP2"), + PINCTRL_PIN(79, "MF_SMB_ALERTB"), + PINCTRL_PIN(80, "SATA_GP3"), + PINCTRL_PIN(81, "MF_SMB_CLK"), + PINCTRL_PIN(82, "MF_SMB_DATA"), + + PINCTRL_PIN(90, "PCIE_CLKREQ0B"), + PINCTRL_PIN(91, "PCIE_CLKREQ1B"), + PINCTRL_PIN(92, "GP_SSP_2_CLK"), + PINCTRL_PIN(93, "PCIE_CLKREQ2B"), + PINCTRL_PIN(94, "GP_SSP_2_RXD"), + PINCTRL_PIN(95, "PCIE_CLKREQ3B"), + PINCTRL_PIN(96, "GP_SSP_2_FS"), + PINCTRL_PIN(97, "GP_SSP_2_TXD"), +}; + +static const unsigned southwest_uart0_pins[] = { 16, 20 }; +static const unsigned southwest_uart1_pins[] = { 15, 16, 18, 20 }; +static const unsigned southwest_uart2_pins[] = { 17, 19, 21, 22 }; +static const unsigned southwest_i2c0_pins[] = { 61, 65 }; +static const unsigned southwest_hda_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37 }; +static const unsigned southwest_lpe_pins[] = { + 30, 31, 32, 33, 34, 35, 36, 37, 92, 94, 96, 97, +}; +static const unsigned southwest_i2c1_pins[] = { 60, 63 }; +static const unsigned southwest_i2c2_pins[] = { 62, 66 }; +static const unsigned southwest_i2c3_pins[] = { 64, 67 }; +static const unsigned southwest_i2c4_pins[] = { 46, 50 }; +static const unsigned southwest_i2c5_pins[] = { 45, 48 }; +static const unsigned southwest_i2c6_pins[] = { 47, 51 }; +static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 }; +static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 }; + +/* Some of LPE I2S TXD pins need to have OE inversion set */ +static const unsigned int southwest_lpe_altfuncs[] = { + PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 30, 31, 32, 33 */ + PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 34, 35, 36, 37 */ + PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 1), /* 92, 94, 96, 97 */ +}; + +/* + * Two spi3 chipselects are available in different mode than the main spi3 + * functionality, which is using mode 2. + */ +static const unsigned int southwest_spi3_altfuncs[] = { + PINMODE(3, 0), PINMODE(2, 0), PINMODE(3, 0), PINMODE(2, 0), /* 76, 79, 80, 81 */ + PINMODE(2, 0), /* 82 */ +}; + +static const struct intel_pingroup southwest_groups[] = { + PIN_GROUP("uart0_grp", southwest_uart0_pins, PINMODE(2, 0)), + PIN_GROUP("uart1_grp", southwest_uart1_pins, PINMODE(1, 0)), + PIN_GROUP("uart2_grp", southwest_uart2_pins, PINMODE(1, 0)), + PIN_GROUP("hda_grp", southwest_hda_pins, PINMODE(2, 0)), + PIN_GROUP("i2c0_grp", southwest_i2c0_pins, PINMODE(1, 1)), + PIN_GROUP("i2c1_grp", southwest_i2c1_pins, PINMODE(1, 1)), + PIN_GROUP("i2c2_grp", southwest_i2c2_pins, PINMODE(1, 1)), + PIN_GROUP("i2c3_grp", southwest_i2c3_pins, PINMODE(1, 1)), + PIN_GROUP("i2c4_grp", southwest_i2c4_pins, PINMODE(1, 1)), + PIN_GROUP("i2c5_grp", southwest_i2c5_pins, PINMODE(1, 1)), + PIN_GROUP("i2c6_grp", southwest_i2c6_pins, PINMODE(1, 1)), + PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, PINMODE(2, 1)), + PIN_GROUP("lpe_grp", southwest_lpe_pins, southwest_lpe_altfuncs), + PIN_GROUP("spi3_grp", southwest_spi3_pins, southwest_spi3_altfuncs), +}; + +static const char * const southwest_uart0_groups[] = { "uart0_grp" }; +static const char * const southwest_uart1_groups[] = { "uart1_grp" }; +static const char * const southwest_uart2_groups[] = { "uart2_grp" }; +static const char * const southwest_hda_groups[] = { "hda_grp" }; +static const char * const southwest_lpe_groups[] = { "lpe_grp" }; +static const char * const southwest_i2c0_groups[] = { "i2c0_grp" }; +static const char * const southwest_i2c1_groups[] = { "i2c1_grp" }; +static const char * const southwest_i2c2_groups[] = { "i2c2_grp" }; +static const char * const southwest_i2c3_groups[] = { "i2c3_grp" }; +static const char * const southwest_i2c4_groups[] = { "i2c4_grp" }; +static const char * const southwest_i2c5_groups[] = { "i2c5_grp" }; +static const char * const southwest_i2c6_groups[] = { "i2c6_grp" }; +static const char * const southwest_i2c_nfc_groups[] = { "i2c_nfc_grp" }; +static const char * const southwest_spi3_groups[] = { "spi3_grp" }; + +/* + * Only do pinmuxing for certain LPSS devices for now. Rest of the pins are + * enabled only as GPIOs. + */ +static const struct intel_function southwest_functions[] = { + FUNCTION("uart0", southwest_uart0_groups), + FUNCTION("uart1", southwest_uart1_groups), + FUNCTION("uart2", southwest_uart2_groups), + FUNCTION("hda", southwest_hda_groups), + FUNCTION("lpe", southwest_lpe_groups), + FUNCTION("i2c0", southwest_i2c0_groups), + FUNCTION("i2c1", southwest_i2c1_groups), + FUNCTION("i2c2", southwest_i2c2_groups), + FUNCTION("i2c3", southwest_i2c3_groups), + FUNCTION("i2c4", southwest_i2c4_groups), + FUNCTION("i2c5", southwest_i2c5_groups), + FUNCTION("i2c6", southwest_i2c6_groups), + FUNCTION("i2c_nfc", southwest_i2c_nfc_groups), + FUNCTION("spi3", southwest_spi3_groups), +}; + +static const struct intel_padgroup southwest_gpps[] = { + CHV_GPP(0, 7), + CHV_GPP(15, 22), + CHV_GPP(30, 37), + CHV_GPP(45, 52), + CHV_GPP(60, 67), + CHV_GPP(75, 82), + CHV_GPP(90, 97), +}; + +/* + * Southwest community can generate GPIO interrupts only for the first 8 + * interrupts. The upper half (8-15) can only be used to trigger GPEs. + */ +static const struct intel_community southwest_communities[] = { + CHV_COMMUNITY(southwest_gpps, 8, 0x91), +}; + +static const struct intel_pinctrl_soc_data southwest_soc_data = { + .uid = "1", + .pins = southwest_pins, + .npins = ARRAY_SIZE(southwest_pins), + .groups = southwest_groups, + .ngroups = ARRAY_SIZE(southwest_groups), + .functions = southwest_functions, + .nfunctions = ARRAY_SIZE(southwest_functions), + .communities = southwest_communities, + .ncommunities = ARRAY_SIZE(southwest_communities), +}; + +static const struct pinctrl_pin_desc north_pins[] = { + PINCTRL_PIN(0, "GPIO_DFX_0"), + PINCTRL_PIN(1, "GPIO_DFX_3"), + PINCTRL_PIN(2, "GPIO_DFX_7"), + PINCTRL_PIN(3, "GPIO_DFX_1"), + PINCTRL_PIN(4, "GPIO_DFX_5"), + PINCTRL_PIN(5, "GPIO_DFX_4"), + PINCTRL_PIN(6, "GPIO_DFX_8"), + PINCTRL_PIN(7, "GPIO_DFX_2"), + PINCTRL_PIN(8, "GPIO_DFX_6"), + + PINCTRL_PIN(15, "GPIO_SUS0"), + PINCTRL_PIN(16, "SEC_GPIO_SUS10"), + PINCTRL_PIN(17, "GPIO_SUS3"), + PINCTRL_PIN(18, "GPIO_SUS7"), + PINCTRL_PIN(19, "GPIO_SUS1"), + PINCTRL_PIN(20, "GPIO_SUS5"), + PINCTRL_PIN(21, "SEC_GPIO_SUS11"), + PINCTRL_PIN(22, "GPIO_SUS4"), + PINCTRL_PIN(23, "SEC_GPIO_SUS8"), + PINCTRL_PIN(24, "GPIO_SUS2"), + PINCTRL_PIN(25, "GPIO_SUS6"), + PINCTRL_PIN(26, "CX_PREQ_B"), + PINCTRL_PIN(27, "SEC_GPIO_SUS9"), + + PINCTRL_PIN(30, "TRST_B"), + PINCTRL_PIN(31, "TCK"), + PINCTRL_PIN(32, "PROCHOT_B"), + PINCTRL_PIN(33, "SVIDO_DATA"), + PINCTRL_PIN(34, "TMS"), + PINCTRL_PIN(35, "CX_PRDY_B_2"), + PINCTRL_PIN(36, "TDO_2"), + PINCTRL_PIN(37, "CX_PRDY_B"), + PINCTRL_PIN(38, "SVIDO_ALERT_B"), + PINCTRL_PIN(39, "TDO"), + PINCTRL_PIN(40, "SVIDO_CLK"), + PINCTRL_PIN(41, "TDI"), + + PINCTRL_PIN(45, "GP_CAMERASB_05"), + PINCTRL_PIN(46, "GP_CAMERASB_02"), + PINCTRL_PIN(47, "GP_CAMERASB_08"), + PINCTRL_PIN(48, "GP_CAMERASB_00"), + PINCTRL_PIN(49, "GP_CAMERASB_06"), + PINCTRL_PIN(50, "GP_CAMERASB_10"), + PINCTRL_PIN(51, "GP_CAMERASB_03"), + PINCTRL_PIN(52, "GP_CAMERASB_09"), + PINCTRL_PIN(53, "GP_CAMERASB_01"), + PINCTRL_PIN(54, "GP_CAMERASB_07"), + PINCTRL_PIN(55, "GP_CAMERASB_11"), + PINCTRL_PIN(56, "GP_CAMERASB_04"), + + PINCTRL_PIN(60, "PANEL0_BKLTEN"), + PINCTRL_PIN(61, "HV_DDI0_HPD"), + PINCTRL_PIN(62, "HV_DDI2_DDC_SDA"), + PINCTRL_PIN(63, "PANEL1_BKLTCTL"), + PINCTRL_PIN(64, "HV_DDI1_HPD"), + PINCTRL_PIN(65, "PANEL0_BKLTCTL"), + PINCTRL_PIN(66, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(67, "HV_DDI2_DDC_SCL"), + PINCTRL_PIN(68, "HV_DDI2_HPD"), + PINCTRL_PIN(69, "PANEL1_VDDEN"), + PINCTRL_PIN(70, "PANEL1_BKLTEN"), + PINCTRL_PIN(71, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(72, "PANEL0_VDDEN"), +}; + +static const struct intel_padgroup north_gpps[] = { + CHV_GPP(0, 8), + CHV_GPP(15, 27), + CHV_GPP(30, 41), + CHV_GPP(45, 56), + CHV_GPP(60, 72), +}; + +/* + * North community can generate GPIO interrupts only for the first 8 + * interrupts. The upper half (8-15) can only be used to trigger GPEs. + */ +static const struct intel_community north_communities[] = { + CHV_COMMUNITY(north_gpps, 8, 0x92), +}; + +static const struct intel_pinctrl_soc_data north_soc_data = { + .uid = "2", + .pins = north_pins, + .npins = ARRAY_SIZE(north_pins), + .communities = north_communities, + .ncommunities = ARRAY_SIZE(north_communities), +}; + +static const struct pinctrl_pin_desc east_pins[] = { + PINCTRL_PIN(0, "PMU_SLP_S3_B"), + PINCTRL_PIN(1, "PMU_BATLOW_B"), + PINCTRL_PIN(2, "SUS_STAT_B"), + PINCTRL_PIN(3, "PMU_SLP_S0IX_B"), + PINCTRL_PIN(4, "PMU_AC_PRESENT"), + PINCTRL_PIN(5, "PMU_PLTRST_B"), + PINCTRL_PIN(6, "PMU_SUSCLK"), + PINCTRL_PIN(7, "PMU_SLP_LAN_B"), + PINCTRL_PIN(8, "PMU_PWRBTN_B"), + PINCTRL_PIN(9, "PMU_SLP_S4_B"), + PINCTRL_PIN(10, "PMU_WAKE_B"), + PINCTRL_PIN(11, "PMU_WAKE_LAN_B"), + + PINCTRL_PIN(15, "MF_ISH_GPIO_3"), + PINCTRL_PIN(16, "MF_ISH_GPIO_7"), + PINCTRL_PIN(17, "MF_ISH_I2C1_SCL"), + PINCTRL_PIN(18, "MF_ISH_GPIO_1"), + PINCTRL_PIN(19, "MF_ISH_GPIO_5"), + PINCTRL_PIN(20, "MF_ISH_GPIO_9"), + PINCTRL_PIN(21, "MF_ISH_GPIO_0"), + PINCTRL_PIN(22, "MF_ISH_GPIO_4"), + PINCTRL_PIN(23, "MF_ISH_GPIO_8"), + PINCTRL_PIN(24, "MF_ISH_GPIO_2"), + PINCTRL_PIN(25, "MF_ISH_GPIO_6"), + PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"), +}; + +static const struct intel_padgroup east_gpps[] = { + CHV_GPP(0, 11), + CHV_GPP(15, 26), +}; + +static const struct intel_community east_communities[] = { + CHV_COMMUNITY(east_gpps, 16, 0x93), +}; + +static const struct intel_pinctrl_soc_data east_soc_data = { + .uid = "3", + .pins = east_pins, + .npins = ARRAY_SIZE(east_pins), + .communities = east_communities, + .ncommunities = ARRAY_SIZE(east_communities), +}; + +static const struct pinctrl_pin_desc southeast_pins[] = { + PINCTRL_PIN(0, "MF_PLT_CLK0"), + PINCTRL_PIN(1, "PWM1"), + PINCTRL_PIN(2, "MF_PLT_CLK1"), + PINCTRL_PIN(3, "MF_PLT_CLK4"), + PINCTRL_PIN(4, "MF_PLT_CLK3"), + PINCTRL_PIN(5, "PWM0"), + PINCTRL_PIN(6, "MF_PLT_CLK5"), + PINCTRL_PIN(7, "MF_PLT_CLK2"), + + PINCTRL_PIN(15, "SDMMC2_D3_CD_B"), + PINCTRL_PIN(16, "SDMMC1_CLK"), + PINCTRL_PIN(17, "SDMMC1_D0"), + PINCTRL_PIN(18, "SDMMC2_D1"), + PINCTRL_PIN(19, "SDMMC2_CLK"), + PINCTRL_PIN(20, "SDMMC1_D2"), + PINCTRL_PIN(21, "SDMMC2_D2"), + PINCTRL_PIN(22, "SDMMC2_CMD"), + PINCTRL_PIN(23, "SDMMC1_CMD"), + PINCTRL_PIN(24, "SDMMC1_D1"), + PINCTRL_PIN(25, "SDMMC2_D0"), + PINCTRL_PIN(26, "SDMMC1_D3_CD_B"), + + PINCTRL_PIN(30, "SDMMC3_D1"), + PINCTRL_PIN(31, "SDMMC3_CLK"), + PINCTRL_PIN(32, "SDMMC3_D3"), + PINCTRL_PIN(33, "SDMMC3_D2"), + PINCTRL_PIN(34, "SDMMC3_CMD"), + PINCTRL_PIN(35, "SDMMC3_D0"), + + PINCTRL_PIN(45, "MF_LPC_AD2"), + PINCTRL_PIN(46, "LPC_CLKRUNB"), + PINCTRL_PIN(47, "MF_LPC_AD0"), + PINCTRL_PIN(48, "LPC_FRAMEB"), + PINCTRL_PIN(49, "MF_LPC_CLKOUT1"), + PINCTRL_PIN(50, "MF_LPC_AD3"), + PINCTRL_PIN(51, "MF_LPC_CLKOUT0"), + PINCTRL_PIN(52, "MF_LPC_AD1"), + + PINCTRL_PIN(60, "SPI1_MISO"), + PINCTRL_PIN(61, "SPI1_CSO_B"), + PINCTRL_PIN(62, "SPI1_CLK"), + PINCTRL_PIN(63, "MMC1_D6"), + PINCTRL_PIN(64, "SPI1_MOSI"), + PINCTRL_PIN(65, "MMC1_D5"), + PINCTRL_PIN(66, "SPI1_CS1_B"), + PINCTRL_PIN(67, "MMC1_D4_SD_WE"), + PINCTRL_PIN(68, "MMC1_D7"), + PINCTRL_PIN(69, "MMC1_RCLK"), + + PINCTRL_PIN(75, "USB_OC1_B"), + PINCTRL_PIN(76, "PMU_RESETBUTTON_B"), + PINCTRL_PIN(77, "GPIO_ALERT"), + PINCTRL_PIN(78, "SDMMC3_PWR_EN_B"), + PINCTRL_PIN(79, "ILB_SERIRQ"), + PINCTRL_PIN(80, "USB_OC0_B"), + PINCTRL_PIN(81, "SDMMC3_CD_B"), + PINCTRL_PIN(82, "SPKR"), + PINCTRL_PIN(83, "SUSPWRDNACK"), + PINCTRL_PIN(84, "SPARE_PIN"), + PINCTRL_PIN(85, "SDMMC3_1P8_EN"), +}; + +static const unsigned southeast_pwm0_pins[] = { 5 }; +static const unsigned southeast_pwm1_pins[] = { 1 }; +static const unsigned southeast_sdmmc1_pins[] = { + 16, 17, 20, 23, 24, 26, 63, 65, 67, 68, 69, +}; +static const unsigned southeast_sdmmc2_pins[] = { 15, 18, 19, 21, 22, 25 }; +static const unsigned southeast_sdmmc3_pins[] = { + 30, 31, 32, 33, 34, 35, 78, 81, 85, +}; +static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 }; +static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 }; + +static const struct intel_pingroup southeast_groups[] = { + PIN_GROUP("pwm0_grp", southeast_pwm0_pins, PINMODE(1, 0)), + PIN_GROUP("pwm1_grp", southeast_pwm1_pins, PINMODE(1, 0)), + PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, PINMODE(1, 0)), + PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, PINMODE(1, 0)), + PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, PINMODE(1, 0)), + PIN_GROUP("spi1_grp", southeast_spi1_pins, PINMODE(1, 0)), + PIN_GROUP("spi2_grp", southeast_spi2_pins, PINMODE(4, 0)), +}; + +static const char * const southeast_pwm0_groups[] = { "pwm0_grp" }; +static const char * const southeast_pwm1_groups[] = { "pwm1_grp" }; +static const char * const southeast_sdmmc1_groups[] = { "sdmmc1_grp" }; +static const char * const southeast_sdmmc2_groups[] = { "sdmmc2_grp" }; +static const char * const southeast_sdmmc3_groups[] = { "sdmmc3_grp" }; +static const char * const southeast_spi1_groups[] = { "spi1_grp" }; +static const char * const southeast_spi2_groups[] = { "spi2_grp" }; + +static const struct intel_function southeast_functions[] = { + FUNCTION("pwm0", southeast_pwm0_groups), + FUNCTION("pwm1", southeast_pwm1_groups), + FUNCTION("sdmmc1", southeast_sdmmc1_groups), + FUNCTION("sdmmc2", southeast_sdmmc2_groups), + FUNCTION("sdmmc3", southeast_sdmmc3_groups), + FUNCTION("spi1", southeast_spi1_groups), + FUNCTION("spi2", southeast_spi2_groups), +}; + +static const struct intel_padgroup southeast_gpps[] = { + CHV_GPP(0, 7), + CHV_GPP(15, 26), + CHV_GPP(30, 35), + CHV_GPP(45, 52), + CHV_GPP(60, 69), + CHV_GPP(75, 85), +}; + +static const struct intel_community southeast_communities[] = { + CHV_COMMUNITY(southeast_gpps, 16, 0x94), +}; + +static const struct intel_pinctrl_soc_data southeast_soc_data = { + .uid = "4", + .pins = southeast_pins, + .npins = ARRAY_SIZE(southeast_pins), + .groups = southeast_groups, + .ngroups = ARRAY_SIZE(southeast_groups), + .functions = southeast_functions, + .nfunctions = ARRAY_SIZE(southeast_functions), + .communities = southeast_communities, + .ncommunities = ARRAY_SIZE(southeast_communities), +}; + +static const struct intel_pinctrl_soc_data *chv_soc_data[] = { + &southwest_soc_data, + &north_soc_data, + &east_soc_data, + &southeast_soc_data, + NULL +}; + +/* + * Lock to serialize register accesses + * + * Due to a silicon issue, a shared lock must be used to prevent + * concurrent accesses across the 4 GPIO controllers. + * + * See Intel Atom Z8000 Processor Series Specification Update (Rev. 005), + * errata #CHT34, for further information. + */ +static DEFINE_RAW_SPINLOCK(chv_lock); + +static u32 chv_pctrl_readl(struct intel_pinctrl *pctrl, unsigned int offset) +{ + const struct intel_community *community = &pctrl->communities[0]; + + return readl(community->regs + offset); +} + +static void chv_pctrl_writel(struct intel_pinctrl *pctrl, unsigned int offset, u32 value) +{ + const struct intel_community *community = &pctrl->communities[0]; + void __iomem *reg = community->regs + offset; + + /* Write and simple read back to confirm the bus transferring done */ + writel(value, reg); + readl(reg); +} + +static void __iomem *chv_padreg(struct intel_pinctrl *pctrl, unsigned int offset, + unsigned int reg) +{ + const struct intel_community *community = &pctrl->communities[0]; + unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO; + unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; + + offset = FAMILY_PAD_REGS_SIZE * family_no + GPIO_REGS_SIZE * pad_no; + + return community->pad_regs + offset + reg; +} + +static u32 chv_readl(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int offset) +{ + return readl(chv_padreg(pctrl, pin, offset)); +} + +static void chv_writel(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int offset, u32 value) +{ + void __iomem *reg = chv_padreg(pctrl, pin, offset); + + /* Write and simple read back to confirm the bus transferring done */ + writel(value, reg); + readl(reg); +} + +/* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ +static bool chv_pad_locked(struct intel_pinctrl *pctrl, unsigned int offset) +{ + return chv_readl(pctrl, offset, CHV_PADCTRL1) & CHV_PADCTRL1_CFGLOCK; +} + +static int chv_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->ngroups; +} + +static const char *chv_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->groups[group].name; +} + +static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, + const unsigned int **pins, unsigned int *npins) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *pins = pctrl->soc->groups[group].pins; + *npins = pctrl->soc->groups[group].npins; + return 0; +} + +static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int offset) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + u32 ctrl0, ctrl1; + bool locked; + + raw_spin_lock_irqsave(&chv_lock, flags); + + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); + ctrl1 = chv_readl(pctrl, offset, CHV_PADCTRL1); + locked = chv_pad_locked(pctrl, offset); + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + if (ctrl0 & CHV_PADCTRL0_GPIOEN) { + seq_puts(s, "GPIO "); + } else { + u32 mode; + + mode = ctrl0 & CHV_PADCTRL0_PMODE_MASK; + mode >>= CHV_PADCTRL0_PMODE_SHIFT; + + seq_printf(s, "mode %d ", mode); + } + + seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1); + + if (locked) + seq_puts(s, " [LOCKED]"); +} + +static const struct pinctrl_ops chv_pinctrl_ops = { + .get_groups_count = chv_get_groups_count, + .get_group_name = chv_get_group_name, + .get_group_pins = chv_get_group_pins, + .pin_dbg_show = chv_pin_dbg_show, +}; + +static int chv_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->nfunctions; +} + +static const char *chv_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->functions[function].name; +} + +static int chv_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char * const **groups, + unsigned int * const ngroups) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *groups = pctrl->soc->functions[function].groups; + *ngroups = pctrl->soc->functions[function].ngroups; + return 0; +} + +static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pingroup *grp; + unsigned long flags; + int i; + + grp = &pctrl->soc->groups[group]; + + raw_spin_lock_irqsave(&chv_lock, flags); + + /* Check first that the pad is not locked */ + for (i = 0; i < grp->npins; i++) { + if (chv_pad_locked(pctrl, grp->pins[i])) { + dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n", + grp->pins[i]); + raw_spin_unlock_irqrestore(&chv_lock, flags); + return -EBUSY; + } + } + + for (i = 0; i < grp->npins; i++) { + int pin = grp->pins[i]; + unsigned int mode; + bool invert_oe; + u32 value; + + /* Check if there is pin-specific config */ + if (grp->modes) + mode = grp->modes[i]; + else + mode = grp->mode; + + /* Extract OE inversion */ + invert_oe = mode & PINMODE_INVERT_OE; + mode &= ~PINMODE_INVERT_OE; + + value = chv_readl(pctrl, pin, CHV_PADCTRL0); + /* Disable GPIO mode */ + value &= ~CHV_PADCTRL0_GPIOEN; + /* Set to desired mode */ + value &= ~CHV_PADCTRL0_PMODE_MASK; + value |= mode << CHV_PADCTRL0_PMODE_SHIFT; + chv_writel(pctrl, pin, CHV_PADCTRL0, value); + + /* Update for invert_oe */ + value = chv_readl(pctrl, pin, CHV_PADCTRL1) & ~CHV_PADCTRL1_INVRXTX_MASK; + if (invert_oe) + value |= CHV_PADCTRL1_INVRXTX_TXENABLE; + chv_writel(pctrl, pin, CHV_PADCTRL1, value); + + dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n", + pin, mode, invert_oe ? "" : "not "); + } + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static void chv_gpio_clear_triggering(struct intel_pinctrl *pctrl, + unsigned int offset) +{ + u32 invrxtx_mask = CHV_PADCTRL1_INVRXTX_MASK; + u32 value; + + /* + * One some devices the GPIO should output the inverted value from what + * device-drivers / ACPI code expects (inverted external buffer?). The + * BIOS makes this work by setting the CHV_PADCTRL1_INVRXTX_TXDATA flag, + * preserve this flag if the pin is already setup as GPIO. + */ + value = chv_readl(pctrl, offset, CHV_PADCTRL0); + if (value & CHV_PADCTRL0_GPIOEN) + invrxtx_mask &= ~CHV_PADCTRL1_INVRXTX_TXDATA; + + value = chv_readl(pctrl, offset, CHV_PADCTRL1); + value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; + value &= ~invrxtx_mask; + chv_writel(pctrl, offset, CHV_PADCTRL1, value); +} + +static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&chv_lock, flags); + + if (chv_pad_locked(pctrl, offset)) { + value = chv_readl(pctrl, offset, CHV_PADCTRL0); + if (!(value & CHV_PADCTRL0_GPIOEN)) { + /* Locked so cannot enable */ + raw_spin_unlock_irqrestore(&chv_lock, flags); + return -EBUSY; + } + } else { + struct intel_community_context *cctx = &pctrl->context.communities[0]; + int i; + + /* Reset the interrupt mapping */ + for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) { + if (cctx->intr_lines[i] == offset) { + cctx->intr_lines[i] = 0; + break; + } + } + + /* Disable interrupt generation */ + chv_gpio_clear_triggering(pctrl, offset); + + value = chv_readl(pctrl, offset, CHV_PADCTRL0); + + /* + * If the pin is in HiZ mode (both TX and RX buffers are + * disabled) we turn it to be input now. + */ + if ((value & CHV_PADCTRL0_GPIOCFG_MASK) == + (CHV_PADCTRL0_GPIOCFG_HIZ << CHV_PADCTRL0_GPIOCFG_SHIFT)) { + value &= ~CHV_PADCTRL0_GPIOCFG_MASK; + value |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; + } + + /* Switch to a GPIO mode */ + value |= CHV_PADCTRL0_GPIOEN; + chv_writel(pctrl, offset, CHV_PADCTRL0, value); + } + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static void chv_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + + raw_spin_lock_irqsave(&chv_lock, flags); + + if (!chv_pad_locked(pctrl, offset)) + chv_gpio_clear_triggering(pctrl, offset); + + raw_spin_unlock_irqrestore(&chv_lock, flags); +} + +static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset, bool input) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + unsigned long flags; + u32 ctrl0; + + raw_spin_lock_irqsave(&chv_lock, flags); + + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0) & ~CHV_PADCTRL0_GPIOCFG_MASK; + if (input) + ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; + else + ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; + chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static const struct pinmux_ops chv_pinmux_ops = { + .get_functions_count = chv_get_functions_count, + .get_function_name = chv_get_function_name, + .get_function_groups = chv_get_function_groups, + .set_mux = chv_pinmux_set_mux, + .gpio_request_enable = chv_gpio_request_enable, + .gpio_disable_free = chv_gpio_disable_free, + .gpio_set_direction = chv_gpio_set_direction, +}; + +static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned long flags; + u32 ctrl0, ctrl1; + u16 arg = 0; + u32 term; + + raw_spin_lock_irqsave(&chv_lock, flags); + ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); + ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (term) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if (!(ctrl0 & CHV_PADCTRL0_TERM_UP)) + return -EINVAL; + + switch (term) { + case CHV_PADCTRL0_TERM_20K: + arg = 20000; + break; + case CHV_PADCTRL0_TERM_5K: + arg = 5000; + break; + case CHV_PADCTRL0_TERM_1K: + arg = 1000; + break; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if (!term || (ctrl0 & CHV_PADCTRL0_TERM_UP)) + return -EINVAL; + + switch (term) { + case CHV_PADCTRL0_TERM_20K: + arg = 20000; + break; + case CHV_PADCTRL0_TERM_5K: + arg = 5000; + break; + } + + break; + + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { + u32 cfg; + + cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; + cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; + if (cfg != CHV_PADCTRL0_GPIOCFG_HIZ) + return -EINVAL; + + break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (ctrl1 & CHV_PADCTRL1_ODEN) + return -EINVAL; + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(ctrl1 & CHV_PADCTRL1_ODEN)) + return -EINVAL; + break; + } + + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int chv_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 arg) +{ + unsigned long flags; + u32 ctrl0, pull; + + raw_spin_lock_irqsave(&chv_lock, flags); + ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); + break; + + case PIN_CONFIG_BIAS_PULL_UP: + ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); + + switch (arg) { + case 1000: + /* For 1k there is only pull up */ + pull = CHV_PADCTRL0_TERM_1K << CHV_PADCTRL0_TERM_SHIFT; + break; + case 5000: + pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; + break; + case 20000: + pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; + break; + default: + raw_spin_unlock_irqrestore(&chv_lock, flags); + return -EINVAL; + } + + ctrl0 |= CHV_PADCTRL0_TERM_UP | pull; + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); + + switch (arg) { + case 5000: + pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; + break; + case 20000: + pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; + break; + default: + raw_spin_unlock_irqrestore(&chv_lock, flags); + return -EINVAL; + } + + ctrl0 |= pull; + break; + + default: + raw_spin_unlock_irqrestore(&chv_lock, flags); + return -EINVAL; + } + + chv_writel(pctrl, pin, CHV_PADCTRL0, ctrl0); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static int chv_config_set_oden(struct intel_pinctrl *pctrl, unsigned int pin, + bool enable) +{ + unsigned long flags; + u32 ctrl1; + + raw_spin_lock_irqsave(&chv_lock, flags); + ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); + + if (enable) + ctrl1 |= CHV_PADCTRL1_ODEN; + else + ctrl1 &= ~CHV_PADCTRL1_ODEN; + + chv_writel(pctrl, pin, CHV_PADCTRL1, ctrl1); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static int chv_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfigs) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param; + int i, ret; + u32 arg; + + if (chv_pad_locked(pctrl, pin)) + return -EBUSY; + + for (i = 0; i < nconfigs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = chv_config_set_pull(pctrl, pin, param, arg); + if (ret) + return ret; + break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + ret = chv_config_set_oden(pctrl, pin, false); + if (ret) + return ret; + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + ret = chv_config_set_oden(pctrl, pin, true); + if (ret) + return ret; + break; + + default: + return -ENOTSUPP; + } + + dev_dbg(pctrl->dev, "pin %d set config %d arg %u\n", pin, + param, arg); + } + + return 0; +} + +static int chv_config_group_get(struct pinctrl_dev *pctldev, + unsigned int group, + unsigned long *config) +{ + const unsigned int *pins; + unsigned int npins; + int ret; + + ret = chv_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + ret = chv_config_get(pctldev, pins[0], config); + if (ret) + return ret; + + return 0; +} + +static int chv_config_group_set(struct pinctrl_dev *pctldev, + unsigned int group, unsigned long *configs, + unsigned int num_configs) +{ + const unsigned int *pins; + unsigned int npins; + int i, ret; + + ret = chv_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + for (i = 0; i < npins; i++) { + ret = chv_config_set(pctldev, pins[i], configs, num_configs); + if (ret) + return ret; + } + + return 0; +} + +static const struct pinconf_ops chv_pinconf_ops = { + .is_generic = true, + .pin_config_set = chv_config_set, + .pin_config_get = chv_config_get, + .pin_config_group_get = chv_config_group_get, + .pin_config_group_set = chv_config_group_set, +}; + +static struct pinctrl_desc chv_pinctrl_desc = { + .pctlops = &chv_pinctrl_ops, + .pmxops = &chv_pinmux_ops, + .confops = &chv_pinconf_ops, + .owner = THIS_MODULE, +}; + +static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + unsigned long flags; + u32 ctrl0, cfg; + + raw_spin_lock_irqsave(&chv_lock, flags); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; + cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; + + if (cfg == CHV_PADCTRL0_GPIOCFG_GPO) + return !!(ctrl0 & CHV_PADCTRL0_GPIOTXSTATE); + return !!(ctrl0 & CHV_PADCTRL0_GPIORXSTATE); +} + +static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + unsigned long flags; + u32 ctrl0; + + raw_spin_lock_irqsave(&chv_lock, flags); + + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); + + if (value) + ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE; + else + ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE; + + chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); + + raw_spin_unlock_irqrestore(&chv_lock, flags); +} + +static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + u32 ctrl0, direction; + unsigned long flags; + + raw_spin_lock_irqsave(&chv_lock, flags); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; + direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT; + + if (direction == CHV_PADCTRL0_GPIOCFG_GPO) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + return pinctrl_gpio_direction_input(chip->base + offset); +} + +static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) +{ + chv_gpio_set(chip, offset, value); + return pinctrl_gpio_direction_output(chip->base + offset); +} + +static const struct gpio_chip chv_gpio_chip = { + .owner = THIS_MODULE, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .get_direction = chv_gpio_get_direction, + .direction_input = chv_gpio_direction_input, + .direction_output = chv_gpio_direction_output, + .get = chv_gpio_get, + .set = chv_gpio_set, +}; + +static void chv_gpio_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + int pin = irqd_to_hwirq(d); + u32 intr_line; + + raw_spin_lock(&chv_lock); + + intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); + intr_line &= CHV_PADCTRL0_INTSEL_MASK; + intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; + chv_pctrl_writel(pctrl, CHV_INTSTAT, BIT(intr_line)); + + raw_spin_unlock(&chv_lock); +} + +static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + int pin = irqd_to_hwirq(d); + u32 value, intr_line; + unsigned long flags; + + raw_spin_lock_irqsave(&chv_lock, flags); + + intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); + intr_line &= CHV_PADCTRL0_INTSEL_MASK; + intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; + + value = chv_pctrl_readl(pctrl, CHV_INTMASK); + if (mask) + value &= ~BIT(intr_line); + else + value |= BIT(intr_line); + chv_pctrl_writel(pctrl, CHV_INTMASK, value); + + raw_spin_unlock_irqrestore(&chv_lock, flags); +} + +static void chv_gpio_irq_mask(struct irq_data *d) +{ + chv_gpio_irq_mask_unmask(d, true); +} + +static void chv_gpio_irq_unmask(struct irq_data *d) +{ + chv_gpio_irq_mask_unmask(d, false); +} + +static unsigned chv_gpio_irq_startup(struct irq_data *d) +{ + /* + * Check if the interrupt has been requested with 0 as triggering + * type. In that case it is assumed that the current values + * programmed to the hardware are used (e.g BIOS configured + * defaults). + * + * In that case ->irq_set_type() will never be called so we need to + * read back the values from hardware now, set correct flow handler + * and update mappings before the interrupt is being used. + */ + if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) { + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_community_context *cctx = &pctrl->context.communities[0]; + unsigned int pin = irqd_to_hwirq(d); + irq_flow_handler_t handler; + unsigned long flags; + u32 intsel, value; + + raw_spin_lock_irqsave(&chv_lock, flags); + intsel = chv_readl(pctrl, pin, CHV_PADCTRL0); + intsel &= CHV_PADCTRL0_INTSEL_MASK; + intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; + + value = chv_readl(pctrl, pin, CHV_PADCTRL1); + if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL) + handler = handle_level_irq; + else + handler = handle_edge_irq; + + if (!cctx->intr_lines[intsel]) { + irq_set_handler_locked(d, handler); + cctx->intr_lines[intsel] = pin; + } + raw_spin_unlock_irqrestore(&chv_lock, flags); + } + + chv_gpio_irq_unmask(d); + return 0; +} + +static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + struct intel_community_context *cctx = &pctrl->context.communities[0]; + unsigned int pin = irqd_to_hwirq(d); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&chv_lock, flags); + + /* + * Pins which can be used as shared interrupt are configured in + * BIOS. Driver trusts BIOS configurations and assigns different + * handler according to the irq type. + * + * Driver needs to save the mapping between each pin and + * its interrupt line. + * 1. If the pin cfg is locked in BIOS: + * Trust BIOS has programmed IntWakeCfg bits correctly, + * driver just needs to save the mapping. + * 2. If the pin cfg is not locked in BIOS: + * Driver programs the IntWakeCfg bits and save the mapping. + */ + if (!chv_pad_locked(pctrl, pin)) { + value = chv_readl(pctrl, pin, CHV_PADCTRL1); + value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; + value &= ~CHV_PADCTRL1_INVRXTX_MASK; + + if (type & IRQ_TYPE_EDGE_BOTH) { + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) + value |= CHV_PADCTRL1_INTWAKECFG_BOTH; + else if (type & IRQ_TYPE_EDGE_RISING) + value |= CHV_PADCTRL1_INTWAKECFG_RISING; + else if (type & IRQ_TYPE_EDGE_FALLING) + value |= CHV_PADCTRL1_INTWAKECFG_FALLING; + } else if (type & IRQ_TYPE_LEVEL_MASK) { + value |= CHV_PADCTRL1_INTWAKECFG_LEVEL; + if (type & IRQ_TYPE_LEVEL_LOW) + value |= CHV_PADCTRL1_INVRXTX_RXDATA; + } + + chv_writel(pctrl, pin, CHV_PADCTRL1, value); + } + + value = chv_readl(pctrl, pin, CHV_PADCTRL0); + value &= CHV_PADCTRL0_INTSEL_MASK; + value >>= CHV_PADCTRL0_INTSEL_SHIFT; + + cctx->intr_lines[value] = pin; + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static void chv_gpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + const struct intel_community *community = &pctrl->communities[0]; + struct intel_community_context *cctx = &pctrl->context.communities[0]; + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned long pending; + unsigned long flags; + u32 intr_line; + + chained_irq_enter(chip, desc); + + raw_spin_lock_irqsave(&chv_lock, flags); + pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + for_each_set_bit(intr_line, &pending, community->nirqs) { + unsigned int irq, offset; + + offset = cctx->intr_lines[intr_line]; + irq = irq_find_mapping(gc->irq.domain, offset); + generic_handle_irq(irq); + } + + chained_irq_exit(chip, desc); +} + +/* + * Certain machines seem to hardcode Linux IRQ numbers in their ACPI + * tables. Since we leave GPIOs that are not capable of generating + * interrupts out of the irqdomain the numbering will be different and + * cause devices using the hardcoded IRQ numbers fail. In order not to + * break such machines we will only mask pins from irqdomain if the machine + * is not listed below. + */ +static const struct dmi_system_id chv_no_valid_mask[] = { + /* See https://bugzilla.kernel.org/show_bug.cgi?id=194945 */ + { + .ident = "Intel_Strago based Chromebooks (All models)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"), + }, + }, + { + .ident = "HP Chromebook 11 G5 (Setzer)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), + }, + }, + { + .ident = "Acer Chromebook R11 (Cyan)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"), + }, + }, + { + .ident = "Samsung Chromebook 3 (Celes)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Celes"), + }, + }, + {} +}; + +static void chv_init_irq_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + const struct intel_community *community = &pctrl->communities[0]; + int i; + + /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ + for (i = 0; i < pctrl->soc->npins; i++) { + const struct pinctrl_pin_desc *desc; + u32 intsel; + + desc = &pctrl->soc->pins[i]; + + intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + intsel &= CHV_PADCTRL0_INTSEL_MASK; + intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; + + if (intsel >= community->nirqs) + clear_bit(desc->number, valid_mask); + } +} + +static int chv_gpio_irq_init_hw(struct gpio_chip *chip) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + const struct intel_community *community = &pctrl->communities[0]; + + /* + * The same set of machines in chv_no_valid_mask[] have incorrectly + * configured GPIOs that generate spurious interrupts so we use + * this same list to apply another quirk for them. + * + * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. + */ + if (!pctrl->chip.irq.init_valid_mask) { + /* + * Mask all interrupts the community is able to generate + * but leave the ones that can only generate GPEs unmasked. + */ + chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs)); + } + + /* Clear all interrupts */ + chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); + + return 0; +} + +static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + const struct intel_community *community = &pctrl->communities[0]; + const struct intel_padgroup *gpp; + int ret, i; + + for (i = 0; i < community->ngpps; i++) { + gpp = &community->gpps[i]; + ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), + gpp->base, gpp->base, + gpp->size); + if (ret) { + dev_err(pctrl->dev, "failed to add GPIO pin range\n"); + return ret; + } + } + + return 0; +} + +static int chv_gpio_probe(struct intel_pinctrl *pctrl, int irq) +{ + const struct intel_community *community = &pctrl->communities[0]; + const struct intel_padgroup *gpp; + struct gpio_chip *chip = &pctrl->chip; + bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); + int ret, i, irq_base; + + *chip = chv_gpio_chip; + + chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1; + chip->label = dev_name(pctrl->dev); + chip->add_pin_ranges = chv_gpio_add_pin_ranges; + chip->parent = pctrl->dev; + chip->base = -1; + + pctrl->irq = irq; + pctrl->irqchip.name = "chv-gpio"; + pctrl->irqchip.irq_startup = chv_gpio_irq_startup; + pctrl->irqchip.irq_ack = chv_gpio_irq_ack; + pctrl->irqchip.irq_mask = chv_gpio_irq_mask; + pctrl->irqchip.irq_unmask = chv_gpio_irq_unmask; + pctrl->irqchip.irq_set_type = chv_gpio_irq_type; + pctrl->irqchip.flags = IRQCHIP_SKIP_SET_WAKE; + + chip->irq.chip = &pctrl->irqchip; + chip->irq.init_hw = chv_gpio_irq_init_hw; + chip->irq.parent_handler = chv_gpio_irq_handler; + chip->irq.num_parents = 1; + chip->irq.parents = &pctrl->irq; + chip->irq.default_type = IRQ_TYPE_NONE; + chip->irq.handler = handle_bad_irq; + if (need_valid_mask) { + chip->irq.init_valid_mask = chv_init_irq_valid_mask; + } else { + irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, + pctrl->soc->npins, NUMA_NO_NODE); + if (irq_base < 0) { + dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); + return irq_base; + } + } + + ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); + if (ret) { + dev_err(pctrl->dev, "Failed to register gpiochip\n"); + return ret; + } + + if (!need_valid_mask) { + for (i = 0; i < community->ngpps; i++) { + gpp = &community->gpps[i]; + + irq_domain_associate_many(chip->irq.domain, irq_base, + gpp->base, gpp->size); + irq_base += gpp->size; + } + } + + return 0; +} + +static acpi_status chv_pinctrl_mmio_access_handler(u32 function, + acpi_physical_address address, u32 bits, u64 *value, + void *handler_context, void *region_context) +{ + struct intel_pinctrl *pctrl = region_context; + unsigned long flags; + acpi_status ret = AE_OK; + + raw_spin_lock_irqsave(&chv_lock, flags); + + if (function == ACPI_WRITE) + chv_pctrl_writel(pctrl, address, *value); + else if (function == ACPI_READ) + *value = chv_pctrl_readl(pctrl, address); + else + ret = AE_BAD_PARAMETER; + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return ret; +} + +static int chv_pinctrl_probe(struct platform_device *pdev) +{ + const struct intel_pinctrl_soc_data *soc_data; + struct intel_community *community; + struct device *dev = &pdev->dev; + struct intel_pinctrl *pctrl; + acpi_status status; + int ret, irq; + + soc_data = intel_pinctrl_get_soc_data(pdev); + if (IS_ERR(soc_data)) + return PTR_ERR(soc_data); + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + pctrl->dev = dev; + pctrl->soc = soc_data; + + pctrl->ncommunities = pctrl->soc->ncommunities; + pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities, + pctrl->ncommunities * sizeof(*pctrl->communities), + GFP_KERNEL); + if (!pctrl->communities) + return -ENOMEM; + + community = &pctrl->communities[0]; + community->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(community->regs)) + return PTR_ERR(community->regs); + + community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF; + +#ifdef CONFIG_PM_SLEEP + pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins, + sizeof(*pctrl->context.pads), + GFP_KERNEL); + if (!pctrl->context.pads) + return -ENOMEM; +#endif + + pctrl->context.communities = devm_kcalloc(dev, pctrl->soc->ncommunities, + sizeof(*pctrl->context.communities), + GFP_KERNEL); + if (!pctrl->context.communities) + return -ENOMEM; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + pctrl->pctldesc = chv_pinctrl_desc; + pctrl->pctldesc.name = dev_name(dev); + pctrl->pctldesc.pins = pctrl->soc->pins; + pctrl->pctldesc.npins = pctrl->soc->npins; + + pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); + if (IS_ERR(pctrl->pctldev)) { + dev_err(dev, "failed to register pinctrl driver\n"); + return PTR_ERR(pctrl->pctldev); + } + + ret = chv_gpio_probe(pctrl, irq); + if (ret) + return ret; + + status = acpi_install_address_space_handler(ACPI_HANDLE(dev), + community->acpi_space_id, + chv_pinctrl_mmio_access_handler, + NULL, pctrl); + if (ACPI_FAILURE(status)) + dev_err(dev, "failed to install ACPI addr space handler\n"); + + platform_set_drvdata(pdev, pctrl); + + return 0; +} + +static int chv_pinctrl_remove(struct platform_device *pdev) +{ + struct intel_pinctrl *pctrl = platform_get_drvdata(pdev); + const struct intel_community *community = &pctrl->communities[0]; + + acpi_remove_address_space_handler(ACPI_HANDLE(&pdev->dev), + community->acpi_space_id, + chv_pinctrl_mmio_access_handler); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int chv_pinctrl_suspend_noirq(struct device *dev) +{ + struct intel_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_community_context *cctx = &pctrl->context.communities[0]; + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&chv_lock, flags); + + cctx->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); + + for (i = 0; i < pctrl->soc->npins; i++) { + const struct pinctrl_pin_desc *desc; + struct intel_pad_context *ctx = &pctrl->context.pads[i]; + + desc = &pctrl->soc->pins[i]; + if (chv_pad_locked(pctrl, desc->number)) + continue; + + ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; + + ctx->padctrl1 = chv_readl(pctrl, desc->number, CHV_PADCTRL1); + } + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static int chv_pinctrl_resume_noirq(struct device *dev) +{ + struct intel_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_community_context *cctx = &pctrl->context.communities[0]; + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&chv_lock, flags); + + /* + * Mask all interrupts before restoring per-pin configuration + * registers because we don't know in which state BIOS left them + * upon exiting suspend. + */ + chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); + + for (i = 0; i < pctrl->soc->npins; i++) { + const struct pinctrl_pin_desc *desc; + struct intel_pad_context *ctx = &pctrl->context.pads[i]; + u32 val; + + desc = &pctrl->soc->pins[i]; + if (chv_pad_locked(pctrl, desc->number)) + continue; + + /* Only restore if our saved state differs from the current */ + val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + val &= ~CHV_PADCTRL0_GPIORXSTATE; + if (ctx->padctrl0 != val) { + chv_writel(pctrl, desc->number, CHV_PADCTRL0, ctx->padctrl0); + dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n", + desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL0)); + } + + val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); + if (ctx->padctrl1 != val) { + chv_writel(pctrl, desc->number, CHV_PADCTRL1, ctx->padctrl1); + dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n", + desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL1)); + } + } + + /* + * Now that all pins are restored to known state, we can restore + * the interrupt mask register as well. + */ + chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); + chv_pctrl_writel(pctrl, CHV_INTMASK, cctx->saved_intmask); + + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} +#endif + +static const struct dev_pm_ops chv_pinctrl_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend_noirq, + chv_pinctrl_resume_noirq) +}; + +static const struct acpi_device_id chv_pinctrl_acpi_match[] = { + { "INT33FF", (kernel_ulong_t)chv_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); + +static struct platform_driver chv_pinctrl_driver = { + .probe = chv_pinctrl_probe, + .remove = chv_pinctrl_remove, + .driver = { + .name = "cherryview-pinctrl", + .pm = &chv_pinctrl_pm_ops, + .acpi_match_table = chv_pinctrl_acpi_match, + }, +}; + +static int __init chv_pinctrl_init(void) +{ + return platform_driver_register(&chv_pinctrl_driver); +} +subsys_initcall(chv_pinctrl_init); + +static void __exit chv_pinctrl_exit(void) +{ + platform_driver_unregister(&chv_pinctrl_driver); +} +module_exit(chv_pinctrl_exit); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Cherryview/Braswell pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-denverton.c b/drivers/pinctrl/intel/pinctrl-denverton.c new file mode 100644 index 000000000..f26d030b9 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-denverton.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Denverton SoC pinctrl/GPIO driver + * + * Copyright (C) 2017, Intel Corporation + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define DNV_PAD_OWN 0x020 +#define DNV_PADCFGLOCK 0x090 +#define DNV_HOSTSW_OWN 0x0C0 +#define DNV_GPI_IS 0x100 +#define DNV_GPI_IE 0x120 + +#define DNV_GPP(n, s, e) \ + { \ + .reg_num = (n), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + } + +#define DNV_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = DNV_PAD_OWN, \ + .padcfglock_offset = DNV_PADCFGLOCK, \ + .hostown_offset = DNV_HOSTSW_OWN, \ + .is_offset = DNV_GPI_IS, \ + .ie_offset = DNV_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Denverton */ +static const struct pinctrl_pin_desc dnv_pins[] = { + /* North ALL */ + PINCTRL_PIN(0, "GBE0_SDP0"), + PINCTRL_PIN(1, "GBE1_SDP0"), + PINCTRL_PIN(2, "GBE0_SDP1"), + PINCTRL_PIN(3, "GBE1_SDP1"), + PINCTRL_PIN(4, "GBE0_SDP2"), + PINCTRL_PIN(5, "GBE1_SDP2"), + PINCTRL_PIN(6, "GBE0_SDP3"), + PINCTRL_PIN(7, "GBE1_SDP3"), + PINCTRL_PIN(8, "GBE2_LED0"), + PINCTRL_PIN(9, "GBE2_LED1"), + PINCTRL_PIN(10, "GBE0_I2C_CLK"), + PINCTRL_PIN(11, "GBE0_I2C_DATA"), + PINCTRL_PIN(12, "GBE1_I2C_CLK"), + PINCTRL_PIN(13, "GBE1_I2C_DATA"), + PINCTRL_PIN(14, "NCSI_RXD0"), + PINCTRL_PIN(15, "NCSI_CLK_IN"), + PINCTRL_PIN(16, "NCSI_RXD1"), + PINCTRL_PIN(17, "NCSI_CRS_DV"), + PINCTRL_PIN(18, "IDSLDO_VID_TICKLE"), + PINCTRL_PIN(19, "NCSI_TX_EN"), + PINCTRL_PIN(20, "NCSI_TXD0"), + PINCTRL_PIN(21, "NCSI_TXD1"), + PINCTRL_PIN(22, "NCSI_ARB_OUT"), + PINCTRL_PIN(23, "GBE0_LED0"), + PINCTRL_PIN(24, "GBE0_LED1"), + PINCTRL_PIN(25, "GBE1_LED0"), + PINCTRL_PIN(26, "GBE1_LED1"), + PINCTRL_PIN(27, "SPARE_0"), + PINCTRL_PIN(28, "PCIE_CLKREQ0_N"), + PINCTRL_PIN(29, "PCIE_CLKREQ1_N"), + PINCTRL_PIN(30, "PCIE_CLKREQ2_N"), + PINCTRL_PIN(31, "PCIE_CLKREQ3_N"), + PINCTRL_PIN(32, "PCIE_CLKREQ4_N"), + PINCTRL_PIN(33, "GBE_MDC"), + PINCTRL_PIN(34, "GBE_MDIO"), + PINCTRL_PIN(35, "SVID_ALERT_N"), + PINCTRL_PIN(36, "SVID_DATA"), + PINCTRL_PIN(37, "SVID_CLK"), + PINCTRL_PIN(38, "THERMTRIP_N"), + PINCTRL_PIN(39, "PROCHOT_N"), + PINCTRL_PIN(40, "MEMHOT_N"), + /* South DFX */ + PINCTRL_PIN(41, "DFX_PORT_CLK0"), + PINCTRL_PIN(42, "DFX_PORT_CLK1"), + PINCTRL_PIN(43, "DFX_PORT0"), + PINCTRL_PIN(44, "DFX_PORT1"), + PINCTRL_PIN(45, "DFX_PORT2"), + PINCTRL_PIN(46, "DFX_PORT3"), + PINCTRL_PIN(47, "DFX_PORT4"), + PINCTRL_PIN(48, "DFX_PORT5"), + PINCTRL_PIN(49, "DFX_PORT6"), + PINCTRL_PIN(50, "DFX_PORT7"), + PINCTRL_PIN(51, "DFX_PORT8"), + PINCTRL_PIN(52, "DFX_PORT9"), + PINCTRL_PIN(53, "DFX_PORT10"), + PINCTRL_PIN(54, "DFX_PORT11"), + PINCTRL_PIN(55, "DFX_PORT12"), + PINCTRL_PIN(56, "DFX_PORT13"), + PINCTRL_PIN(57, "DFX_PORT14"), + PINCTRL_PIN(58, "DFX_PORT15"), + /* South GPP0 */ + PINCTRL_PIN(59, "SPI_TPM_CS_N"), + PINCTRL_PIN(60, "UART2_CTS"), + PINCTRL_PIN(61, "PCIE_CLKREQ5_N"), + PINCTRL_PIN(62, "PCIE_CLKREQ6_N"), + PINCTRL_PIN(63, "PCIE_CLKREQ7_N"), + PINCTRL_PIN(64, "UART0_RXD"), + PINCTRL_PIN(65, "UART0_TXD"), + PINCTRL_PIN(66, "CPU_RESET_N"), + PINCTRL_PIN(67, "NMI"), + PINCTRL_PIN(68, "ERROR2_N"), + PINCTRL_PIN(69, "ERROR1_N"), + PINCTRL_PIN(70, "ERROR0_N"), + PINCTRL_PIN(71, "IERR_N"), + PINCTRL_PIN(72, "MCERR_N"), + PINCTRL_PIN(73, "SMB0_LEG_CLK"), + PINCTRL_PIN(74, "SMB0_LEG_DATA"), + PINCTRL_PIN(75, "SMB0_LEG_ALRT_N"), + PINCTRL_PIN(76, "SMB1_HOST_DATA"), + PINCTRL_PIN(77, "SMB1_HOST_CLK"), + PINCTRL_PIN(78, "SMB2_PECI_DATA"), + PINCTRL_PIN(79, "SMB2_PECI_CLK"), + PINCTRL_PIN(80, "SMB4_CSME0_DATA"), + PINCTRL_PIN(81, "SMB4_CSME0_CLK"), + PINCTRL_PIN(82, "SMB4_CSME0_ALRT_N"), + PINCTRL_PIN(83, "USB_OC0_N"), + PINCTRL_PIN(84, "FLEX_CLK_SE0"), + PINCTRL_PIN(85, "FLEX_CLK_SE1"), + PINCTRL_PIN(86, "SPARE_4"), + PINCTRL_PIN(87, "SMB3_IE0_CLK"), + PINCTRL_PIN(88, "SMB3_IE0_DATA"), + PINCTRL_PIN(89, "SMB3_IE0_ALRT_N"), + PINCTRL_PIN(90, "SATA0_LED_N"), + PINCTRL_PIN(91, "SATA1_LED_N"), + PINCTRL_PIN(92, "SATA_PDETECT0"), + PINCTRL_PIN(93, "SATA_PDETECT1"), + PINCTRL_PIN(94, "UART1_RTS"), + PINCTRL_PIN(95, "UART1_CTS"), + PINCTRL_PIN(96, "UART1_RXD"), + PINCTRL_PIN(97, "UART1_TXD"), + PINCTRL_PIN(98, "SPARE_8"), + PINCTRL_PIN(99, "SPARE_9"), + PINCTRL_PIN(100, "TCK"), + PINCTRL_PIN(101, "TRST_N"), + PINCTRL_PIN(102, "TMS"), + PINCTRL_PIN(103, "TDI"), + PINCTRL_PIN(104, "TDO"), + PINCTRL_PIN(105, "CX_PRDY_N"), + PINCTRL_PIN(106, "CX_PREQ_N"), + PINCTRL_PIN(107, "TAP1_TCK"), + PINCTRL_PIN(108, "TAP1_TRST_N"), + PINCTRL_PIN(109, "TAP1_TMS"), + PINCTRL_PIN(110, "TAP1_TDI"), + PINCTRL_PIN(111, "TAP1_TDO"), + /* South GPP1 */ + PINCTRL_PIN(112, "SUSPWRDNACK"), + PINCTRL_PIN(113, "PMU_SUSCLK"), + PINCTRL_PIN(114, "ADR_TRIGGER"), + PINCTRL_PIN(115, "PMU_SLP_S45_N"), + PINCTRL_PIN(116, "PMU_SLP_S3_N"), + PINCTRL_PIN(117, "PMU_WAKE_N"), + PINCTRL_PIN(118, "PMU_PWRBTN_N"), + PINCTRL_PIN(119, "PMU_RESETBUTTON_N"), + PINCTRL_PIN(120, "PMU_PLTRST_N"), + PINCTRL_PIN(121, "SUS_STAT_N"), + PINCTRL_PIN(122, "SLP_S0IX_N"), + PINCTRL_PIN(123, "SPI_CS0_N"), + PINCTRL_PIN(124, "SPI_CS1_N"), + PINCTRL_PIN(125, "SPI_MOSI_IO0"), + PINCTRL_PIN(126, "SPI_MISO_IO1"), + PINCTRL_PIN(127, "SPI_IO2"), + PINCTRL_PIN(128, "SPI_IO3"), + PINCTRL_PIN(129, "SPI_CLK"), + PINCTRL_PIN(130, "SPI_CLK_LOOPBK"), + PINCTRL_PIN(131, "ESPI_IO0"), + PINCTRL_PIN(132, "ESPI_IO1"), + PINCTRL_PIN(133, "ESPI_IO2"), + PINCTRL_PIN(134, "ESPI_IO3"), + PINCTRL_PIN(135, "ESPI_CS0_N"), + PINCTRL_PIN(136, "ESPI_CLK"), + PINCTRL_PIN(137, "ESPI_RST_N"), + PINCTRL_PIN(138, "ESPI_ALRT0_N"), + PINCTRL_PIN(139, "ESPI_CS1_N"), + PINCTRL_PIN(140, "ESPI_ALRT1_N"), + PINCTRL_PIN(141, "ESPI_CLK_LOOPBK"), + PINCTRL_PIN(142, "EMMC_CMD"), + PINCTRL_PIN(143, "EMMC_STROBE"), + PINCTRL_PIN(144, "EMMC_CLK"), + PINCTRL_PIN(145, "EMMC_D0"), + PINCTRL_PIN(146, "EMMC_D1"), + PINCTRL_PIN(147, "EMMC_D2"), + PINCTRL_PIN(148, "EMMC_D3"), + PINCTRL_PIN(149, "EMMC_D4"), + PINCTRL_PIN(150, "EMMC_D5"), + PINCTRL_PIN(151, "EMMC_D6"), + PINCTRL_PIN(152, "EMMC_D7"), + PINCTRL_PIN(153, "SPARE_3"), +}; + +static const unsigned int dnv_uart0_pins[] = { 60, 61, 64, 65 }; +static const unsigned int dnv_uart0_modes[] = { 2, 3, 1, 1 }; +static const unsigned int dnv_uart1_pins[] = { 94, 95, 96, 97 }; +static const unsigned int dnv_uart2_pins[] = { 60, 61, 62, 63 }; +static const unsigned int dnv_uart2_modes[] = { 1, 2, 2, 2 }; +static const unsigned int dnv_emmc_pins[] = { + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, +}; + +static const struct intel_pingroup dnv_groups[] = { + PIN_GROUP("uart0_grp", dnv_uart0_pins, dnv_uart0_modes), + PIN_GROUP("uart1_grp", dnv_uart1_pins, 1), + PIN_GROUP("uart2_grp", dnv_uart2_pins, dnv_uart2_modes), + PIN_GROUP("emmc_grp", dnv_emmc_pins, 1), +}; + +static const char * const dnv_uart0_groups[] = { "uart0_grp" }; +static const char * const dnv_uart1_groups[] = { "uart1_grp" }; +static const char * const dnv_uart2_groups[] = { "uart2_grp" }; +static const char * const dnv_emmc_groups[] = { "emmc_grp" }; + +static const struct intel_function dnv_functions[] = { + FUNCTION("uart0", dnv_uart0_groups), + FUNCTION("uart1", dnv_uart1_groups), + FUNCTION("uart2", dnv_uart2_groups), + FUNCTION("emmc", dnv_emmc_groups), +}; + +static const struct intel_padgroup dnv_north_gpps[] = { + DNV_GPP(0, 0, 31), /* North ALL_0 */ + DNV_GPP(1, 32, 40), /* North ALL_1 */ +}; + +static const struct intel_padgroup dnv_south_gpps[] = { + DNV_GPP(0, 41, 58), /* South DFX */ + DNV_GPP(1, 59, 90), /* South GPP0_0 */ + DNV_GPP(2, 91, 111), /* South GPP0_1 */ + DNV_GPP(3, 112, 143), /* South GPP1_0 */ + DNV_GPP(4, 144, 153), /* South GPP1_1 */ +}; + +static const struct intel_community dnv_communities[] = { + DNV_COMMUNITY(0, 0, 40, dnv_north_gpps), + DNV_COMMUNITY(1, 41, 153, dnv_south_gpps), +}; + +static const struct intel_pinctrl_soc_data dnv_soc_data = { + .pins = dnv_pins, + .npins = ARRAY_SIZE(dnv_pins), + .groups = dnv_groups, + .ngroups = ARRAY_SIZE(dnv_groups), + .functions = dnv_functions, + .nfunctions = ARRAY_SIZE(dnv_functions), + .communities = dnv_communities, + .ncommunities = ARRAY_SIZE(dnv_communities), +}; + +static INTEL_PINCTRL_PM_OPS(dnv_pinctrl_pm_ops); + +static const struct acpi_device_id dnv_pinctrl_acpi_match[] = { + { "INTC3000", (kernel_ulong_t)&dnv_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, dnv_pinctrl_acpi_match); + +static struct platform_driver dnv_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "denverton-pinctrl", + .acpi_match_table = dnv_pinctrl_acpi_match, + .pm = &dnv_pinctrl_pm_ops, + }, +}; + +static int __init dnv_pinctrl_init(void) +{ + return platform_driver_register(&dnv_pinctrl_driver); +} +subsys_initcall(dnv_pinctrl_init); + +static void __exit dnv_pinctrl_exit(void) +{ + platform_driver_unregister(&dnv_pinctrl_driver); +} +module_exit(dnv_pinctrl_exit); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Denverton SoC pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-emmitsburg.c b/drivers/pinctrl/intel/pinctrl-emmitsburg.c new file mode 100644 index 000000000..f6114dbf7 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-emmitsburg.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Emmitsburg PCH pinctrl/GPIO driver + * + * Copyright (C) 2020, Intel Corporation + * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define EBG_PAD_OWN 0x0a0 +#define EBG_PADCFGLOCK 0x100 +#define EBG_HOSTSW_OWN 0x130 +#define EBG_GPI_IS 0x200 +#define EBG_GPI_IE 0x210 + +#define EBG_GPP(r, s, e) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + } + +#define EBG_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = EBG_PAD_OWN, \ + .padcfglock_offset = EBG_PADCFGLOCK, \ + .hostown_offset = EBG_HOSTSW_OWN, \ + .is_offset = EBG_GPI_IS, \ + .ie_offset = EBG_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Emmitsburg */ +static const struct pinctrl_pin_desc ebg_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "ESPI_ALERT0B"), + PINCTRL_PIN(1, "ESPI_ALERT1B"), + PINCTRL_PIN(2, "ESPI_IO_0"), + PINCTRL_PIN(3, "ESPI_IO_1"), + PINCTRL_PIN(4, "ESPI_IO_2"), + PINCTRL_PIN(5, "ESPI_IO_3"), + PINCTRL_PIN(6, "ESPI_CS0B"), + PINCTRL_PIN(7, "ESPI_CS1B"), + PINCTRL_PIN(8, "ESPI_RESETB"), + PINCTRL_PIN(9, "ESPI_CLK"), + PINCTRL_PIN(10, "SRCCLKREQB_0"), + PINCTRL_PIN(11, "SRCCLKREQB_1"), + PINCTRL_PIN(12, "SRCCLKREQB_2"), + PINCTRL_PIN(13, "SRCCLKREQB_3"), + PINCTRL_PIN(14, "SRCCLKREQB_4"), + PINCTRL_PIN(15, "SRCCLKREQB_5"), + PINCTRL_PIN(16, "SRCCLKREQB_6"), + PINCTRL_PIN(17, "SRCCLKREQB_7"), + PINCTRL_PIN(18, "SRCCLKREQB_8"), + PINCTRL_PIN(19, "SRCCLKREQB_9"), + PINCTRL_PIN(20, "ESPI_CLK_LOOPBK"), + /* GPP_B */ + PINCTRL_PIN(21, "GSXDOUT"), + PINCTRL_PIN(22, "GSXSLOAD"), + PINCTRL_PIN(23, "GSXDIN"), + PINCTRL_PIN(24, "GSXSRESETB"), + PINCTRL_PIN(25, "GSXCLK"), + PINCTRL_PIN(26, "USB2_OCB_0"), + PINCTRL_PIN(27, "USB2_OCB_1"), + PINCTRL_PIN(28, "USB2_OCB_2"), + PINCTRL_PIN(29, "USB2_OCB_3"), + PINCTRL_PIN(30, "USB2_OCB_4"), + PINCTRL_PIN(31, "USB2_OCB_5"), + PINCTRL_PIN(32, "USB2_OCB_6"), + PINCTRL_PIN(33, "HS_UART0_RXD"), + PINCTRL_PIN(34, "HS_UART0_TXD"), + PINCTRL_PIN(35, "HS_UART0_RTSB"), + PINCTRL_PIN(36, "HS_UART0_CTSB"), + PINCTRL_PIN(37, "HS_UART1_RXD"), + PINCTRL_PIN(38, "HS_UART1_TXD"), + PINCTRL_PIN(39, "HS_UART1_RTSB"), + PINCTRL_PIN(40, "HS_UART1_CTSB"), + PINCTRL_PIN(41, "GPPC_B_20"), + PINCTRL_PIN(42, "GPPC_B_21"), + PINCTRL_PIN(43, "GPPC_B_22"), + PINCTRL_PIN(44, "PS_ONB"), + /* SPI */ + PINCTRL_PIN(45, "SPI0_IO_2"), + PINCTRL_PIN(46, "SPI0_IO_3"), + PINCTRL_PIN(47, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(48, "SPI0_MISO_IO_1"), + PINCTRL_PIN(49, "SPI0_TPM_CSB"), + PINCTRL_PIN(50, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(51, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(52, "SPI0_CLK"), + PINCTRL_PIN(53, "TIME_SYNC_0"), + PINCTRL_PIN(54, "SPKR"), + PINCTRL_PIN(55, "CPU_GP_0"), + PINCTRL_PIN(56, "CPU_GP_1"), + PINCTRL_PIN(57, "CPU_GP_2"), + PINCTRL_PIN(58, "CPU_GP_3"), + PINCTRL_PIN(59, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(60, "SUSACKB"), + PINCTRL_PIN(61, "NMIB"), + PINCTRL_PIN(62, "SMIB"), + PINCTRL_PIN(63, "GPPC_S_10"), + PINCTRL_PIN(64, "GPPC_S_11"), + PINCTRL_PIN(65, "SPI_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(66, "ME_SML0CLK"), + PINCTRL_PIN(67, "ME_SML0DATA"), + PINCTRL_PIN(68, "ME_SML0ALERTB"), + PINCTRL_PIN(69, "ME_SML0BDATA"), + PINCTRL_PIN(70, "ME_SML0BCLK"), + PINCTRL_PIN(71, "ME_SML0BALERTB"), + PINCTRL_PIN(72, "ME_SML1CLK"), + PINCTRL_PIN(73, "ME_SML1DATA"), + PINCTRL_PIN(74, "ME_SML1ALERTB"), + PINCTRL_PIN(75, "ME_SML2CLK"), + PINCTRL_PIN(76, "ME_SML2DATA"), + PINCTRL_PIN(77, "ME_SML2ALERTB"), + PINCTRL_PIN(78, "ME_SML3CLK"), + PINCTRL_PIN(79, "ME_SML3DATA"), + PINCTRL_PIN(80, "ME_SML3ALERTB"), + PINCTRL_PIN(81, "ME_SML4CLK"), + PINCTRL_PIN(82, "ME_SML4DATA"), + PINCTRL_PIN(83, "ME_SML4ALERTB"), + PINCTRL_PIN(84, "GPPC_C_18"), + PINCTRL_PIN(85, "MC_SMBCLK"), + PINCTRL_PIN(86, "MC_SMBDATA"), + PINCTRL_PIN(87, "MC_SMBALERTB"), + /* GPP_D */ + PINCTRL_PIN(88, "HS_SMBCLK"), + PINCTRL_PIN(89, "HS_SMBDATA"), + PINCTRL_PIN(90, "HS_SMBALERTB"), + PINCTRL_PIN(91, "GBE_SMB_ALRT_N"), + PINCTRL_PIN(92, "GBE_SMB_CLK"), + PINCTRL_PIN(93, "GBE_SMB_DATA"), + PINCTRL_PIN(94, "GBE_GPIO10"), + PINCTRL_PIN(95, "GBE_GPIO11"), + PINCTRL_PIN(96, "CRASHLOG_TRIG_N"), + PINCTRL_PIN(97, "PMEB"), + PINCTRL_PIN(98, "BM_BUSYB"), + PINCTRL_PIN(99, "PLTRSTB"), + PINCTRL_PIN(100, "PCHHOTB"), + PINCTRL_PIN(101, "ADR_COMPLETE"), + PINCTRL_PIN(102, "ADR_TRIGGER_N"), + PINCTRL_PIN(103, "VRALERTB"), + PINCTRL_PIN(104, "ADR_ACK"), + PINCTRL_PIN(105, "THERMTRIP_N"), + PINCTRL_PIN(106, "MEMTRIP_N"), + PINCTRL_PIN(107, "MSMI_N"), + PINCTRL_PIN(108, "CATERR_N"), + PINCTRL_PIN(109, "GLB_RST_WARN_B"), + PINCTRL_PIN(110, "USB2_OCB_7"), + PINCTRL_PIN(111, "GPP_D_23"), + /* GPP_E */ + PINCTRL_PIN(112, "SATA1_XPCIE_0"), + PINCTRL_PIN(113, "SATA1_XPCIE_1"), + PINCTRL_PIN(114, "SATA1_XPCIE_2"), + PINCTRL_PIN(115, "SATA1_XPCIE_3"), + PINCTRL_PIN(116, "SATA0_XPCIE_2"), + PINCTRL_PIN(117, "SATA0_XPCIE_3"), + PINCTRL_PIN(118, "SATA0_USB3_XPCIE_0"), + PINCTRL_PIN(119, "SATA0_USB3_XPCIE_1"), + PINCTRL_PIN(120, "SATA0_SCLOCK"), + PINCTRL_PIN(121, "SATA0_SLOAD"), + PINCTRL_PIN(122, "SATA0_SDATAOUT"), + PINCTRL_PIN(123, "SATA1_SCLOCK"), + PINCTRL_PIN(124, "SATA1_SLOAD"), + PINCTRL_PIN(125, "SATA1_SDATAOUT"), + PINCTRL_PIN(126, "SATA2_SCLOCK"), + PINCTRL_PIN(127, "SATA2_SLOAD"), + PINCTRL_PIN(128, "SATA2_SDATAOUT"), + PINCTRL_PIN(129, "ERR0_N"), + PINCTRL_PIN(130, "ERR1_N"), + PINCTRL_PIN(131, "ERR2_N"), + PINCTRL_PIN(132, "GBE_UART_RXD"), + PINCTRL_PIN(133, "GBE_UART_TXD"), + PINCTRL_PIN(134, "GBE_UART_RTSB"), + PINCTRL_PIN(135, "GBE_UART_CTSB"), + /* JTAG */ + PINCTRL_PIN(136, "JTAG_TDO"), + PINCTRL_PIN(137, "JTAG_TDI"), + PINCTRL_PIN(138, "JTAG_TCK"), + PINCTRL_PIN(139, "JTAG_TMS"), + PINCTRL_PIN(140, "JTAGX"), + PINCTRL_PIN(141, "PRDYB"), + PINCTRL_PIN(142, "PREQB"), + PINCTRL_PIN(143, "GLB_PC_DISABLE"), + PINCTRL_PIN(144, "DBG_PMODE"), + PINCTRL_PIN(145, "GLB_EXT_ACC_DISABLE"), + /* GPP_H */ + PINCTRL_PIN(146, "GBE_GPIO12"), + PINCTRL_PIN(147, "GBE_GPIO13"), + PINCTRL_PIN(148, "GBE_SDP_TIMESYNC0_S2N"), + PINCTRL_PIN(149, "GBE_SDP_TIMESYNC1_S2N"), + PINCTRL_PIN(150, "GBE_SDP_TIMESYNC2_S2N"), + PINCTRL_PIN(151, "GBE_SDP_TIMESYNC3_S2N"), + PINCTRL_PIN(152, "GPPC_H_6"), + PINCTRL_PIN(153, "GPPC_H_7"), + PINCTRL_PIN(154, "NCSI_CLK_IN"), + PINCTRL_PIN(155, "NCSI_CRS_DV"), + PINCTRL_PIN(156, "NCSI_RXD0"), + PINCTRL_PIN(157, "NCSI_RXD1"), + PINCTRL_PIN(158, "NCSI_TX_EN"), + PINCTRL_PIN(159, "NCSI_TXD0"), + PINCTRL_PIN(160, "NCSI_TXD1"), + PINCTRL_PIN(161, "NAC_NCSI_CLK_OUT_0"), + PINCTRL_PIN(162, "NAC_NCSI_CLK_OUT_1"), + PINCTRL_PIN(163, "NAC_NCSI_CLK_OUT_2"), + PINCTRL_PIN(164, "PMCALERTB"), + PINCTRL_PIN(165, "GPPC_H_19"), + /* GPP_J */ + PINCTRL_PIN(166, "CPUPWRGD"), + PINCTRL_PIN(167, "CPU_THRMTRIP_N"), + PINCTRL_PIN(168, "PLTRST_CPUB"), + PINCTRL_PIN(169, "TRIGGER0_N"), + PINCTRL_PIN(170, "TRIGGER1_N"), + PINCTRL_PIN(171, "CPU_PWR_DEBUG_N"), + PINCTRL_PIN(172, "CPU_MEMTRIP_N"), + PINCTRL_PIN(173, "CPU_MSMI_N"), + PINCTRL_PIN(174, "ME_PECI"), + PINCTRL_PIN(175, "NAC_SPARE0"), + PINCTRL_PIN(176, "NAC_SPARE1"), + PINCTRL_PIN(177, "NAC_SPARE2"), + PINCTRL_PIN(178, "CPU_ERR0_N"), + PINCTRL_PIN(179, "CPU_CATERR_N"), + PINCTRL_PIN(180, "CPU_ERR1_N"), + PINCTRL_PIN(181, "CPU_ERR2_N"), + PINCTRL_PIN(182, "GPP_J_16"), + PINCTRL_PIN(183, "GPP_J_17"), + /* GPP_I */ + PINCTRL_PIN(184, "GBE_GPIO4"), + PINCTRL_PIN(185, "GBE_GPIO5"), + PINCTRL_PIN(186, "GBE_GPIO6"), + PINCTRL_PIN(187, "GBE_GPIO7"), + PINCTRL_PIN(188, "GBE1_LED1"), + PINCTRL_PIN(189, "GBE1_LED2"), + PINCTRL_PIN(190, "GBE2_LED0"), + PINCTRL_PIN(191, "GBE2_LED1"), + PINCTRL_PIN(192, "GBE2_LED2"), + PINCTRL_PIN(193, "GBE3_LED0"), + PINCTRL_PIN(194, "GBE3_LED1"), + PINCTRL_PIN(195, "GBE3_LED2"), + PINCTRL_PIN(196, "GBE0_I2C_CLK"), + PINCTRL_PIN(197, "GBE0_I2C_DATA"), + PINCTRL_PIN(198, "GBE1_I2C_CLK"), + PINCTRL_PIN(199, "GBE1_I2C_DATA"), + PINCTRL_PIN(200, "GBE2_I2C_CLK"), + PINCTRL_PIN(201, "GBE2_I2C_DATA"), + PINCTRL_PIN(202, "GBE3_I2C_CLK"), + PINCTRL_PIN(203, "GBE3_I2C_DATA"), + PINCTRL_PIN(204, "GBE4_I2C_CLK"), + PINCTRL_PIN(205, "GBE4_I2C_DATA"), + PINCTRL_PIN(206, "GBE_GPIO8"), + PINCTRL_PIN(207, "GBE_GPIO9"), + /* GPP_L */ + PINCTRL_PIN(208, "PM_SYNC_0"), + PINCTRL_PIN(209, "PM_DOWN_0"), + PINCTRL_PIN(210, "PM_SYNC_CLK_0"), + PINCTRL_PIN(211, "GPP_L_3"), + PINCTRL_PIN(212, "GPP_L_4"), + PINCTRL_PIN(213, "GPP_L_5"), + PINCTRL_PIN(214, "GPP_L_6"), + PINCTRL_PIN(215, "GPP_L_7"), + PINCTRL_PIN(216, "GPP_L_8"), + PINCTRL_PIN(217, "NAC_GBE_GPIO0_S2N"), + PINCTRL_PIN(218, "NAC_GBE_GPIO1_S2N"), + PINCTRL_PIN(219, "NAC_GBE_GPIO2_S2N"), + PINCTRL_PIN(220, "NAC_GBE_GPIO3_S2N"), + PINCTRL_PIN(221, "NAC_GBE_SMB_DATA_IN"), + PINCTRL_PIN(222, "NAC_GBE_SMB_DATA_OUT"), + PINCTRL_PIN(223, "NAC_GBE_SMB_ALRT_N"), + PINCTRL_PIN(224, "NAC_GBE_SMB_CLK_IN"), + PINCTRL_PIN(225, "NAC_GBE_SMB_CLK_OUT"), + /* GPP_M */ + PINCTRL_PIN(226, "GPP_M_0"), + PINCTRL_PIN(227, "GPP_M_1"), + PINCTRL_PIN(228, "GPP_M_2"), + PINCTRL_PIN(229, "GPP_M_3"), + PINCTRL_PIN(230, "NAC_WAKE_N"), + PINCTRL_PIN(231, "GPP_M_5"), + PINCTRL_PIN(232, "GPP_M_6"), + PINCTRL_PIN(233, "GPP_M_7"), + PINCTRL_PIN(234, "GPP_M_8"), + PINCTRL_PIN(235, "NAC_SBLINK_S2N"), + PINCTRL_PIN(236, "NAC_SBLINK_N2S"), + PINCTRL_PIN(237, "NAC_SBLINK_CLK_N2S"), + PINCTRL_PIN(238, "NAC_SBLINK_CLK_S2N"), + PINCTRL_PIN(239, "NAC_XTAL_VALID"), + PINCTRL_PIN(240, "NAC_RESET_NAC_N"), + PINCTRL_PIN(241, "GPP_M_15"), + PINCTRL_PIN(242, "GPP_M_16"), + PINCTRL_PIN(243, "GPP_M_17"), + /* GPP_N */ + PINCTRL_PIN(244, "GPP_N_0"), + PINCTRL_PIN(245, "NAC_NCSI_TXD0"), + PINCTRL_PIN(246, "GPP_N_2"), + PINCTRL_PIN(247, "GPP_N_3"), + PINCTRL_PIN(248, "NAC_NCSI_REFCLK_IN"), + PINCTRL_PIN(249, "GPP_N_5"), + PINCTRL_PIN(250, "GPP_N_6"), + PINCTRL_PIN(251, "GPP_N_7"), + PINCTRL_PIN(252, "NAC_NCSI_RXD0"), + PINCTRL_PIN(253, "NAC_NCSI_RXD1"), + PINCTRL_PIN(254, "NAC_NCSI_CRS_DV"), + PINCTRL_PIN(255, "NAC_NCSI_CLK_IN"), + PINCTRL_PIN(256, "NAC_NCSI_REFCLK_OUT"), + PINCTRL_PIN(257, "NAC_NCSI_TX_EN"), + PINCTRL_PIN(258, "NAC_NCSI_TXD1"), + PINCTRL_PIN(259, "NAC_NCSI_OE_N"), + PINCTRL_PIN(260, "NAC_GR_N"), + PINCTRL_PIN(261, "NAC_INIT_SX_WAKE_N"), +}; + +static const struct intel_padgroup ebg_community0_gpps[] = { + EBG_GPP(0, 0, 20), /* GPP_A */ + EBG_GPP(1, 21, 44), /* GPP_B */ + EBG_GPP(2, 45, 65), /* SPI */ +}; + +static const struct intel_padgroup ebg_community1_gpps[] = { + EBG_GPP(0, 66, 87), /* GPP_C */ + EBG_GPP(1, 88, 111), /* GPP_D */ +}; + +static const struct intel_padgroup ebg_community3_gpps[] = { + EBG_GPP(0, 112, 135), /* GPP_E */ + EBG_GPP(1, 136, 145), /* JTAG */ +}; + +static const struct intel_padgroup ebg_community4_gpps[] = { + EBG_GPP(0, 146, 165), /* GPP_H */ + EBG_GPP(1, 166, 183), /* GPP_J */ +}; + +static const struct intel_padgroup ebg_community5_gpps[] = { + EBG_GPP(0, 184, 207), /* GPP_I */ + EBG_GPP(1, 208, 225), /* GPP_L */ + EBG_GPP(2, 226, 243), /* GPP_M */ + EBG_GPP(3, 244, 261), /* GPP_N */ +}; + +static const struct intel_community ebg_communities[] = { + EBG_COMMUNITY(0, 0, 65, ebg_community0_gpps), + EBG_COMMUNITY(1, 66, 111, ebg_community1_gpps), + EBG_COMMUNITY(2, 112, 145, ebg_community3_gpps), + EBG_COMMUNITY(3, 146, 183, ebg_community4_gpps), + EBG_COMMUNITY(4, 184, 261, ebg_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data ebg_soc_data = { + .pins = ebg_pins, + .npins = ARRAY_SIZE(ebg_pins), + .communities = ebg_communities, + .ncommunities = ARRAY_SIZE(ebg_communities), +}; + +static const struct acpi_device_id ebg_pinctrl_acpi_match[] = { + { "INTC1071", (kernel_ulong_t)&ebg_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, ebg_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(ebg_pinctrl_pm_ops); + +static struct platform_driver ebg_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "emmitsburg-pinctrl", + .acpi_match_table = ebg_pinctrl_acpi_match, + .pm = &ebg_pinctrl_pm_ops, + }, +}; + +module_platform_driver(ebg_pinctrl_driver); + +MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Emmitsburg PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-geminilake.c b/drivers/pinctrl/intel/pinctrl-geminilake.c new file mode 100644 index 000000000..df02028b4 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-geminilake.c @@ -0,0 +1,484 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Gemini Lake SoC pinctrl/GPIO driver + * + * Copyright (C) 2017 Intel Corporation + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define GLK_PAD_OWN 0x020 +#define GLK_PADCFGLOCK 0x080 +#define GLK_HOSTSW_OWN 0x0b0 +#define GLK_GPI_IS 0x100 +#define GLK_GPI_IE 0x110 + +#define GLK_COMMUNITY(s, e) \ + { \ + .padown_offset = GLK_PAD_OWN, \ + .padcfglock_offset = GLK_PADCFGLOCK, \ + .hostown_offset = GLK_HOSTSW_OWN, \ + .is_offset = GLK_GPI_IS, \ + .ie_offset = GLK_GPI_IE, \ + .gpp_size = 32, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + } + +/* GLK */ +static const struct pinctrl_pin_desc glk_northwest_pins[] = { + PINCTRL_PIN(0, "TCK"), + PINCTRL_PIN(1, "TRST_B"), + PINCTRL_PIN(2, "TMS"), + PINCTRL_PIN(3, "TDI"), + PINCTRL_PIN(4, "TDO"), + PINCTRL_PIN(5, "JTAGX"), + PINCTRL_PIN(6, "CX_PREQ_B"), + PINCTRL_PIN(7, "CX_PRDY_B"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "ISH_GPIO_0"), + PINCTRL_PIN(27, "ISH_GPIO_1"), + PINCTRL_PIN(28, "ISH_GPIO_2"), + PINCTRL_PIN(29, "ISH_GPIO_3"), + PINCTRL_PIN(30, "ISH_GPIO_4"), + PINCTRL_PIN(31, "ISH_GPIO_5"), + PINCTRL_PIN(32, "ISH_GPIO_6"), + PINCTRL_PIN(33, "ISH_GPIO_7"), + PINCTRL_PIN(34, "ISH_GPIO_8"), + PINCTRL_PIN(35, "ISH_GPIO_9"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GP_INTD_DSI_TE1"), + PINCTRL_PIN(43, "GP_INTD_DSI_TE2"), + PINCTRL_PIN(44, "USB_OC0_B"), + PINCTRL_PIN(45, "USB_OC1_B"), + PINCTRL_PIN(46, "DSI_I2C_SDA"), + PINCTRL_PIN(47, "DSI_I2C_SCL"), + PINCTRL_PIN(48, "PMC_I2C_SDA"), + PINCTRL_PIN(49, "PMC_I2C_SCL"), + PINCTRL_PIN(50, "LPSS_I2C0_SDA"), + PINCTRL_PIN(51, "LPSS_I2C0_SCL"), + PINCTRL_PIN(52, "LPSS_I2C1_SDA"), + PINCTRL_PIN(53, "LPSS_I2C1_SCL"), + PINCTRL_PIN(54, "LPSS_I2C2_SDA"), + PINCTRL_PIN(55, "LPSS_I2C2_SCL"), + PINCTRL_PIN(56, "LPSS_I2C3_SDA"), + PINCTRL_PIN(57, "LPSS_I2C3_SCL"), + PINCTRL_PIN(58, "LPSS_I2C4_SDA"), + PINCTRL_PIN(59, "LPSS_I2C4_SCL"), + PINCTRL_PIN(60, "LPSS_UART0_RXD"), + PINCTRL_PIN(61, "LPSS_UART0_TXD"), + PINCTRL_PIN(62, "LPSS_UART0_RTS_B"), + PINCTRL_PIN(63, "LPSS_UART0_CTS_B"), + PINCTRL_PIN(64, "LPSS_UART2_RXD"), + PINCTRL_PIN(65, "LPSS_UART2_TXD"), + PINCTRL_PIN(66, "LPSS_UART2_RTS_B"), + PINCTRL_PIN(67, "LPSS_UART2_CTS_B"), + PINCTRL_PIN(68, "PMC_SPI_FS0"), + PINCTRL_PIN(69, "PMC_SPI_FS1"), + PINCTRL_PIN(70, "PMC_SPI_FS2"), + PINCTRL_PIN(71, "PMC_SPI_RXD"), + PINCTRL_PIN(72, "PMC_SPI_TXD"), + PINCTRL_PIN(73, "PMC_SPI_CLK"), + PINCTRL_PIN(74, "THERMTRIP_B"), + PINCTRL_PIN(75, "PROCHOT_B"), + PINCTRL_PIN(76, "EMMC_RST_B"), + PINCTRL_PIN(77, "GPIO_212"), + PINCTRL_PIN(78, "GPIO_213"), + PINCTRL_PIN(79, "GPIO_214"), +}; + +static const unsigned int glk_northwest_uart1_pins[] = { 26, 27, 28, 29 }; +static const unsigned int glk_northwest_pwm0_pins[] = { 42 }; +static const unsigned int glk_northwest_pwm1_pins[] = { 43 }; +static const unsigned int glk_northwest_pwm2_pins[] = { 44 }; +static const unsigned int glk_northwest_pwm3_pins[] = { 45 }; +static const unsigned int glk_northwest_i2c0_pins[] = { 50, 51 }; +static const unsigned int glk_northwest_i2c1_pins[] = { 52, 53 }; +static const unsigned int glk_northwest_i2c2_pins[] = { 54, 55 }; +static const unsigned int glk_northwest_i2c3_pins[] = { 56, 57 }; +static const unsigned int glk_northwest_i2c4_pins[] = { 58, 59 }; +static const unsigned int glk_northwest_uart0_pins[] = { 60, 61, 62, 63 }; +static const unsigned int glk_northwest_uart2_pins[] = { 64, 65, 66, 67 }; + +static const struct intel_pingroup glk_northwest_groups[] = { + PIN_GROUP("uart1_grp", glk_northwest_uart1_pins, 2), + PIN_GROUP("pwm0_grp", glk_northwest_pwm0_pins, 2), + PIN_GROUP("pwm1_grp", glk_northwest_pwm1_pins, 2), + PIN_GROUP("pwm2_grp", glk_northwest_pwm2_pins, 2), + PIN_GROUP("pwm3_grp", glk_northwest_pwm3_pins, 2), + PIN_GROUP("i2c0_grp", glk_northwest_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", glk_northwest_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", glk_northwest_i2c2_pins, 1), + PIN_GROUP("i2c3_grp", glk_northwest_i2c3_pins, 1), + PIN_GROUP("i2c4_grp", glk_northwest_i2c4_pins, 1), + PIN_GROUP("uart0_grp", glk_northwest_uart0_pins, 1), + PIN_GROUP("uart2_grp", glk_northwest_uart2_pins, 1), +}; + +static const char * const glk_northwest_uart1_groups[] = { "uart1_grp" }; +static const char * const glk_northwest_pwm0_groups[] = { "pwm0_grp" }; +static const char * const glk_northwest_pwm1_groups[] = { "pwm1_grp" }; +static const char * const glk_northwest_pwm2_groups[] = { "pwm2_grp" }; +static const char * const glk_northwest_pwm3_groups[] = { "pwm3_grp" }; +static const char * const glk_northwest_i2c0_groups[] = { "i2c0_grp" }; +static const char * const glk_northwest_i2c1_groups[] = { "i2c1_grp" }; +static const char * const glk_northwest_i2c2_groups[] = { "i2c2_grp" }; +static const char * const glk_northwest_i2c3_groups[] = { "i2c3_grp" }; +static const char * const glk_northwest_i2c4_groups[] = { "i2c4_grp" }; +static const char * const glk_northwest_uart0_groups[] = { "uart0_grp" }; +static const char * const glk_northwest_uart2_groups[] = { "uart2_grp" }; + +static const struct intel_function glk_northwest_functions[] = { + FUNCTION("uart1", glk_northwest_uart1_groups), + FUNCTION("pmw0", glk_northwest_pwm0_groups), + FUNCTION("pmw1", glk_northwest_pwm1_groups), + FUNCTION("pmw2", glk_northwest_pwm2_groups), + FUNCTION("pmw3", glk_northwest_pwm3_groups), + FUNCTION("i2c0", glk_northwest_i2c0_groups), + FUNCTION("i2c1", glk_northwest_i2c1_groups), + FUNCTION("i2c2", glk_northwest_i2c2_groups), + FUNCTION("i2c3", glk_northwest_i2c3_groups), + FUNCTION("i2c4", glk_northwest_i2c4_groups), + FUNCTION("uart0", glk_northwest_uart0_groups), + FUNCTION("uart2", glk_northwest_uart2_groups), +}; + +static const struct intel_community glk_northwest_communities[] = { + GLK_COMMUNITY(0, 79), +}; + +static const struct intel_pinctrl_soc_data glk_northwest_soc_data = { + .uid = "1", + .pins = glk_northwest_pins, + .npins = ARRAY_SIZE(glk_northwest_pins), + .groups = glk_northwest_groups, + .ngroups = ARRAY_SIZE(glk_northwest_groups), + .functions = glk_northwest_functions, + .nfunctions = ARRAY_SIZE(glk_northwest_functions), + .communities = glk_northwest_communities, + .ncommunities = ARRAY_SIZE(glk_northwest_communities), +}; + +static const struct pinctrl_pin_desc glk_north_pins[] = { + PINCTRL_PIN(0, "SVID0_ALERT_B"), + PINCTRL_PIN(1, "SVID0_DATA"), + PINCTRL_PIN(2, "SVID0_CLK"), + PINCTRL_PIN(3, "LPSS_SPI_0_CLK"), + PINCTRL_PIN(4, "LPSS_SPI_0_FS0"), + PINCTRL_PIN(5, "LPSS_SPI_0_FS1"), + PINCTRL_PIN(6, "LPSS_SPI_0_RXD"), + PINCTRL_PIN(7, "LPSS_SPI_0_TXD"), + PINCTRL_PIN(8, "LPSS_SPI_2_CLK"), + PINCTRL_PIN(9, "LPSS_SPI_2_FS0"), + PINCTRL_PIN(10, "LPSS_SPI_2_FS1"), + PINCTRL_PIN(11, "LPSS_SPI_2_FS2"), + PINCTRL_PIN(12, "LPSS_SPI_2_RXD"), + PINCTRL_PIN(13, "LPSS_SPI_2_TXD"), + PINCTRL_PIN(14, "FST_SPI_CS0_B"), + PINCTRL_PIN(15, "FST_SPI_CS1_B"), + PINCTRL_PIN(16, "FST_SPI_MOSI_IO0"), + PINCTRL_PIN(17, "FST_SPI_MISO_IO1"), + PINCTRL_PIN(18, "FST_SPI_IO2"), + PINCTRL_PIN(19, "FST_SPI_IO3"), + PINCTRL_PIN(20, "FST_SPI_CLK"), + PINCTRL_PIN(21, "FST_SPI_CLK_FB"), + PINCTRL_PIN(22, "PMU_PLTRST_B"), + PINCTRL_PIN(23, "PMU_PWRBTN_B"), + PINCTRL_PIN(24, "PMU_SLP_S0_B"), + PINCTRL_PIN(25, "PMU_SLP_S3_B"), + PINCTRL_PIN(26, "PMU_SLP_S4_B"), + PINCTRL_PIN(27, "SUSPWRDNACK"), + PINCTRL_PIN(28, "EMMC_DNX_PWR_EN_B"), + PINCTRL_PIN(29, "GPIO_105"), + PINCTRL_PIN(30, "PMU_BATLOW_B"), + PINCTRL_PIN(31, "PMU_RESETBUTTON_B"), + PINCTRL_PIN(32, "PMU_SUSCLK"), + PINCTRL_PIN(33, "SUS_STAT_B"), + PINCTRL_PIN(34, "LPSS_I2C5_SDA"), + PINCTRL_PIN(35, "LPSS_I2C5_SCL"), + PINCTRL_PIN(36, "LPSS_I2C6_SDA"), + PINCTRL_PIN(37, "LPSS_I2C6_SCL"), + PINCTRL_PIN(38, "LPSS_I2C7_SDA"), + PINCTRL_PIN(39, "LPSS_I2C7_SCL"), + PINCTRL_PIN(40, "PCIE_WAKE0_B"), + PINCTRL_PIN(41, "PCIE_WAKE1_B"), + PINCTRL_PIN(42, "PCIE_WAKE2_B"), + PINCTRL_PIN(43, "PCIE_WAKE3_B"), + PINCTRL_PIN(44, "PCIE_CLKREQ0_B"), + PINCTRL_PIN(45, "PCIE_CLKREQ1_B"), + PINCTRL_PIN(46, "PCIE_CLKREQ2_B"), + PINCTRL_PIN(47, "PCIE_CLKREQ3_B"), + PINCTRL_PIN(48, "HV_DDI0_DDC_SDA"), + PINCTRL_PIN(49, "HV_DDI0_DDC_SCL"), + PINCTRL_PIN(50, "HV_DDI1_DDC_SDA"), + PINCTRL_PIN(51, "HV_DDI1_DDC_SCL"), + PINCTRL_PIN(52, "PANEL0_VDDEN"), + PINCTRL_PIN(53, "PANEL0_BKLTEN"), + PINCTRL_PIN(54, "PANEL0_BKLTCTL"), + PINCTRL_PIN(55, "HV_DDI0_HPD"), + PINCTRL_PIN(56, "HV_DDI1_HPD"), + PINCTRL_PIN(57, "HV_EDP_HPD"), + PINCTRL_PIN(58, "GPIO_134"), + PINCTRL_PIN(59, "GPIO_135"), + PINCTRL_PIN(60, "GPIO_136"), + PINCTRL_PIN(61, "GPIO_137"), + PINCTRL_PIN(62, "GPIO_138"), + PINCTRL_PIN(63, "GPIO_139"), + PINCTRL_PIN(64, "GPIO_140"), + PINCTRL_PIN(65, "GPIO_141"), + PINCTRL_PIN(66, "GPIO_142"), + PINCTRL_PIN(67, "GPIO_143"), + PINCTRL_PIN(68, "GPIO_144"), + PINCTRL_PIN(69, "GPIO_145"), + PINCTRL_PIN(70, "GPIO_146"), + PINCTRL_PIN(71, "LPC_ILB_SERIRQ"), + PINCTRL_PIN(72, "LPC_CLKOUT0"), + PINCTRL_PIN(73, "LPC_CLKOUT1"), + PINCTRL_PIN(74, "LPC_AD0"), + PINCTRL_PIN(75, "LPC_AD1"), + PINCTRL_PIN(76, "LPC_AD2"), + PINCTRL_PIN(77, "LPC_AD3"), + PINCTRL_PIN(78, "LPC_CLKRUNB"), + PINCTRL_PIN(79, "LPC_FRAMEB"), +}; + +static const unsigned int glk_north_spi0_pins[] = { 3, 4, 5, 6, 7 }; +static const unsigned int glk_north_spi1_pins[] = { 8, 9, 10, 11, 12, 13 }; +static const unsigned int glk_north_i2c5_pins[] = { 34, 35 }; +static const unsigned int glk_north_i2c6_pins[] = { 36, 37 }; +static const unsigned int glk_north_i2c7_pins[] = { 38, 39 }; +static const unsigned int glk_north_uart0_pins[] = { 62, 63, 64, 65 }; +static const unsigned int glk_north_spi0b_pins[] = { 66, 67, 68, 69, 70 }; + +static const struct intel_pingroup glk_north_groups[] = { + PIN_GROUP("spi0_grp", glk_north_spi0_pins, 1), + PIN_GROUP("spi1_grp", glk_north_spi1_pins, 1), + PIN_GROUP("i2c5_grp", glk_north_i2c5_pins, 1), + PIN_GROUP("i2c6_grp", glk_north_i2c6_pins, 1), + PIN_GROUP("i2c7_grp", glk_north_i2c7_pins, 1), + PIN_GROUP("uart0_grp", glk_north_uart0_pins, 2), + PIN_GROUP("spi0b_grp", glk_north_spi0b_pins, 2), +}; + +static const char * const glk_north_spi0_groups[] = { "spi0_grp", "spi0b_grp" }; +static const char * const glk_north_spi1_groups[] = { "spi1_grp" }; +static const char * const glk_north_i2c5_groups[] = { "i2c5_grp" }; +static const char * const glk_north_i2c6_groups[] = { "i2c6_grp" }; +static const char * const glk_north_i2c7_groups[] = { "i2c7_grp" }; +static const char * const glk_north_uart0_groups[] = { "uart0_grp" }; + +static const struct intel_function glk_north_functions[] = { + FUNCTION("spi0", glk_north_spi0_groups), + FUNCTION("spi1", glk_north_spi1_groups), + FUNCTION("i2c5", glk_north_i2c5_groups), + FUNCTION("i2c6", glk_north_i2c6_groups), + FUNCTION("i2c7", glk_north_i2c7_groups), + FUNCTION("uart0", glk_north_uart0_groups), +}; + +static const struct intel_community glk_north_communities[] = { + GLK_COMMUNITY(0, 79), +}; + +static const struct intel_pinctrl_soc_data glk_north_soc_data = { + .uid = "2", + .pins = glk_north_pins, + .npins = ARRAY_SIZE(glk_north_pins), + .groups = glk_north_groups, + .ngroups = ARRAY_SIZE(glk_north_groups), + .functions = glk_north_functions, + .nfunctions = ARRAY_SIZE(glk_north_functions), + .communities = glk_north_communities, + .ncommunities = ARRAY_SIZE(glk_north_communities), +}; + +static const struct pinctrl_pin_desc glk_audio_pins[] = { + PINCTRL_PIN(0, "AVS_I2S0_MCLK"), + PINCTRL_PIN(1, "AVS_I2S0_BCLK"), + PINCTRL_PIN(2, "AVS_I2S0_WS_SYNC"), + PINCTRL_PIN(3, "AVS_I2S0_SDI"), + PINCTRL_PIN(4, "AVS_I2S0_SDO"), + PINCTRL_PIN(5, "AVS_I2S1_MCLK"), + PINCTRL_PIN(6, "AVS_I2S1_BCLK"), + PINCTRL_PIN(7, "AVS_I2S1_WS_SYNC"), + PINCTRL_PIN(8, "AVS_I2S1_SDI"), + PINCTRL_PIN(9, "AVS_I2S1_SDO"), + PINCTRL_PIN(10, "AVS_HDA_BCLK"), + PINCTRL_PIN(11, "AVS_HDA_WS_SYNC"), + PINCTRL_PIN(12, "AVS_HDA_SDI"), + PINCTRL_PIN(13, "AVS_HDA_SDO"), + PINCTRL_PIN(14, "AVS_HDA_RSTB"), + PINCTRL_PIN(15, "AVS_M_CLK_A1"), + PINCTRL_PIN(16, "AVS_M_CLK_B1"), + PINCTRL_PIN(17, "AVS_M_DATA_1"), + PINCTRL_PIN(18, "AVS_M_CLK_AB2"), + PINCTRL_PIN(19, "AVS_M_DATA_2"), +}; + +static const struct intel_community glk_audio_communities[] = { + GLK_COMMUNITY(0, 19), +}; + +static const struct intel_pinctrl_soc_data glk_audio_soc_data = { + .uid = "3", + .pins = glk_audio_pins, + .npins = ARRAY_SIZE(glk_audio_pins), + .communities = glk_audio_communities, + .ncommunities = ARRAY_SIZE(glk_audio_communities), +}; + +static const struct pinctrl_pin_desc glk_scc_pins[] = { + PINCTRL_PIN(0, "SMB_ALERTB"), + PINCTRL_PIN(1, "SMB_CLK"), + PINCTRL_PIN(2, "SMB_DATA"), + PINCTRL_PIN(3, "SDCARD_LVL_WP"), + PINCTRL_PIN(4, "SDCARD_CLK"), + PINCTRL_PIN(5, "SDCARD_CLK_FB"), + PINCTRL_PIN(6, "SDCARD_D0"), + PINCTRL_PIN(7, "SDCARD_D1"), + PINCTRL_PIN(8, "SDCARD_D2"), + PINCTRL_PIN(9, "SDCARD_D3"), + PINCTRL_PIN(10, "SDCARD_CMD"), + PINCTRL_PIN(11, "SDCARD_CD_B"), + PINCTRL_PIN(12, "SDCARD_PWR_DOWN_B"), + PINCTRL_PIN(13, "GPIO_210"), + PINCTRL_PIN(14, "OSC_CLK_OUT_0"), + PINCTRL_PIN(15, "OSC_CLK_OUT_1"), + PINCTRL_PIN(16, "CNV_BRI_DT"), + PINCTRL_PIN(17, "CNV_BRI_RSP"), + PINCTRL_PIN(18, "CNV_RGI_DT"), + PINCTRL_PIN(19, "CNV_RGI_RSP"), + PINCTRL_PIN(20, "CNV_RF_RESET_B"), + PINCTRL_PIN(21, "XTAL_CLKREQ"), + PINCTRL_PIN(22, "SDIO_CLK_FB"), + PINCTRL_PIN(23, "EMMC0_CLK"), + PINCTRL_PIN(24, "EMMC0_CLK_FB"), + PINCTRL_PIN(25, "EMMC0_D0"), + PINCTRL_PIN(26, "EMMC0_D1"), + PINCTRL_PIN(27, "EMMC0_D2"), + PINCTRL_PIN(28, "EMMC0_D3"), + PINCTRL_PIN(29, "EMMC0_D4"), + PINCTRL_PIN(30, "EMMC0_D5"), + PINCTRL_PIN(31, "EMMC0_D6"), + PINCTRL_PIN(32, "EMMC0_D7"), + PINCTRL_PIN(33, "EMMC0_CMD"), + PINCTRL_PIN(34, "EMMC0_STROBE"), +}; + +static const unsigned int glk_scc_i2c7_pins[] = { 1, 2 }; +static const unsigned int glk_scc_sdcard_pins[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, +}; +static const unsigned int glk_scc_sdio_pins[] = { 16, 17, 18, 19, 20, 21, 22 }; +static const unsigned int glk_scc_uart1_pins[] = { 16, 17, 18, 19 }; +static const unsigned int glk_scc_emmc_pins[] = { + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +}; + +static const struct intel_pingroup glk_scc_groups[] = { + PIN_GROUP("i2c7_grp", glk_scc_i2c7_pins, 2), + PIN_GROUP("sdcard_grp", glk_scc_sdcard_pins, 1), + PIN_GROUP("sdio_grp", glk_scc_sdio_pins, 2), + PIN_GROUP("uart1_grp", glk_scc_uart1_pins, 3), + PIN_GROUP("emmc_grp", glk_scc_emmc_pins, 1), +}; + +static const char * const glk_scc_i2c7_groups[] = { "i2c7_grp" }; +static const char * const glk_scc_sdcard_groups[] = { "sdcard_grp" }; +static const char * const glk_scc_sdio_groups[] = { "sdio_grp" }; +static const char * const glk_scc_uart1_groups[] = { "uart1_grp" }; +static const char * const glk_scc_emmc_groups[] = { "emmc_grp" }; + +static const struct intel_function glk_scc_functions[] = { + FUNCTION("i2c7", glk_scc_i2c7_groups), + FUNCTION("sdcard", glk_scc_sdcard_groups), + FUNCTION("sdio", glk_scc_sdio_groups), + FUNCTION("uart1", glk_scc_uart1_groups), + FUNCTION("emmc", glk_scc_emmc_groups), +}; + +static const struct intel_community glk_scc_communities[] = { + GLK_COMMUNITY(0, 34), +}; + +static const struct intel_pinctrl_soc_data glk_scc_soc_data = { + .uid = "4", + .pins = glk_scc_pins, + .npins = ARRAY_SIZE(glk_scc_pins), + .groups = glk_scc_groups, + .ngroups = ARRAY_SIZE(glk_scc_groups), + .functions = glk_scc_functions, + .nfunctions = ARRAY_SIZE(glk_scc_functions), + .communities = glk_scc_communities, + .ncommunities = ARRAY_SIZE(glk_scc_communities), +}; + +static const struct intel_pinctrl_soc_data *glk_pinctrl_soc_data[] = { + &glk_northwest_soc_data, + &glk_north_soc_data, + &glk_audio_soc_data, + &glk_scc_soc_data, + NULL +}; + +static const struct acpi_device_id glk_pinctrl_acpi_match[] = { + { "INT3453", (kernel_ulong_t)glk_pinctrl_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, glk_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(glk_pinctrl_pm_ops); + +static struct platform_driver glk_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_uid, + .driver = { + .name = "geminilake-pinctrl", + .acpi_match_table = glk_pinctrl_acpi_match, + .pm = &glk_pinctrl_pm_ops, + }, +}; + +static int __init glk_pinctrl_init(void) +{ + return platform_driver_register(&glk_pinctrl_driver); +} +subsys_initcall(glk_pinctrl_init); + +static void __exit glk_pinctrl_exit(void) +{ + platform_driver_unregister(&glk_pinctrl_driver); +} +module_exit(glk_pinctrl_exit); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Gemini Lake SoC pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c new file mode 100644 index 000000000..429b5a83a --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-icelake.c @@ -0,0 +1,428 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Ice Lake PCH pinctrl/GPIO driver + * + * Copyright (C) 2018, Intel Corporation + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/acpi.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define ICL_PAD_OWN 0x020 +#define ICL_PADCFGLOCK 0x080 +#define ICL_HOSTSW_OWN 0x0b0 +#define ICL_GPI_IS 0x100 +#define ICL_GPI_IE 0x110 + +#define ICL_GPP(r, s, e, g) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ + } + +#define ICL_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = ICL_PAD_OWN, \ + .padcfglock_offset = ICL_PADCFGLOCK, \ + .hostown_offset = ICL_HOSTSW_OWN, \ + .is_offset = ICL_GPI_IS, \ + .ie_offset = ICL_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Ice Lake-LP */ +static const struct pinctrl_pin_desc icllp_pins[] = { + /* GPP_G */ + PINCTRL_PIN(0, "SD3_CMD"), + PINCTRL_PIN(1, "SD3_D0"), + PINCTRL_PIN(2, "SD3_D1"), + PINCTRL_PIN(3, "SD3_D2"), + PINCTRL_PIN(4, "SD3_D3"), + PINCTRL_PIN(5, "SD3_CDB"), + PINCTRL_PIN(6, "SD3_CLK"), + PINCTRL_PIN(7, "SD3_WP"), + /* GPP_B */ + PINCTRL_PIN(8, "CORE_VID_0"), + PINCTRL_PIN(9, "CORE_VID_1"), + PINCTRL_PIN(10, "VRALERTB"), + PINCTRL_PIN(11, "CPU_GP_2"), + PINCTRL_PIN(12, "CPU_GP_3"), + PINCTRL_PIN(13, "ISH_I2C0_SDA"), + PINCTRL_PIN(14, "ISH_I2C0_SCL"), + PINCTRL_PIN(15, "ISH_I2C1_SDA"), + PINCTRL_PIN(16, "ISH_I2C1_SCL"), + PINCTRL_PIN(17, "I2C5_SDA"), + PINCTRL_PIN(18, "I2C5_SCL"), + PINCTRL_PIN(19, "PMCALERTB"), + PINCTRL_PIN(20, "SLP_S0B"), + PINCTRL_PIN(21, "PLTRSTB"), + PINCTRL_PIN(22, "SPKR"), + PINCTRL_PIN(23, "GSPI0_CS0B"), + PINCTRL_PIN(24, "GSPI0_CLK"), + PINCTRL_PIN(25, "GSPI0_MISO"), + PINCTRL_PIN(26, "GSPI0_MOSI"), + PINCTRL_PIN(27, "GSPI1_CS0B"), + PINCTRL_PIN(28, "GSPI1_CLK"), + PINCTRL_PIN(29, "GSPI1_MISO"), + PINCTRL_PIN(30, "GSPI1_MOSI"), + PINCTRL_PIN(31, "SML1ALERTB"), + PINCTRL_PIN(32, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(33, "GSPI1_CLK_LOOPBK"), + /* GPP_A */ + PINCTRL_PIN(34, "ESPI_IO_0"), + PINCTRL_PIN(35, "ESPI_IO_1"), + PINCTRL_PIN(36, "ESPI_IO_2"), + PINCTRL_PIN(37, "ESPI_IO_3"), + PINCTRL_PIN(38, "ESPI_CSB"), + PINCTRL_PIN(39, "ESPI_CLK"), + PINCTRL_PIN(40, "ESPI_RESETB"), + PINCTRL_PIN(41, "I2S2_SCLK"), + PINCTRL_PIN(42, "I2S2_SFRM"), + PINCTRL_PIN(43, "I2S2_TXD"), + PINCTRL_PIN(44, "I2S2_RXD"), + PINCTRL_PIN(45, "SATA_DEVSLP_2"), + PINCTRL_PIN(46, "SATAXPCIE_1"), + PINCTRL_PIN(47, "SATAXPCIE_2"), + PINCTRL_PIN(48, "USB2_OCB_1"), + PINCTRL_PIN(49, "USB2_OCB_2"), + PINCTRL_PIN(50, "USB2_OCB_3"), + PINCTRL_PIN(51, "DDSP_HPD_C"), + PINCTRL_PIN(52, "DDSP_HPD_B"), + PINCTRL_PIN(53, "DDSP_HPD_1"), + PINCTRL_PIN(54, "DDSP_HPD_2"), + PINCTRL_PIN(55, "I2S5_TXD"), + PINCTRL_PIN(56, "I2S5_RXD"), + PINCTRL_PIN(57, "I2S1_SCLK"), + PINCTRL_PIN(58, "ESPI_CLK_LOOPBK"), + /* GPP_H */ + PINCTRL_PIN(59, "SD_1P8_SEL"), + PINCTRL_PIN(60, "SD_PWR_EN_B"), + PINCTRL_PIN(61, "GPPC_H_2"), + PINCTRL_PIN(62, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(63, "I2C2_SDA"), + PINCTRL_PIN(64, "I2C2_SCL"), + PINCTRL_PIN(65, "I2C3_SDA"), + PINCTRL_PIN(66, "I2C3_SCL"), + PINCTRL_PIN(67, "I2C4_SDA"), + PINCTRL_PIN(68, "I2C4_SCL"), + PINCTRL_PIN(69, "SRCCLKREQB_4"), + PINCTRL_PIN(70, "SRCCLKREQB_5"), + PINCTRL_PIN(71, "M2_SKT2_CFG_0"), + PINCTRL_PIN(72, "M2_SKT2_CFG_1"), + PINCTRL_PIN(73, "M2_SKT2_CFG_2"), + PINCTRL_PIN(74, "M2_SKT2_CFG_3"), + PINCTRL_PIN(75, "DDPB_CTRLCLK"), + PINCTRL_PIN(76, "DDPB_CTRLDATA"), + PINCTRL_PIN(77, "CPU_VCCIO_PWR_GATEB"), + PINCTRL_PIN(78, "TIME_SYNC_0"), + PINCTRL_PIN(79, "IMGCLKOUT_1"), + PINCTRL_PIN(80, "IMGCLKOUT_2"), + PINCTRL_PIN(81, "IMGCLKOUT_3"), + PINCTRL_PIN(82, "IMGCLKOUT_4"), + /* GPP_D */ + PINCTRL_PIN(83, "ISH_GP_0"), + PINCTRL_PIN(84, "ISH_GP_1"), + PINCTRL_PIN(85, "ISH_GP_2"), + PINCTRL_PIN(86, "ISH_GP_3"), + PINCTRL_PIN(87, "IMGCLKOUT_0"), + PINCTRL_PIN(88, "SRCCLKREQB_0"), + PINCTRL_PIN(89, "SRCCLKREQB_1"), + PINCTRL_PIN(90, "SRCCLKREQB_2"), + PINCTRL_PIN(91, "SRCCLKREQB_3"), + PINCTRL_PIN(92, "ISH_SPI_CSB"), + PINCTRL_PIN(93, "ISH_SPI_CLK"), + PINCTRL_PIN(94, "ISH_SPI_MISO"), + PINCTRL_PIN(95, "ISH_SPI_MOSI"), + PINCTRL_PIN(96, "ISH_UART0_RXD"), + PINCTRL_PIN(97, "ISH_UART0_TXD"), + PINCTRL_PIN(98, "ISH_UART0_RTSB"), + PINCTRL_PIN(99, "ISH_UART0_CTSB"), + PINCTRL_PIN(100, "ISH_GP_4"), + PINCTRL_PIN(101, "ISH_GP_5"), + PINCTRL_PIN(102, "I2S_MCLK"), + PINCTRL_PIN(103, "GSPI2_CLK_LOOPBK"), + /* GPP_F */ + PINCTRL_PIN(104, "CNV_BRI_DT"), + PINCTRL_PIN(105, "CNV_BRI_RSP"), + PINCTRL_PIN(106, "CNV_RGI_DT"), + PINCTRL_PIN(107, "CNV_RGI_RSP"), + PINCTRL_PIN(108, "CNV_RF_RESET_B"), + PINCTRL_PIN(109, "EMMC_HIP_MON"), + PINCTRL_PIN(110, "CNV_PA_BLANKING"), + PINCTRL_PIN(111, "EMMC_CMD"), + PINCTRL_PIN(112, "EMMC_DATA0"), + PINCTRL_PIN(113, "EMMC_DATA1"), + PINCTRL_PIN(114, "EMMC_DATA2"), + PINCTRL_PIN(115, "EMMC_DATA3"), + PINCTRL_PIN(116, "EMMC_DATA4"), + PINCTRL_PIN(117, "EMMC_DATA5"), + PINCTRL_PIN(118, "EMMC_DATA6"), + PINCTRL_PIN(119, "EMMC_DATA7"), + PINCTRL_PIN(120, "EMMC_RCLK"), + PINCTRL_PIN(121, "EMMC_CLK"), + PINCTRL_PIN(122, "EMMC_RESETB"), + PINCTRL_PIN(123, "A4WP_PRESENT"), + /* vGPIO */ + PINCTRL_PIN(124, "CNV_BTEN"), + PINCTRL_PIN(125, "CNV_WCEN"), + PINCTRL_PIN(126, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(127, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(128, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(129, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(130, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(131, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(132, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(133, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(134, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(135, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(136, "vUART0_TXD"), + PINCTRL_PIN(137, "vUART0_RXD"), + PINCTRL_PIN(138, "vUART0_CTS_B"), + PINCTRL_PIN(139, "vUART0_RTS_B"), + PINCTRL_PIN(140, "vISH_UART0_TXD"), + PINCTRL_PIN(141, "vISH_UART0_RXD"), + PINCTRL_PIN(142, "vISH_UART0_CTS_B"), + PINCTRL_PIN(143, "vISH_UART0_RTS_B"), + PINCTRL_PIN(144, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(145, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(146, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(147, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(148, "vI2S2_SCLK"), + PINCTRL_PIN(149, "vI2S2_SFRM"), + PINCTRL_PIN(150, "vI2S2_TXD"), + PINCTRL_PIN(151, "vI2S2_RXD"), + PINCTRL_PIN(152, "vSD3_CD_B"), + /* GPP_C */ + PINCTRL_PIN(153, "SMBCLK"), + PINCTRL_PIN(154, "SMBDATA"), + PINCTRL_PIN(155, "SMBALERTB"), + PINCTRL_PIN(156, "SML0CLK"), + PINCTRL_PIN(157, "SML0DATA"), + PINCTRL_PIN(158, "SML0ALERTB"), + PINCTRL_PIN(159, "SML1CLK"), + PINCTRL_PIN(160, "SML1DATA"), + PINCTRL_PIN(161, "UART0_RXD"), + PINCTRL_PIN(162, "UART0_TXD"), + PINCTRL_PIN(163, "UART0_RTSB"), + PINCTRL_PIN(164, "UART0_CTSB"), + PINCTRL_PIN(165, "UART1_RXD"), + PINCTRL_PIN(166, "UART1_TXD"), + PINCTRL_PIN(167, "UART1_RTSB"), + PINCTRL_PIN(168, "UART1_CTSB"), + PINCTRL_PIN(169, "I2C0_SDA"), + PINCTRL_PIN(170, "I2C0_SCL"), + PINCTRL_PIN(171, "I2C1_SDA"), + PINCTRL_PIN(172, "I2C1_SCL"), + PINCTRL_PIN(173, "UART2_RXD"), + PINCTRL_PIN(174, "UART2_TXD"), + PINCTRL_PIN(175, "UART2_RTSB"), + PINCTRL_PIN(176, "UART2_CTSB"), + /* HVCMOS */ + PINCTRL_PIN(177, "L_BKLTEN"), + PINCTRL_PIN(178, "L_BKLTCTL"), + PINCTRL_PIN(179, "L_VDDEN"), + PINCTRL_PIN(180, "SYS_PWROK"), + PINCTRL_PIN(181, "SYS_RESETB"), + PINCTRL_PIN(182, "MLK_RSTB"), + /* GPP_E */ + PINCTRL_PIN(183, "SATAXPCIE_0"), + PINCTRL_PIN(184, "SPI1_IO_2"), + PINCTRL_PIN(185, "SPI1_IO_3"), + PINCTRL_PIN(186, "CPU_GP_0"), + PINCTRL_PIN(187, "SATA_DEVSLP_0"), + PINCTRL_PIN(188, "SATA_DEVSLP_1"), + PINCTRL_PIN(189, "GPPC_E_6"), + PINCTRL_PIN(190, "CPU_GP_1"), + PINCTRL_PIN(191, "SATA_LEDB"), + PINCTRL_PIN(192, "USB2_OCB_0"), + PINCTRL_PIN(193, "SPI1_CSB"), + PINCTRL_PIN(194, "SPI1_CLK"), + PINCTRL_PIN(195, "SPI1_MISO_IO_1"), + PINCTRL_PIN(196, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(197, "DDSP_HPD_A"), + PINCTRL_PIN(198, "ISH_GP_6"), + PINCTRL_PIN(199, "ISH_GP_7"), + PINCTRL_PIN(200, "DISP_MISC_4"), + PINCTRL_PIN(201, "DDP1_CTRLCLK"), + PINCTRL_PIN(202, "DDP1_CTRLDATA"), + PINCTRL_PIN(203, "DDP2_CTRLCLK"), + PINCTRL_PIN(204, "DDP2_CTRLDATA"), + PINCTRL_PIN(205, "DDPA_CTRLCLK"), + PINCTRL_PIN(206, "DDPA_CTRLDATA"), + /* JTAG */ + PINCTRL_PIN(207, "JTAG_TDO"), + PINCTRL_PIN(208, "JTAGX"), + PINCTRL_PIN(209, "PRDYB"), + PINCTRL_PIN(210, "PREQB"), + PINCTRL_PIN(211, "CPU_TRSTB"), + PINCTRL_PIN(212, "JTAG_TDI"), + PINCTRL_PIN(213, "JTAG_TMS"), + PINCTRL_PIN(214, "JTAG_TCK"), + PINCTRL_PIN(215, "ITP_PMODE"), + /* GPP_R */ + PINCTRL_PIN(216, "HDA_BCLK"), + PINCTRL_PIN(217, "HDA_SYNC"), + PINCTRL_PIN(218, "HDA_SDO"), + PINCTRL_PIN(219, "HDA_SDI_0"), + PINCTRL_PIN(220, "HDA_RSTB"), + PINCTRL_PIN(221, "HDA_SDI_1"), + PINCTRL_PIN(222, "I2S1_TXD"), + PINCTRL_PIN(223, "I2S1_RXD"), + /* GPP_S */ + PINCTRL_PIN(224, "SNDW1_CLK"), + PINCTRL_PIN(225, "SNDW1_DATA"), + PINCTRL_PIN(226, "SNDW2_CLK"), + PINCTRL_PIN(227, "SNDW2_DATA"), + PINCTRL_PIN(228, "SNDW3_CLK"), + PINCTRL_PIN(229, "SNDW3_DATA"), + PINCTRL_PIN(230, "SNDW4_CLK"), + PINCTRL_PIN(231, "SNDW4_DATA"), + /* SPI */ + PINCTRL_PIN(232, "SPI0_IO_2"), + PINCTRL_PIN(233, "SPI0_IO_3"), + PINCTRL_PIN(234, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(235, "SPI0_MISO_IO_1"), + PINCTRL_PIN(236, "SPI0_TPM_CSB"), + PINCTRL_PIN(237, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(238, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(239, "SPI0_CLK"), + PINCTRL_PIN(240, "SPI0_CLK_LOOPBK"), +}; + +static const struct intel_padgroup icllp_community0_gpps[] = { + ICL_GPP(0, 0, 7, 0), /* GPP_G */ + ICL_GPP(1, 8, 33, 32), /* GPP_B */ + ICL_GPP(2, 34, 58, 64), /* GPP_A */ +}; + +static const struct intel_padgroup icllp_community1_gpps[] = { + ICL_GPP(0, 59, 82, 96), /* GPP_H */ + ICL_GPP(1, 83, 103, 128), /* GPP_D */ + ICL_GPP(2, 104, 123, 160), /* GPP_F */ + ICL_GPP(3, 124, 152, 192), /* vGPIO */ +}; + +static const struct intel_padgroup icllp_community4_gpps[] = { + ICL_GPP(0, 153, 176, 224), /* GPP_C */ + ICL_GPP(1, 177, 182, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */ + ICL_GPP(2, 183, 206, 256), /* GPP_E */ + ICL_GPP(3, 207, 215, INTEL_GPIO_BASE_NOMAP), /* JTAG */ +}; + +static const struct intel_padgroup icllp_community5_gpps[] = { + ICL_GPP(0, 216, 223, 288), /* GPP_R */ + ICL_GPP(1, 224, 231, 320), /* GPP_S */ + ICL_GPP(2, 232, 240, INTEL_GPIO_BASE_NOMAP), /* SPI */ +}; + +static const struct intel_community icllp_communities[] = { + ICL_COMMUNITY(0, 0, 58, icllp_community0_gpps), + ICL_COMMUNITY(1, 59, 152, icllp_community1_gpps), + ICL_COMMUNITY(2, 153, 215, icllp_community4_gpps), + ICL_COMMUNITY(3, 216, 240, icllp_community5_gpps), +}; + +static const unsigned int icllp_spi0_pins[] = { 22, 23, 24, 25, 26 }; +static const unsigned int icllp_spi0_modes[] = { 3, 1, 1, 1, 1 }; +static const unsigned int icllp_spi1_pins[] = { 27, 28, 29, 30, 31 }; +static const unsigned int icllp_spi1_modes[] = { 1, 1, 1, 1, 3 }; +static const unsigned int icllp_spi2_pins[] = { 92, 93, 94, 95, 98 }; +static const unsigned int icllp_spi2_modes[] = { 3, 3, 3, 3, 2 }; + +static const unsigned int icllp_i2c0_pins[] = { 169, 170 }; +static const unsigned int icllp_i2c1_pins[] = { 171, 172 }; +static const unsigned int icllp_i2c2_pins[] = { 63, 64 }; +static const unsigned int icllp_i2c3_pins[] = { 65, 66 }; +static const unsigned int icllp_i2c4_pins[] = { 67, 68 }; + +static const unsigned int icllp_uart0_pins[] = { 161, 162, 163, 164 }; +static const unsigned int icllp_uart1_pins[] = { 165, 166, 167, 168 }; +static const unsigned int icllp_uart2_pins[] = { 173, 174, 175, 176 }; + +static const struct intel_pingroup icllp_groups[] = { + PIN_GROUP("spi0_grp", icllp_spi0_pins, icllp_spi0_modes), + PIN_GROUP("spi1_grp", icllp_spi1_pins, icllp_spi1_modes), + PIN_GROUP("spi2_grp", icllp_spi2_pins, icllp_spi2_modes), + PIN_GROUP("i2c0_grp", icllp_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", icllp_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", icllp_i2c2_pins, 1), + PIN_GROUP("i2c3_grp", icllp_i2c3_pins, 1), + PIN_GROUP("i2c4_grp", icllp_i2c4_pins, 1), + PIN_GROUP("uart0_grp", icllp_uart0_pins, 1), + PIN_GROUP("uart1_grp", icllp_uart1_pins, 1), + PIN_GROUP("uart2_grp", icllp_uart2_pins, 1), +}; + +static const char * const icllp_spi0_groups[] = { "spi0_grp" }; +static const char * const icllp_spi1_groups[] = { "spi1_grp" }; +static const char * const icllp_spi2_groups[] = { "spi2_grp" }; +static const char * const icllp_i2c0_groups[] = { "i2c0_grp" }; +static const char * const icllp_i2c1_groups[] = { "i2c1_grp" }; +static const char * const icllp_i2c2_groups[] = { "i2c2_grp" }; +static const char * const icllp_i2c3_groups[] = { "i2c3_grp" }; +static const char * const icllp_i2c4_groups[] = { "i2c4_grp" }; +static const char * const icllp_uart0_groups[] = { "uart0_grp" }; +static const char * const icllp_uart1_groups[] = { "uart1_grp" }; +static const char * const icllp_uart2_groups[] = { "uart2_grp" }; + +static const struct intel_function icllp_functions[] = { + FUNCTION("spi0", icllp_spi0_groups), + FUNCTION("spi1", icllp_spi1_groups), + FUNCTION("spi2", icllp_spi2_groups), + FUNCTION("i2c0", icllp_i2c0_groups), + FUNCTION("i2c1", icllp_i2c1_groups), + FUNCTION("i2c2", icllp_i2c2_groups), + FUNCTION("i2c3", icllp_i2c3_groups), + FUNCTION("i2c4", icllp_i2c4_groups), + FUNCTION("uart0", icllp_uart0_groups), + FUNCTION("uart1", icllp_uart1_groups), + FUNCTION("uart2", icllp_uart2_groups), +}; + +static const struct intel_pinctrl_soc_data icllp_soc_data = { + .pins = icllp_pins, + .npins = ARRAY_SIZE(icllp_pins), + .groups = icllp_groups, + .ngroups = ARRAY_SIZE(icllp_groups), + .functions = icllp_functions, + .nfunctions = ARRAY_SIZE(icllp_functions), + .communities = icllp_communities, + .ncommunities = ARRAY_SIZE(icllp_communities), +}; + +static INTEL_PINCTRL_PM_OPS(icl_pinctrl_pm_ops); + +static const struct acpi_device_id icl_pinctrl_acpi_match[] = { + { "INT3455", (kernel_ulong_t)&icllp_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, icl_pinctrl_acpi_match); + +static struct platform_driver icl_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "icelake-pinctrl", + .acpi_match_table = icl_pinctrl_acpi_match, + .pm = &icl_pinctrl_pm_ops, + }, +}; + +module_platform_driver(icl_pinctrl_driver); + +MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Ice Lake PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c new file mode 100644 index 000000000..2ef9e2d8f --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -0,0 +1,1814 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel pinctrl/GPIO core driver. + * + * Copyright (C) 2015, Intel Corporation + * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/acpi.h> +#include <linux/gpio/driver.h> +#include <linux/interrupt.h> +#include <linux/log2.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/time.h> + +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> + +#include "../core.h" +#include "pinctrl-intel.h" + +/* Offset from regs */ +#define REVID 0x000 +#define REVID_SHIFT 16 +#define REVID_MASK GENMASK(31, 16) + +#define PADBAR 0x00c + +#define PADOWN_BITS 4 +#define PADOWN_SHIFT(p) ((p) % 8 * PADOWN_BITS) +#define PADOWN_MASK(p) (GENMASK(3, 0) << PADOWN_SHIFT(p)) +#define PADOWN_GPP(p) ((p) / 8) + +/* Offset from pad_regs */ +#define PADCFG0 0x000 +#define PADCFG0_RXEVCFG_SHIFT 25 +#define PADCFG0_RXEVCFG_MASK GENMASK(26, 25) +#define PADCFG0_RXEVCFG_LEVEL 0 +#define PADCFG0_RXEVCFG_EDGE 1 +#define PADCFG0_RXEVCFG_DISABLED 2 +#define PADCFG0_RXEVCFG_EDGE_BOTH 3 +#define PADCFG0_PREGFRXSEL BIT(24) +#define PADCFG0_RXINV BIT(23) +#define PADCFG0_GPIROUTIOXAPIC BIT(20) +#define PADCFG0_GPIROUTSCI BIT(19) +#define PADCFG0_GPIROUTSMI BIT(18) +#define PADCFG0_GPIROUTNMI BIT(17) +#define PADCFG0_PMODE_SHIFT 10 +#define PADCFG0_PMODE_MASK GENMASK(13, 10) +#define PADCFG0_PMODE_GPIO 0 +#define PADCFG0_GPIORXDIS BIT(9) +#define PADCFG0_GPIOTXDIS BIT(8) +#define PADCFG0_GPIORXSTATE BIT(1) +#define PADCFG0_GPIOTXSTATE BIT(0) + +#define PADCFG1 0x004 +#define PADCFG1_TERM_UP BIT(13) +#define PADCFG1_TERM_SHIFT 10 +#define PADCFG1_TERM_MASK GENMASK(12, 10) +#define PADCFG1_TERM_20K BIT(2) +#define PADCFG1_TERM_5K BIT(1) +#define PADCFG1_TERM_1K BIT(0) +#define PADCFG1_TERM_833 (BIT(1) | BIT(0)) + +#define PADCFG2 0x008 +#define PADCFG2_DEBEN BIT(0) +#define PADCFG2_DEBOUNCE_SHIFT 1 +#define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1) + +#define DEBOUNCE_PERIOD_NSEC 31250 + +struct intel_pad_context { + u32 padcfg0; + u32 padcfg1; + u32 padcfg2; +}; + +struct intel_community_context { + u32 *intmask; + u32 *hostown; +}; + +#define pin_to_padno(c, p) ((p) - (c)->pin_base) +#define padgroup_offset(g, p) ((p) - (g)->base) + +static struct intel_community *intel_get_community(struct intel_pinctrl *pctrl, + unsigned int pin) +{ + struct intel_community *community; + int i; + + for (i = 0; i < pctrl->ncommunities; i++) { + community = &pctrl->communities[i]; + if (pin >= community->pin_base && + pin < community->pin_base + community->npins) + return community; + } + + dev_warn(pctrl->dev, "failed to find community for pin %u\n", pin); + return NULL; +} + +static const struct intel_padgroup * +intel_community_get_padgroup(const struct intel_community *community, + unsigned int pin) +{ + int i; + + for (i = 0; i < community->ngpps; i++) { + const struct intel_padgroup *padgrp = &community->gpps[i]; + + if (pin >= padgrp->base && pin < padgrp->base + padgrp->size) + return padgrp; + } + + return NULL; +} + +static void __iomem *intel_get_padcfg(struct intel_pinctrl *pctrl, + unsigned int pin, unsigned int reg) +{ + const struct intel_community *community; + unsigned int padno; + size_t nregs; + + community = intel_get_community(pctrl, pin); + if (!community) + return NULL; + + padno = pin_to_padno(community, pin); + nregs = (community->features & PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2; + + if (reg >= nregs * 4) + return NULL; + + return community->pad_regs + reg + padno * nregs * 4; +} + +static bool intel_pad_owned_by_host(struct intel_pinctrl *pctrl, unsigned int pin) +{ + const struct intel_community *community; + const struct intel_padgroup *padgrp; + unsigned int gpp, offset, gpp_offset; + void __iomem *padown; + + community = intel_get_community(pctrl, pin); + if (!community) + return false; + if (!community->padown_offset) + return true; + + padgrp = intel_community_get_padgroup(community, pin); + if (!padgrp) + return false; + + gpp_offset = padgroup_offset(padgrp, pin); + gpp = PADOWN_GPP(gpp_offset); + offset = community->padown_offset + padgrp->padown_num * 4 + gpp * 4; + padown = community->regs + offset; + + return !(readl(padown) & PADOWN_MASK(gpp_offset)); +} + +static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin) +{ + const struct intel_community *community; + const struct intel_padgroup *padgrp; + unsigned int offset, gpp_offset; + void __iomem *hostown; + + community = intel_get_community(pctrl, pin); + if (!community) + return true; + if (!community->hostown_offset) + return false; + + padgrp = intel_community_get_padgroup(community, pin); + if (!padgrp) + return true; + + gpp_offset = padgroup_offset(padgrp, pin); + offset = community->hostown_offset + padgrp->reg_num * 4; + hostown = community->regs + offset; + + return !(readl(hostown) & BIT(gpp_offset)); +} + +/** + * enum - Locking variants of the pad configuration + * + * @PAD_UNLOCKED: pad is fully controlled by the configuration registers + * @PAD_LOCKED: pad configuration registers, except TX state, are locked + * @PAD_LOCKED_TX: pad configuration TX state is locked + * @PAD_LOCKED_FULL: pad configuration registers are locked completely + * + * Locking is considered as read-only mode for corresponding registers and + * their respective fields. That said, TX state bit is locked separately from + * the main locking scheme. + */ +enum { + PAD_UNLOCKED = 0, + PAD_LOCKED = 1, + PAD_LOCKED_TX = 2, + PAD_LOCKED_FULL = PAD_LOCKED | PAD_LOCKED_TX, +}; + +static int intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin) +{ + struct intel_community *community; + const struct intel_padgroup *padgrp; + unsigned int offset, gpp_offset; + u32 value; + int ret = PAD_UNLOCKED; + + community = intel_get_community(pctrl, pin); + if (!community) + return PAD_LOCKED_FULL; + if (!community->padcfglock_offset) + return PAD_UNLOCKED; + + padgrp = intel_community_get_padgroup(community, pin); + if (!padgrp) + return PAD_LOCKED_FULL; + + gpp_offset = padgroup_offset(padgrp, pin); + + /* + * If PADCFGLOCK and PADCFGLOCKTX bits are both clear for this pad, + * the pad is considered unlocked. Any other case means that it is + * either fully or partially locked. + */ + offset = community->padcfglock_offset + 0 + padgrp->reg_num * 8; + value = readl(community->regs + offset); + if (value & BIT(gpp_offset)) + ret |= PAD_LOCKED; + + offset = community->padcfglock_offset + 4 + padgrp->reg_num * 8; + value = readl(community->regs + offset); + if (value & BIT(gpp_offset)) + ret |= PAD_LOCKED_TX; + + return ret; +} + +static bool intel_pad_is_unlocked(struct intel_pinctrl *pctrl, unsigned int pin) +{ + return (intel_pad_locked(pctrl, pin) & PAD_LOCKED) == PAD_UNLOCKED; +} + +static bool intel_pad_usable(struct intel_pinctrl *pctrl, unsigned int pin) +{ + return intel_pad_owned_by_host(pctrl, pin) && intel_pad_is_unlocked(pctrl, pin); +} + +static int intel_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->ngroups; +} + +static const char *intel_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->groups[group].name; +} + +static int intel_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, + const unsigned int **pins, unsigned int *npins) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *pins = pctrl->soc->groups[group].pins; + *npins = pctrl->soc->groups[group].npins; + return 0; +} + +static void intel_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + void __iomem *padcfg; + u32 cfg0, cfg1, mode; + int locked; + bool acpi; + + if (!intel_pad_owned_by_host(pctrl, pin)) { + seq_puts(s, "not available"); + return; + } + + cfg0 = readl(intel_get_padcfg(pctrl, pin, PADCFG0)); + cfg1 = readl(intel_get_padcfg(pctrl, pin, PADCFG1)); + + mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; + if (mode == PADCFG0_PMODE_GPIO) + seq_puts(s, "GPIO "); + else + seq_printf(s, "mode %d ", mode); + + seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1); + + /* Dump the additional PADCFG registers if available */ + padcfg = intel_get_padcfg(pctrl, pin, PADCFG2); + if (padcfg) + seq_printf(s, " 0x%08x", readl(padcfg)); + + locked = intel_pad_locked(pctrl, pin); + acpi = intel_pad_acpi_mode(pctrl, pin); + + if (locked || acpi) { + seq_puts(s, " ["); + if (locked) + seq_puts(s, "LOCKED"); + if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_TX) + seq_puts(s, " tx"); + else if ((locked & PAD_LOCKED_FULL) == PAD_LOCKED_FULL) + seq_puts(s, " full"); + + if (locked && acpi) + seq_puts(s, ", "); + + if (acpi) + seq_puts(s, "ACPI"); + seq_puts(s, "]"); + } +} + +static const struct pinctrl_ops intel_pinctrl_ops = { + .get_groups_count = intel_get_groups_count, + .get_group_name = intel_get_group_name, + .get_group_pins = intel_get_group_pins, + .pin_dbg_show = intel_pin_dbg_show, +}; + +static int intel_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->nfunctions; +} + +static const char *intel_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + return pctrl->soc->functions[function].name; +} + +static int intel_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char * const **groups, + unsigned int * const ngroups) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + + *groups = pctrl->soc->functions[function].groups; + *ngroups = pctrl->soc->functions[function].ngroups; + return 0; +} + +static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pingroup *grp = &pctrl->soc->groups[group]; + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + /* + * All pins in the groups needs to be accessible and writable + * before we can enable the mux for this group. + */ + for (i = 0; i < grp->npins; i++) { + if (!intel_pad_usable(pctrl, grp->pins[i])) { + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return -EBUSY; + } + } + + /* Now enable the mux setting for each pin in the group */ + for (i = 0; i < grp->npins; i++) { + void __iomem *padcfg0; + u32 value; + + padcfg0 = intel_get_padcfg(pctrl, grp->pins[i], PADCFG0); + value = readl(padcfg0); + + value &= ~PADCFG0_PMODE_MASK; + + if (grp->modes) + value |= grp->modes[i] << PADCFG0_PMODE_SHIFT; + else + value |= grp->mode << PADCFG0_PMODE_SHIFT; + + writel(value, padcfg0); + } + + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) +{ + u32 value; + + value = readl(padcfg0); + if (input) { + value &= ~PADCFG0_GPIORXDIS; + value |= PADCFG0_GPIOTXDIS; + } else { + value &= ~PADCFG0_GPIOTXDIS; + value |= PADCFG0_GPIORXDIS; + } + writel(value, padcfg0); +} + +static int __intel_gpio_get_gpio_mode(u32 value) +{ + return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; +} + +static int intel_gpio_get_gpio_mode(void __iomem *padcfg0) +{ + return __intel_gpio_get_gpio_mode(readl(padcfg0)); +} + +static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) +{ + u32 value; + + value = readl(padcfg0); + + /* Put the pad into GPIO mode */ + value &= ~PADCFG0_PMODE_MASK; + value |= PADCFG0_PMODE_GPIO; + + /* Disable TX buffer and enable RX (this will be input) */ + value &= ~PADCFG0_GPIORXDIS; + value |= PADCFG0_GPIOTXDIS; + + /* Disable SCI/SMI/NMI generation */ + value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); + value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); + + writel(value, padcfg0); +} + +static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + void __iomem *padcfg0; + unsigned long flags; + + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + if (!intel_pad_owned_by_host(pctrl, pin)) { + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return -EBUSY; + } + + if (!intel_pad_is_unlocked(pctrl, pin)) { + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return 0; + } + + /* + * If pin is already configured in GPIO mode, we assume that + * firmware provides correct settings. In such case we avoid + * potential glitches on the pin. Otherwise, for the pin in + * alternative mode, consumer has to supply respective flags. + */ + if (intel_gpio_get_gpio_mode(padcfg0) == PADCFG0_PMODE_GPIO) { + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return 0; + } + + intel_gpio_set_gpio_mode(padcfg0); + + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + void __iomem *padcfg0; + unsigned long flags; + + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + __intel_gpio_set_direction(padcfg0, input); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static const struct pinmux_ops intel_pinmux_ops = { + .get_functions_count = intel_get_functions_count, + .get_function_name = intel_get_function_name, + .get_function_groups = intel_get_function_groups, + .set_mux = intel_pinmux_set_mux, + .gpio_request_enable = intel_gpio_request_enable, + .gpio_set_direction = intel_gpio_set_direction, +}; + +static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) +{ + const struct intel_community *community; + void __iomem *padcfg1; + unsigned long flags; + u32 value, term; + + community = intel_get_community(pctrl, pin); + padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + value = readl(padcfg1); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (term) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if (!term || !(value & PADCFG1_TERM_UP)) + return -EINVAL; + + switch (term) { + case PADCFG1_TERM_833: + *arg = 833; + break; + case PADCFG1_TERM_1K: + *arg = 1000; + break; + case PADCFG1_TERM_5K: + *arg = 5000; + break; + case PADCFG1_TERM_20K: + *arg = 20000; + break; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if (!term || value & PADCFG1_TERM_UP) + return -EINVAL; + + switch (term) { + case PADCFG1_TERM_833: + if (!(community->features & PINCTRL_FEATURE_1K_PD)) + return -EINVAL; + *arg = 833; + break; + case PADCFG1_TERM_1K: + if (!(community->features & PINCTRL_FEATURE_1K_PD)) + return -EINVAL; + *arg = 1000; + break; + case PADCFG1_TERM_5K: + *arg = 5000; + break; + case PADCFG1_TERM_20K: + *arg = 20000; + break; + } + + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) +{ + void __iomem *padcfg2; + unsigned long flags; + unsigned long v; + u32 value2; + + padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); + if (!padcfg2) + return -ENOTSUPP; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + value2 = readl(padcfg2); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + if (!(value2 & PADCFG2_DEBEN)) + return -EINVAL; + + v = (value2 & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; + *arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; + + return 0; +} + +static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 arg = 0; + int ret; + + if (!intel_pad_owned_by_host(pctrl, pin)) + return -ENOTSUPP; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = intel_config_get_pull(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + + case PIN_CONFIG_INPUT_DEBOUNCE: + ret = intel_config_get_debounce(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, + unsigned long config) +{ + unsigned int param = pinconf_to_config_param(config); + unsigned int arg = pinconf_to_config_argument(config); + const struct intel_community *community; + void __iomem *padcfg1; + unsigned long flags; + int ret = 0; + u32 value; + + community = intel_get_community(pctrl, pin); + padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + value = readl(padcfg1); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + value &= ~(PADCFG1_TERM_MASK | PADCFG1_TERM_UP); + break; + + case PIN_CONFIG_BIAS_PULL_UP: + value &= ~PADCFG1_TERM_MASK; + + value |= PADCFG1_TERM_UP; + + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 5000; + + switch (arg) { + case 20000: + value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT; + break; + case 5000: + value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT; + break; + case 1000: + value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT; + break; + case 833: + value |= PADCFG1_TERM_833 << PADCFG1_TERM_SHIFT; + break; + default: + ret = -EINVAL; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK); + + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 5000; + + switch (arg) { + case 20000: + value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT; + break; + case 5000: + value |= PADCFG1_TERM_5K << PADCFG1_TERM_SHIFT; + break; + case 1000: + if (!(community->features & PINCTRL_FEATURE_1K_PD)) { + ret = -EINVAL; + break; + } + value |= PADCFG1_TERM_1K << PADCFG1_TERM_SHIFT; + break; + case 833: + if (!(community->features & PINCTRL_FEATURE_1K_PD)) { + ret = -EINVAL; + break; + } + value |= PADCFG1_TERM_833 << PADCFG1_TERM_SHIFT; + break; + default: + ret = -EINVAL; + } + + break; + } + + if (!ret) + writel(value, padcfg1); + + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return ret; +} + +static int intel_config_set_debounce(struct intel_pinctrl *pctrl, + unsigned int pin, unsigned int debounce) +{ + void __iomem *padcfg0, *padcfg2; + unsigned long flags; + u32 value0, value2; + + padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); + if (!padcfg2) + return -ENOTSUPP; + + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + value0 = readl(padcfg0); + value2 = readl(padcfg2); + + /* Disable glitch filter and debouncer */ + value0 &= ~PADCFG0_PREGFRXSEL; + value2 &= ~(PADCFG2_DEBEN | PADCFG2_DEBOUNCE_MASK); + + if (debounce) { + unsigned long v; + + v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); + if (v < 3 || v > 15) { + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return -EINVAL; + } + + /* Enable glitch filter and debouncer */ + value0 |= PADCFG0_PREGFRXSEL; + value2 |= v << PADCFG2_DEBOUNCE_SHIFT; + value2 |= PADCFG2_DEBEN; + } + + writel(value0, padcfg0); + writel(value2, padcfg2); + + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfigs) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + int i, ret; + + if (!intel_pad_usable(pctrl, pin)) + return -ENOTSUPP; + + for (i = 0; i < nconfigs; i++) { + switch (pinconf_to_config_param(configs[i])) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = intel_config_set_pull(pctrl, pin, configs[i]); + if (ret) + return ret; + break; + + case PIN_CONFIG_INPUT_DEBOUNCE: + ret = intel_config_set_debounce(pctrl, pin, + pinconf_to_config_argument(configs[i])); + if (ret) + return ret; + break; + + default: + return -ENOTSUPP; + } + } + + return 0; +} + +static const struct pinconf_ops intel_pinconf_ops = { + .is_generic = true, + .pin_config_get = intel_config_get, + .pin_config_set = intel_config_set, +}; + +static const struct pinctrl_desc intel_pinctrl_desc = { + .pctlops = &intel_pinctrl_ops, + .pmxops = &intel_pinmux_ops, + .confops = &intel_pinconf_ops, + .owner = THIS_MODULE, +}; + +/** + * intel_gpio_to_pin() - Translate from GPIO offset to pin number + * @pctrl: Pinctrl structure + * @offset: GPIO offset from gpiolib + * @community: Community is filled here if not %NULL + * @padgrp: Pad group is filled here if not %NULL + * + * When coming through gpiolib irqchip, the GPIO offset is not + * automatically translated to pinctrl pin number. This function can be + * used to find out the corresponding pinctrl pin. + */ +static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned int offset, + const struct intel_community **community, + const struct intel_padgroup **padgrp) +{ + int i; + + for (i = 0; i < pctrl->ncommunities; i++) { + const struct intel_community *comm = &pctrl->communities[i]; + int j; + + for (j = 0; j < comm->ngpps; j++) { + const struct intel_padgroup *pgrp = &comm->gpps[j]; + + if (pgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) + continue; + + if (offset >= pgrp->gpio_base && + offset < pgrp->gpio_base + pgrp->size) { + int pin; + + pin = pgrp->base + offset - pgrp->gpio_base; + if (community) + *community = comm; + if (padgrp) + *padgrp = pgrp; + + return pin; + } + } + } + + return -EINVAL; +} + +/** + * intel_pin_to_gpio() - Translate from pin number to GPIO offset + * @pctrl: Pinctrl structure + * @pin: pin number + * + * Translate the pin number of pinctrl to GPIO offset + */ +static __maybe_unused int intel_pin_to_gpio(struct intel_pinctrl *pctrl, int pin) +{ + const struct intel_community *community; + const struct intel_padgroup *padgrp; + + community = intel_get_community(pctrl, pin); + if (!community) + return -EINVAL; + + padgrp = intel_community_get_padgroup(community, pin); + if (!padgrp) + return -EINVAL; + + return pin - padgrp->base + padgrp->gpio_base; +} + +static int intel_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + void __iomem *reg; + u32 padcfg0; + int pin; + + pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL); + if (pin < 0) + return -EINVAL; + + reg = intel_get_padcfg(pctrl, pin, PADCFG0); + if (!reg) + return -EINVAL; + + padcfg0 = readl(reg); + if (!(padcfg0 & PADCFG0_GPIOTXDIS)) + return !!(padcfg0 & PADCFG0_GPIOTXSTATE); + + return !!(padcfg0 & PADCFG0_GPIORXSTATE); +} + +static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + unsigned long flags; + void __iomem *reg; + u32 padcfg0; + int pin; + + pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL); + if (pin < 0) + return; + + reg = intel_get_padcfg(pctrl, pin, PADCFG0); + if (!reg) + return; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + padcfg0 = readl(reg); + if (value) + padcfg0 |= PADCFG0_GPIOTXSTATE; + else + padcfg0 &= ~PADCFG0_GPIOTXSTATE; + writel(padcfg0, reg); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); +} + +static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + unsigned long flags; + void __iomem *reg; + u32 padcfg0; + int pin; + + pin = intel_gpio_to_pin(pctrl, offset, NULL, NULL); + if (pin < 0) + return -EINVAL; + + reg = intel_get_padcfg(pctrl, pin, PADCFG0); + if (!reg) + return -EINVAL; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + padcfg0 = readl(reg); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + if (padcfg0 & PADCFG0_PMODE_MASK) + return -EINVAL; + + if (padcfg0 & PADCFG0_GPIOTXDIS) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + +static int intel_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + return pinctrl_gpio_direction_input(chip->base + offset); +} + +static int intel_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) +{ + intel_gpio_set(chip, offset, value); + return pinctrl_gpio_direction_output(chip->base + offset); +} + +static const struct gpio_chip intel_gpio_chip = { + .owner = THIS_MODULE, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .get_direction = intel_gpio_get_direction, + .direction_input = intel_gpio_direction_input, + .direction_output = intel_gpio_direction_output, + .get = intel_gpio_get, + .set = intel_gpio_set, + .set_config = gpiochip_generic_config, +}; + +static void intel_gpio_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + const struct intel_community *community; + const struct intel_padgroup *padgrp; + int pin; + + pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp); + if (pin >= 0) { + unsigned int gpp, gpp_offset, is_offset; + + gpp = padgrp->reg_num; + gpp_offset = padgroup_offset(padgrp, pin); + is_offset = community->is_offset + gpp * 4; + + raw_spin_lock(&pctrl->lock); + writel(BIT(gpp_offset), community->regs + is_offset); + raw_spin_unlock(&pctrl->lock); + } +} + +static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + const struct intel_community *community; + const struct intel_padgroup *padgrp; + int pin; + + pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp); + if (pin >= 0) { + unsigned int gpp, gpp_offset; + unsigned long flags; + void __iomem *reg, *is; + u32 value; + + gpp = padgrp->reg_num; + gpp_offset = padgroup_offset(padgrp, pin); + + reg = community->regs + community->ie_offset + gpp * 4; + is = community->regs + community->is_offset + gpp * 4; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + /* Clear interrupt status first to avoid unexpected interrupt */ + writel(BIT(gpp_offset), is); + + value = readl(reg); + if (mask) + value &= ~BIT(gpp_offset); + else + value |= BIT(gpp_offset); + writel(value, reg); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + } +} + +static void intel_gpio_irq_mask(struct irq_data *d) +{ + intel_gpio_irq_mask_unmask(d, true); +} + +static void intel_gpio_irq_unmask(struct irq_data *d) +{ + intel_gpio_irq_mask_unmask(d, false); +} + +static int intel_gpio_irq_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL); + unsigned long flags; + void __iomem *reg; + u32 value; + + reg = intel_get_padcfg(pctrl, pin, PADCFG0); + if (!reg) + return -EINVAL; + + /* + * If the pin is in ACPI mode it is still usable as a GPIO but it + * cannot be used as IRQ because GPI_IS status bit will not be + * updated by the host controller hardware. + */ + if (intel_pad_acpi_mode(pctrl, pin)) { + dev_warn(pctrl->dev, "pin %u cannot be used as IRQ\n", pin); + return -EPERM; + } + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + intel_gpio_set_gpio_mode(reg); + + value = readl(reg); + + value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV); + + if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { + value |= PADCFG0_RXEVCFG_EDGE_BOTH << PADCFG0_RXEVCFG_SHIFT; + } else if (type & IRQ_TYPE_EDGE_FALLING) { + value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT; + value |= PADCFG0_RXINV; + } else if (type & IRQ_TYPE_EDGE_RISING) { + value |= PADCFG0_RXEVCFG_EDGE << PADCFG0_RXEVCFG_SHIFT; + } else if (type & IRQ_TYPE_LEVEL_MASK) { + if (type & IRQ_TYPE_LEVEL_LOW) + value |= PADCFG0_RXINV; + } else { + value |= PADCFG0_RXEVCFG_DISABLED << PADCFG0_RXEVCFG_SHIFT; + } + + writel(value, reg); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return 0; +} + +static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + unsigned int pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL); + + if (on) + enable_irq_wake(pctrl->irq); + else + disable_irq_wake(pctrl->irq); + + dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin); + return 0; +} + +static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, + const struct intel_community *community) +{ + struct gpio_chip *gc = &pctrl->chip; + unsigned int gpp; + int ret = 0; + + for (gpp = 0; gpp < community->ngpps; gpp++) { + const struct intel_padgroup *padgrp = &community->gpps[gpp]; + unsigned long pending, enabled, gpp_offset; + unsigned long flags; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + + pending = readl(community->regs + community->is_offset + + padgrp->reg_num * 4); + enabled = readl(community->regs + community->ie_offset + + padgrp->reg_num * 4); + + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + /* Only interrupts that are enabled */ + pending &= enabled; + + for_each_set_bit(gpp_offset, &pending, padgrp->size) { + unsigned int irq; + + irq = irq_find_mapping(gc->irq.domain, + padgrp->gpio_base + gpp_offset); + generic_handle_irq(irq); + } + + ret += pending ? 1 : 0; + } + + return ret; +} + +static irqreturn_t intel_gpio_irq(int irq, void *data) +{ + const struct intel_community *community; + struct intel_pinctrl *pctrl = data; + unsigned int i; + int ret = 0; + + /* Need to check all communities for pending interrupts */ + for (i = 0; i < pctrl->ncommunities; i++) { + community = &pctrl->communities[i]; + ret += intel_gpio_community_irq_handler(pctrl, community); + } + + return IRQ_RETVAL(ret); +} + +static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) +{ + int i; + + for (i = 0; i < pctrl->ncommunities; i++) { + const struct intel_community *community; + void __iomem *base; + unsigned int gpp; + + community = &pctrl->communities[i]; + base = community->regs; + + for (gpp = 0; gpp < community->ngpps; gpp++) { + /* Mask and clear all interrupts */ + writel(0, base + community->ie_offset + gpp * 4); + writel(0xffff, base + community->is_offset + gpp * 4); + } + } +} + +static int intel_gpio_irq_init_hw(struct gpio_chip *gc) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + + /* + * Make sure the interrupt lines are in a proper state before + * further configuration. + */ + intel_gpio_irq_init(pctrl); + + return 0; +} + +static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl, + const struct intel_community *community) +{ + int ret = 0, i; + + for (i = 0; i < community->ngpps; i++) { + const struct intel_padgroup *gpp = &community->gpps[i]; + + if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP) + continue; + + ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), + gpp->gpio_base, gpp->base, + gpp->size); + if (ret) + return ret; + } + + return ret; +} + +static int intel_gpio_add_pin_ranges(struct gpio_chip *gc) +{ + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + int ret, i; + + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + + ret = intel_gpio_add_community_ranges(pctrl, community); + if (ret) { + dev_err(pctrl->dev, "failed to add GPIO pin range\n"); + return ret; + } + } + + return 0; +} + +static unsigned int intel_gpio_ngpio(const struct intel_pinctrl *pctrl) +{ + const struct intel_community *community; + unsigned int ngpio = 0; + int i, j; + + for (i = 0; i < pctrl->ncommunities; i++) { + community = &pctrl->communities[i]; + for (j = 0; j < community->ngpps; j++) { + const struct intel_padgroup *gpp = &community->gpps[j]; + + if (gpp->gpio_base == INTEL_GPIO_BASE_NOMAP) + continue; + + if (gpp->gpio_base + gpp->size > ngpio) + ngpio = gpp->gpio_base + gpp->size; + } + } + + return ngpio; +} + +static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) +{ + int ret; + struct gpio_irq_chip *girq; + + pctrl->chip = intel_gpio_chip; + + /* Setup GPIO chip */ + pctrl->chip.ngpio = intel_gpio_ngpio(pctrl); + pctrl->chip.label = dev_name(pctrl->dev); + pctrl->chip.parent = pctrl->dev; + pctrl->chip.base = -1; + pctrl->chip.add_pin_ranges = intel_gpio_add_pin_ranges; + pctrl->irq = irq; + + /* Setup IRQ chip */ + pctrl->irqchip.name = dev_name(pctrl->dev); + pctrl->irqchip.irq_ack = intel_gpio_irq_ack; + pctrl->irqchip.irq_mask = intel_gpio_irq_mask; + pctrl->irqchip.irq_unmask = intel_gpio_irq_unmask; + pctrl->irqchip.irq_set_type = intel_gpio_irq_type; + pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake; + pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND; + + /* + * On some platforms several GPIO controllers share the same interrupt + * line. + */ + ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, + IRQF_SHARED | IRQF_NO_THREAD, + dev_name(pctrl->dev), pctrl); + if (ret) { + dev_err(pctrl->dev, "failed to request interrupt\n"); + return ret; + } + + girq = &pctrl->chip.irq; + girq->chip = &pctrl->irqchip; + /* This will let us handle the IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + girq->init_hw = intel_gpio_irq_init_hw; + + ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl); + if (ret) { + dev_err(pctrl->dev, "failed to register gpiochip\n"); + return ret; + } + + return 0; +} + +static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl, + struct intel_community *community) +{ + struct intel_padgroup *gpps; + unsigned int npins = community->npins; + unsigned int padown_num = 0; + size_t ngpps, i; + + if (community->gpps) + ngpps = community->ngpps; + else + ngpps = DIV_ROUND_UP(community->npins, community->gpp_size); + + gpps = devm_kcalloc(pctrl->dev, ngpps, sizeof(*gpps), GFP_KERNEL); + if (!gpps) + return -ENOMEM; + + for (i = 0; i < ngpps; i++) { + if (community->gpps) { + gpps[i] = community->gpps[i]; + } else { + unsigned int gpp_size = community->gpp_size; + + gpps[i].reg_num = i; + gpps[i].base = community->pin_base + i * gpp_size; + gpps[i].size = min(gpp_size, npins); + npins -= gpps[i].size; + } + + if (gpps[i].size > 32) + return -EINVAL; + + /* Special treatment for GPIO base */ + switch (gpps[i].gpio_base) { + case INTEL_GPIO_BASE_MATCH: + gpps[i].gpio_base = gpps[i].base; + break; + case INTEL_GPIO_BASE_ZERO: + gpps[i].gpio_base = 0; + break; + case INTEL_GPIO_BASE_NOMAP: + default: + break; + } + + gpps[i].padown_num = padown_num; + + /* + * In older hardware the number of padown registers per + * group is fixed regardless of the group size. + */ + if (community->gpp_num_padown_regs) + padown_num += community->gpp_num_padown_regs; + else + padown_num += DIV_ROUND_UP(gpps[i].size * 4, 32); + } + + community->ngpps = ngpps; + community->gpps = gpps; + + return 0; +} + +static int intel_pinctrl_pm_init(struct intel_pinctrl *pctrl) +{ +#ifdef CONFIG_PM_SLEEP + const struct intel_pinctrl_soc_data *soc = pctrl->soc; + struct intel_community_context *communities; + struct intel_pad_context *pads; + int i; + + pads = devm_kcalloc(pctrl->dev, soc->npins, sizeof(*pads), GFP_KERNEL); + if (!pads) + return -ENOMEM; + + communities = devm_kcalloc(pctrl->dev, pctrl->ncommunities, + sizeof(*communities), GFP_KERNEL); + if (!communities) + return -ENOMEM; + + + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + u32 *intmask, *hostown; + + intmask = devm_kcalloc(pctrl->dev, community->ngpps, + sizeof(*intmask), GFP_KERNEL); + if (!intmask) + return -ENOMEM; + + communities[i].intmask = intmask; + + hostown = devm_kcalloc(pctrl->dev, community->ngpps, + sizeof(*hostown), GFP_KERNEL); + if (!hostown) + return -ENOMEM; + + communities[i].hostown = hostown; + } + + pctrl->context.pads = pads; + pctrl->context.communities = communities; +#endif + + return 0; +} + +static int intel_pinctrl_probe(struct platform_device *pdev, + const struct intel_pinctrl_soc_data *soc_data) +{ + struct intel_pinctrl *pctrl; + int i, ret, irq; + + pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + pctrl->dev = &pdev->dev; + pctrl->soc = soc_data; + raw_spin_lock_init(&pctrl->lock); + + /* + * Make a copy of the communities which we can use to hold pointers + * to the registers. + */ + pctrl->ncommunities = pctrl->soc->ncommunities; + pctrl->communities = devm_kcalloc(&pdev->dev, pctrl->ncommunities, + sizeof(*pctrl->communities), GFP_KERNEL); + if (!pctrl->communities) + return -ENOMEM; + + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + void __iomem *regs; + u32 padbar; + + *community = pctrl->soc->communities[i]; + + regs = devm_platform_ioremap_resource(pdev, community->barno); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + /* + * Determine community features based on the revision if + * not specified already. + */ + if (!community->features) { + u32 rev; + + rev = (readl(regs + REVID) & REVID_MASK) >> REVID_SHIFT; + if (rev >= 0x94) { + community->features |= PINCTRL_FEATURE_DEBOUNCE; + community->features |= PINCTRL_FEATURE_1K_PD; + } + } + + /* Read offset of the pad configuration registers */ + padbar = readl(regs + PADBAR); + + community->regs = regs; + community->pad_regs = regs + padbar; + + ret = intel_pinctrl_add_padgroups(pctrl, community); + if (ret) + return ret; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret = intel_pinctrl_pm_init(pctrl); + if (ret) + return ret; + + pctrl->pctldesc = intel_pinctrl_desc; + pctrl->pctldesc.name = dev_name(&pdev->dev); + pctrl->pctldesc.pins = pctrl->soc->pins; + pctrl->pctldesc.npins = pctrl->soc->npins; + + pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc, + pctrl); + if (IS_ERR(pctrl->pctldev)) { + dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + return PTR_ERR(pctrl->pctldev); + } + + ret = intel_gpio_probe(pctrl, irq); + if (ret) + return ret; + + platform_set_drvdata(pdev, pctrl); + + return 0; +} + +int intel_pinctrl_probe_by_hid(struct platform_device *pdev) +{ + const struct intel_pinctrl_soc_data *data; + + data = device_get_match_data(&pdev->dev); + if (!data) + return -ENODATA; + + return intel_pinctrl_probe(pdev, data); +} +EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_hid); + +int intel_pinctrl_probe_by_uid(struct platform_device *pdev) +{ + const struct intel_pinctrl_soc_data *data; + + data = intel_pinctrl_get_soc_data(pdev); + if (IS_ERR(data)) + return PTR_ERR(data); + + return intel_pinctrl_probe(pdev, data); +} +EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid); + +const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev) +{ + const struct intel_pinctrl_soc_data * const *table; + const struct intel_pinctrl_soc_data *data = NULL; + + table = device_get_match_data(&pdev->dev); + if (table) { + struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); + unsigned int i; + + for (i = 0; table[i]; i++) { + if (!strcmp(adev->pnp.unique_id, table[i]->uid)) { + data = table[i]; + break; + } + } + } else { + const struct platform_device_id *id; + + id = platform_get_device_id(pdev); + if (!id) + return ERR_PTR(-ENODEV); + + table = (const struct intel_pinctrl_soc_data * const *)id->driver_data; + data = table[pdev->id]; + } + + return data ?: ERR_PTR(-ENODATA); +} +EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data); + +#ifdef CONFIG_PM_SLEEP +static bool __intel_gpio_is_direct_irq(u32 value) +{ + return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && + (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO); +} + +static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) +{ + const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); + u32 value; + + if (!pd || !intel_pad_usable(pctrl, pin)) + return false; + + /* + * Only restore the pin if it is actually in use by the kernel (or + * by userspace). It is possible that some pins are used by the + * BIOS during resume and those are not always locked down so leave + * them alone. + */ + if (pd->mux_owner || pd->gpio_owner || + gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin))) + return true; + + /* + * The firmware on some systems may configure GPIO pins to be + * an interrupt source in so called "direct IRQ" mode. In such + * cases the GPIO controller driver has no idea if those pins + * are being used or not. At the same time, there is a known bug + * in the firmwares that don't restore the pin settings correctly + * after suspend, i.e. by an unknown reason the Rx value becomes + * inverted. + * + * Hence, let's save and restore the pins that are configured + * as GPIOs in the input mode with GPIROUTIOXAPIC bit set. + * + * See https://bugzilla.kernel.org/show_bug.cgi?id=214749. + */ + value = readl(intel_get_padcfg(pctrl, pin, PADCFG0)); + if (__intel_gpio_is_direct_irq(value)) + return true; + + return false; +} + +int intel_pinctrl_suspend_noirq(struct device *dev) +{ + struct intel_pinctrl *pctrl = dev_get_drvdata(dev); + struct intel_community_context *communities; + struct intel_pad_context *pads; + int i; + + pads = pctrl->context.pads; + for (i = 0; i < pctrl->soc->npins; i++) { + const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; + void __iomem *padcfg; + u32 val; + + if (!intel_pinctrl_should_save(pctrl, desc->number)) + continue; + + val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0)); + pads[i].padcfg0 = val & ~PADCFG0_GPIORXSTATE; + val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG1)); + pads[i].padcfg1 = val; + + padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG2); + if (padcfg) + pads[i].padcfg2 = readl(padcfg); + } + + communities = pctrl->context.communities; + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + void __iomem *base; + unsigned int gpp; + + base = community->regs + community->ie_offset; + for (gpp = 0; gpp < community->ngpps; gpp++) + communities[i].intmask[gpp] = readl(base + gpp * 4); + + base = community->regs + community->hostown_offset; + for (gpp = 0; gpp < community->ngpps; gpp++) + communities[i].hostown[gpp] = readl(base + gpp * 4); + } + + return 0; +} +EXPORT_SYMBOL_GPL(intel_pinctrl_suspend_noirq); + +static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value) +{ + u32 curr, updated; + + curr = readl(reg); + + updated = (curr & ~mask) | (value & mask); + if (curr == updated) + return false; + + writel(updated, reg); + return true; +} + +static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c, + void __iomem *base, unsigned int gpp, u32 saved) +{ + const struct intel_community *community = &pctrl->communities[c]; + const struct intel_padgroup *padgrp = &community->gpps[gpp]; + struct device *dev = pctrl->dev; + const char *dummy; + u32 requested = 0; + unsigned int i; + + if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) + return; + + for_each_requested_gpio_in_range(&pctrl->chip, i, padgrp->gpio_base, padgrp->size, dummy) + requested |= BIT(i); + + if (!intel_gpio_update_reg(base + gpp * 4, requested, saved)) + return; + + dev_dbg(dev, "restored hostown %u/%u %#08x\n", c, gpp, readl(base + gpp * 4)); +} + +static void intel_restore_intmask(struct intel_pinctrl *pctrl, unsigned int c, + void __iomem *base, unsigned int gpp, u32 saved) +{ + struct device *dev = pctrl->dev; + + if (!intel_gpio_update_reg(base + gpp * 4, ~0U, saved)) + return; + + dev_dbg(dev, "restored mask %u/%u %#08x\n", c, gpp, readl(base + gpp * 4)); +} + +static void intel_restore_padcfg(struct intel_pinctrl *pctrl, unsigned int pin, + unsigned int reg, u32 saved) +{ + u32 mask = (reg == PADCFG0) ? PADCFG0_GPIORXSTATE : 0; + unsigned int n = reg / sizeof(u32); + struct device *dev = pctrl->dev; + void __iomem *padcfg; + + padcfg = intel_get_padcfg(pctrl, pin, reg); + if (!padcfg) + return; + + if (!intel_gpio_update_reg(padcfg, ~mask, saved)) + return; + + dev_dbg(dev, "restored pin %u padcfg%u %#08x\n", pin, n, readl(padcfg)); +} + +int intel_pinctrl_resume_noirq(struct device *dev) +{ + struct intel_pinctrl *pctrl = dev_get_drvdata(dev); + const struct intel_community_context *communities; + const struct intel_pad_context *pads; + int i; + + /* Mask all interrupts */ + intel_gpio_irq_init(pctrl); + + pads = pctrl->context.pads; + for (i = 0; i < pctrl->soc->npins; i++) { + const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i]; + + if (!(intel_pinctrl_should_save(pctrl, desc->number) || + /* + * If the firmware mangled the register contents too much, + * check the saved value for the Direct IRQ mode. + */ + __intel_gpio_is_direct_irq(pads[i].padcfg0))) + continue; + + intel_restore_padcfg(pctrl, desc->number, PADCFG0, pads[i].padcfg0); + intel_restore_padcfg(pctrl, desc->number, PADCFG1, pads[i].padcfg1); + intel_restore_padcfg(pctrl, desc->number, PADCFG2, pads[i].padcfg2); + } + + communities = pctrl->context.communities; + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + void __iomem *base; + unsigned int gpp; + + base = community->regs + community->ie_offset; + for (gpp = 0; gpp < community->ngpps; gpp++) + intel_restore_intmask(pctrl, i, base, gpp, communities[i].intmask[gpp]); + + base = community->regs + community->hostown_offset; + for (gpp = 0; gpp < community->ngpps; gpp++) + intel_restore_hostown(pctrl, i, base, gpp, communities[i].hostown[gpp]); + } + + return 0; +} +EXPORT_SYMBOL_GPL(intel_pinctrl_resume_noirq); +#endif + +MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>"); +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel pinctrl/GPIO core driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h new file mode 100644 index 000000000..ad34b7a3f --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Core pinctrl/GPIO driver for Intel GPIO controllers + * + * Copyright (C) 2015, Intel Corporation + * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#ifndef PINCTRL_INTEL_H +#define PINCTRL_INTEL_H + +#include <linux/bits.h> +#include <linux/compiler_types.h> +#include <linux/gpio/driver.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/pm.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/spinlock_types.h> + +struct platform_device; +struct device; + +/** + * struct intel_pingroup - Description about group of pins + * @name: Name of the groups + * @pins: All pins in this group + * @npins: Number of pins in this groups + * @mode: Native mode in which the group is muxed out @pins. Used if @modes + * is %NULL. + * @modes: If not %NULL this will hold mode for each pin in @pins + */ +struct intel_pingroup { + const char *name; + const unsigned int *pins; + size_t npins; + unsigned short mode; + const unsigned int *modes; +}; + +/** + * struct intel_function - Description about a function + * @name: Name of the function + * @groups: An array of groups for this function + * @ngroups: Number of groups in @groups + */ +struct intel_function { + const char *name; + const char * const *groups; + size_t ngroups; +}; + +/** + * struct intel_padgroup - Hardware pad group information + * @reg_num: GPI_IS register number + * @base: Starting pin of this group + * @size: Size of this group (maximum is 32). + * @gpio_base: Starting GPIO base of this group + * @padown_num: PAD_OWN register number (assigned by the core driver) + * + * If pad groups of a community are not the same size, use this structure + * to specify them. + */ +struct intel_padgroup { + unsigned int reg_num; + unsigned int base; + unsigned int size; + int gpio_base; + unsigned int padown_num; +}; + +/** + * enum - Special treatment for GPIO base in pad group + * + * @INTEL_GPIO_BASE_ZERO: force GPIO base to be 0 + * @INTEL_GPIO_BASE_NOMAP: no GPIO mapping should be created + * @INTEL_GPIO_BASE_MATCH: matches with starting pin number + */ +enum { + INTEL_GPIO_BASE_ZERO = -2, + INTEL_GPIO_BASE_NOMAP = -1, + INTEL_GPIO_BASE_MATCH = 0, +}; + +/** + * struct intel_community - Intel pin community description + * @barno: MMIO BAR number where registers for this community reside + * @padown_offset: Register offset of PAD_OWN register from @regs. If %0 + * then there is no support for owner. + * @padcfglock_offset: Register offset of PADCFGLOCK from @regs. If %0 then + * locking is not supported. + * @hostown_offset: Register offset of HOSTSW_OWN from @regs. If %0 then it + * is assumed that the host owns the pin (rather than + * ACPI). + * @is_offset: Register offset of GPI_IS from @regs. + * @ie_offset: Register offset of GPI_IE from @regs. + * @features: Additional features supported by the hardware + * @pin_base: Starting pin of pins in this community + * @npins: Number of pins in this community + * @gpp_size: Maximum number of pads in each group, such as PADCFGLOCK, + * HOSTSW_OWN, GPI_IS, GPI_IE. Used when @gpps is %NULL. + * @gpp_num_padown_regs: Number of pad registers each pad group consumes at + * minimum. Use %0 if the number of registers can be + * determined by the size of the group. + * @gpps: Pad groups if the controller has variable size pad groups + * @ngpps: Number of pad groups in this community + * @pad_map: Optional non-linear mapping of the pads + * @nirqs: Optional total number of IRQs this community can generate + * @acpi_space_id: Optional address space ID for ACPI OpRegion handler + * @regs: Community specific common registers (reserved for core driver) + * @pad_regs: Community specific pad registers (reserved for core driver) + * + * In some of Intel GPIO host controllers this driver supports each pad group + * is of equal size (except the last one). In that case the driver can just + * fill in @gpp_size field and let the core driver to handle the rest. If + * the controller has pad groups of variable size the client driver can + * pass custom @gpps and @ngpps instead. + */ +struct intel_community { + unsigned int barno; + unsigned int padown_offset; + unsigned int padcfglock_offset; + unsigned int hostown_offset; + unsigned int is_offset; + unsigned int ie_offset; + unsigned int features; + unsigned int pin_base; + size_t npins; + unsigned int gpp_size; + unsigned int gpp_num_padown_regs; + const struct intel_padgroup *gpps; + size_t ngpps; + const unsigned int *pad_map; + unsigned short nirqs; + unsigned short acpi_space_id; + + /* Reserved for the core driver */ + void __iomem *regs; + void __iomem *pad_regs; +}; + +/* Additional features supported by the hardware */ +#define PINCTRL_FEATURE_DEBOUNCE BIT(0) +#define PINCTRL_FEATURE_1K_PD BIT(1) + +/** + * PIN_GROUP - Declare a pin group + * @n: Name of the group + * @p: An array of pins this group consists + * @m: Mode which the pins are put when this group is active. Can be either + * a single integer or an array of integers in which case mode is per + * pin. + */ +#define PIN_GROUP(n, p, m) \ + { \ + .name = (n), \ + .pins = (p), \ + .npins = ARRAY_SIZE((p)), \ + .mode = __builtin_choose_expr( \ + __builtin_constant_p((m)), (m), 0), \ + .modes = __builtin_choose_expr( \ + __builtin_constant_p((m)), NULL, (m)), \ + } + +#define FUNCTION(n, g) \ + { \ + .name = (n), \ + .groups = (g), \ + .ngroups = ARRAY_SIZE((g)), \ + } + +/** + * struct intel_pinctrl_soc_data - Intel pin controller per-SoC configuration + * @uid: ACPI _UID for the probe driver use if needed + * @pins: Array if pins this pinctrl controls + * @npins: Number of pins in the array + * @groups: Array of pin groups + * @ngroups: Number of groups in the array + * @functions: Array of functions + * @nfunctions: Number of functions in the array + * @communities: Array of communities this pinctrl handles + * @ncommunities: Number of communities in the array + * + * The @communities is used as a template by the core driver. It will make + * copy of all communities and fill in rest of the information. + */ +struct intel_pinctrl_soc_data { + const char *uid; + const struct pinctrl_pin_desc *pins; + size_t npins; + const struct intel_pingroup *groups; + size_t ngroups; + const struct intel_function *functions; + size_t nfunctions; + const struct intel_community *communities; + size_t ncommunities; +}; + +const struct intel_pinctrl_soc_data *intel_pinctrl_get_soc_data(struct platform_device *pdev); + +struct intel_pad_context; +struct intel_community_context; + +/** + * struct intel_pinctrl_context - context to be saved during suspend-resume + * @pads: Opaque context per pad (driver dependent) + * @communities: Opaque context per community (driver dependent) + */ +struct intel_pinctrl_context { + struct intel_pad_context *pads; + struct intel_community_context *communities; +}; + +/** + * struct intel_pinctrl - Intel pinctrl private structure + * @dev: Pointer to the device structure + * @lock: Lock to serialize register access + * @pctldesc: Pin controller description + * @pctldev: Pointer to the pin controller device + * @chip: GPIO chip in this pin controller + * @irqchip: IRQ chip in this pin controller + * @soc: SoC/PCH specific pin configuration data + * @communities: All communities in this pin controller + * @ncommunities: Number of communities in this pin controller + * @context: Configuration saved over system sleep + * @irq: pinctrl/GPIO chip irq number + */ +struct intel_pinctrl { + struct device *dev; + raw_spinlock_t lock; + struct pinctrl_desc pctldesc; + struct pinctrl_dev *pctldev; + struct gpio_chip chip; + struct irq_chip irqchip; + const struct intel_pinctrl_soc_data *soc; + struct intel_community *communities; + size_t ncommunities; + struct intel_pinctrl_context context; + int irq; +}; + +int intel_pinctrl_probe_by_hid(struct platform_device *pdev); +int intel_pinctrl_probe_by_uid(struct platform_device *pdev); + +#ifdef CONFIG_PM_SLEEP +int intel_pinctrl_suspend_noirq(struct device *dev); +int intel_pinctrl_resume_noirq(struct device *dev); +#endif + +#define INTEL_PINCTRL_PM_OPS(_name) \ +const struct dev_pm_ops _name = { \ + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(intel_pinctrl_suspend_noirq, \ + intel_pinctrl_resume_noirq) \ +} + +#endif /* PINCTRL_INTEL_H */ diff --git a/drivers/pinctrl/intel/pinctrl-jasperlake.c b/drivers/pinctrl/intel/pinctrl-jasperlake.c new file mode 100644 index 000000000..ec435b7ab --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-jasperlake.c @@ -0,0 +1,354 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Jasper Lake PCH pinctrl/GPIO driver + * + * Copyright (C) 2020, Intel Corporation + * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define JSL_PAD_OWN 0x020 +#define JSL_PADCFGLOCK 0x080 +#define JSL_HOSTSW_OWN 0x0c0 +#define JSL_GPI_IS 0x100 +#define JSL_GPI_IE 0x120 + +#define JSL_GPP(r, s, e, g) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ + } + +#define JSL_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = JSL_PAD_OWN, \ + .padcfglock_offset = JSL_PADCFGLOCK, \ + .hostown_offset = JSL_HOSTSW_OWN, \ + .is_offset = JSL_GPI_IS, \ + .ie_offset = JSL_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Jasper Lake */ +static const struct pinctrl_pin_desc jsl_pins[] = { + /* GPP_F */ + PINCTRL_PIN(0, "CNV_BRI_DT_UART0_RTSB"), + PINCTRL_PIN(1, "CNV_BRI_RSP_UART0_RXD"), + PINCTRL_PIN(2, "EMMC_HIP_MON"), + PINCTRL_PIN(3, "CNV_RGI_RSP_UART0_CTSB"), + PINCTRL_PIN(4, "CNV_RF_RESET_B"), + PINCTRL_PIN(5, "MODEM_CLKREQ"), + PINCTRL_PIN(6, "CNV_PA_BLANKING"), + PINCTRL_PIN(7, "EMMC_CMD"), + PINCTRL_PIN(8, "EMMC_DATA0"), + PINCTRL_PIN(9, "EMMC_DATA1"), + PINCTRL_PIN(10, "EMMC_DATA2"), + PINCTRL_PIN(11, "EMMC_DATA3"), + PINCTRL_PIN(12, "EMMC_DATA4"), + PINCTRL_PIN(13, "EMMC_DATA5"), + PINCTRL_PIN(14, "EMMC_DATA6"), + PINCTRL_PIN(15, "EMMC_DATA7"), + PINCTRL_PIN(16, "EMMC_RCLK"), + PINCTRL_PIN(17, "EMMC_CLK"), + PINCTRL_PIN(18, "EMMC_RESETB"), + PINCTRL_PIN(19, "A4WP_PRESENT"), + /* SPI */ + PINCTRL_PIN(20, "SPI0_IO_2"), + PINCTRL_PIN(21, "SPI0_IO_3"), + PINCTRL_PIN(22, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(23, "SPI0_MISO_IO_1"), + PINCTRL_PIN(24, "SPI0_TPM_CSB"), + PINCTRL_PIN(25, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(26, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(27, "SPI0_CLK"), + PINCTRL_PIN(28, "SPI0_CLK_LOOPBK"), + /* GPP_B */ + PINCTRL_PIN(29, "CORE_VID_0"), + PINCTRL_PIN(30, "CORE_VID_1"), + PINCTRL_PIN(31, "VRALERTB"), + PINCTRL_PIN(32, "CPU_GP_2"), + PINCTRL_PIN(33, "CPU_GP_3"), + PINCTRL_PIN(34, "SRCCLKREQB_0"), + PINCTRL_PIN(35, "SRCCLKREQB_1"), + PINCTRL_PIN(36, "SRCCLKREQB_2"), + PINCTRL_PIN(37, "SRCCLKREQB_3"), + PINCTRL_PIN(38, "SRCCLKREQB_4"), + PINCTRL_PIN(39, "SRCCLKREQB_5"), + PINCTRL_PIN(40, "PMCALERTB"), + PINCTRL_PIN(41, "SLP_S0B"), + PINCTRL_PIN(42, "PLTRSTB"), + PINCTRL_PIN(43, "SPKR"), + PINCTRL_PIN(44, "GSPI0_CS0B"), + PINCTRL_PIN(45, "GSPI0_CLK"), + PINCTRL_PIN(46, "GSPI0_MISO"), + PINCTRL_PIN(47, "GSPI0_MOSI"), + PINCTRL_PIN(48, "GSPI1_CS0B"), + PINCTRL_PIN(49, "GSPI1_CLK"), + PINCTRL_PIN(50, "GSPI1_MISO"), + PINCTRL_PIN(51, "GSPI1_MOSI"), + PINCTRL_PIN(52, "DDSP_HPD_A"), + PINCTRL_PIN(53, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(54, "GSPI1_CLK_LOOPBK"), + /* GPP_A */ + PINCTRL_PIN(55, "ESPI_IO_0"), + PINCTRL_PIN(56, "ESPI_IO_1"), + PINCTRL_PIN(57, "ESPI_IO_2"), + PINCTRL_PIN(58, "ESPI_IO_3"), + PINCTRL_PIN(59, "ESPI_CSB"), + PINCTRL_PIN(60, "ESPI_CLK"), + PINCTRL_PIN(61, "ESPI_RESETB"), + PINCTRL_PIN(62, "SMBCLK"), + PINCTRL_PIN(63, "SMBDATA"), + PINCTRL_PIN(64, "SMBALERTB"), + PINCTRL_PIN(65, "CPU_GP_0"), + PINCTRL_PIN(66, "CPU_GP_1"), + PINCTRL_PIN(67, "USB2_OCB_1"), + PINCTRL_PIN(68, "USB2_OCB_2"), + PINCTRL_PIN(69, "USB2_OCB_3"), + PINCTRL_PIN(70, "DDSP_HPD_A_TIME_SYNC_0"), + PINCTRL_PIN(71, "DDSP_HPD_B"), + PINCTRL_PIN(72, "DDSP_HPD_C"), + PINCTRL_PIN(73, "USB2_OCB_0"), + PINCTRL_PIN(74, "PCHHOTB"), + PINCTRL_PIN(75, "ESPI_CLK_LOOPBK"), + /* GPP_S */ + PINCTRL_PIN(76, "SNDW1_CLK"), + PINCTRL_PIN(77, "SNDW1_DATA"), + PINCTRL_PIN(78, "SNDW2_CLK"), + PINCTRL_PIN(79, "SNDW2_DATA"), + PINCTRL_PIN(80, "SNDW1_CLK"), + PINCTRL_PIN(81, "SNDW1_DATA"), + PINCTRL_PIN(82, "SNDW4_CLK_DMIC_CLK_0"), + PINCTRL_PIN(83, "SNDW4_DATA_DMIC_DATA_0"), + /* GPP_R */ + PINCTRL_PIN(84, "HDA_BCLK"), + PINCTRL_PIN(85, "HDA_SYNC"), + PINCTRL_PIN(86, "HDA_SDO"), + PINCTRL_PIN(87, "HDA_SDI_0"), + PINCTRL_PIN(88, "HDA_RSTB"), + PINCTRL_PIN(89, "HDA_SDI_1"), + PINCTRL_PIN(90, "I2S1_SFRM"), + PINCTRL_PIN(91, "I2S1_TXD"), + /* GPP_H */ + PINCTRL_PIN(92, "GPPC_H_0"), + PINCTRL_PIN(93, "SD_PWR_EN_B"), + PINCTRL_PIN(94, "MODEM_CLKREQ"), + PINCTRL_PIN(95, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(96, "I2C2_SDA"), + PINCTRL_PIN(97, "I2C2_SCL"), + PINCTRL_PIN(98, "I2C3_SDA"), + PINCTRL_PIN(99, "I2C3_SCL"), + PINCTRL_PIN(100, "I2C4_SDA"), + PINCTRL_PIN(101, "I2C4_SCL"), + PINCTRL_PIN(102, "CPU_VCCIO_PWR_GATEB"), + PINCTRL_PIN(103, "I2S2_SCLK"), + PINCTRL_PIN(104, "I2S2_SFRM"), + PINCTRL_PIN(105, "I2S2_TXD"), + PINCTRL_PIN(106, "I2S2_RXD"), + PINCTRL_PIN(107, "I2S1_SCLK"), + PINCTRL_PIN(108, "GPPC_H_16"), + PINCTRL_PIN(109, "GPPC_H_17"), + PINCTRL_PIN(110, "GPPC_H_18"), + PINCTRL_PIN(111, "GPPC_H_19"), + PINCTRL_PIN(112, "GPPC_H_20"), + PINCTRL_PIN(113, "GPPC_H_21"), + PINCTRL_PIN(114, "GPPC_H_22"), + PINCTRL_PIN(115, "GPPC_H_23"), + /* GPP_D */ + PINCTRL_PIN(116, "SPI1_CSB"), + PINCTRL_PIN(117, "SPI1_CLK"), + PINCTRL_PIN(118, "SPI1_MISO_IO_1"), + PINCTRL_PIN(119, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(120, "ISH_I2C0_SDA"), + PINCTRL_PIN(121, "ISH_I2C0_SCL"), + PINCTRL_PIN(122, "ISH_I2C1_SDA"), + PINCTRL_PIN(123, "ISH_I2C1_SCL"), + PINCTRL_PIN(124, "ISH_SPI_CSB"), + PINCTRL_PIN(125, "ISH_SPI_CLK"), + PINCTRL_PIN(126, "ISH_SPI_MISO"), + PINCTRL_PIN(127, "ISH_SPI_MOSI"), + PINCTRL_PIN(128, "ISH_UART0_RXD"), + PINCTRL_PIN(129, "ISH_UART0_TXD"), + PINCTRL_PIN(130, "ISH_UART0_RTSB"), + PINCTRL_PIN(131, "ISH_UART0_CTSB"), + PINCTRL_PIN(132, "SPI1_IO_2"), + PINCTRL_PIN(133, "SPI1_IO_3"), + PINCTRL_PIN(134, "I2S_MCLK"), + PINCTRL_PIN(135, "CNV_MFUART2_RXD"), + PINCTRL_PIN(136, "CNV_MFUART2_TXD"), + PINCTRL_PIN(137, "CNV_PA_BLANKING"), + PINCTRL_PIN(138, "I2C5_SDA"), + PINCTRL_PIN(139, "I2C5_SCL"), + PINCTRL_PIN(140, "GSPI2_CLK_LOOPBK"), + PINCTRL_PIN(141, "SPI1_CLK_LOOPBK"), + /* vGPIO */ + PINCTRL_PIN(142, "CNV_BTEN"), + PINCTRL_PIN(143, "CNV_WCEN"), + PINCTRL_PIN(144, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(145, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(146, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(147, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(148, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(149, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(150, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(151, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(152, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(153, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(154, "vUART0_TXD"), + PINCTRL_PIN(155, "vUART0_RXD"), + PINCTRL_PIN(156, "vUART0_CTS_B"), + PINCTRL_PIN(157, "vUART0_RTS_B"), + PINCTRL_PIN(158, "vISH_UART0_TXD"), + PINCTRL_PIN(159, "vISH_UART0_RXD"), + PINCTRL_PIN(160, "vISH_UART0_CTS_B"), + PINCTRL_PIN(161, "vISH_UART0_RTS_B"), + PINCTRL_PIN(162, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(163, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(164, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(165, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(166, "vI2S2_SCLK"), + PINCTRL_PIN(167, "vI2S2_SFRM"), + PINCTRL_PIN(168, "vI2S2_TXD"), + PINCTRL_PIN(169, "vI2S2_RXD"), + PINCTRL_PIN(170, "vSD3_CD_B"), + /* GPP_C */ + PINCTRL_PIN(171, "GPPC_C_0"), + PINCTRL_PIN(172, "GPPC_C_1"), + PINCTRL_PIN(173, "GPPC_C_2"), + PINCTRL_PIN(174, "GPPC_C_3"), + PINCTRL_PIN(175, "GPPC_C_4"), + PINCTRL_PIN(176, "GPPC_C_5"), + PINCTRL_PIN(177, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(178, "SUSACKB"), + PINCTRL_PIN(179, "UART0_RXD"), + PINCTRL_PIN(180, "UART0_TXD"), + PINCTRL_PIN(181, "UART0_RTSB"), + PINCTRL_PIN(182, "UART0_CTSB"), + PINCTRL_PIN(183, "UART1_RXD"), + PINCTRL_PIN(184, "UART1_TXD"), + PINCTRL_PIN(185, "UART1_RTSB"), + PINCTRL_PIN(186, "UART1_CTSB"), + PINCTRL_PIN(187, "I2C0_SDA"), + PINCTRL_PIN(188, "I2C0_SCL"), + PINCTRL_PIN(189, "I2C1_SDA"), + PINCTRL_PIN(190, "I2C1_SCL"), + PINCTRL_PIN(191, "UART2_RXD"), + PINCTRL_PIN(192, "UART2_TXD"), + PINCTRL_PIN(193, "UART2_RTSB"), + PINCTRL_PIN(194, "UART2_CTSB"), + /* HVCMOS */ + PINCTRL_PIN(195, "L_BKLTEN"), + PINCTRL_PIN(196, "L_BKLTCTL"), + PINCTRL_PIN(197, "L_VDDEN"), + PINCTRL_PIN(198, "SYS_PWROK"), + PINCTRL_PIN(199, "SYS_RESETB"), + PINCTRL_PIN(200, "MLK_RSTB"), + /* GPP_E */ + PINCTRL_PIN(201, "ISH_GP_0"), + PINCTRL_PIN(202, "ISH_GP_1"), + PINCTRL_PIN(203, "IMGCLKOUT_1"), + PINCTRL_PIN(204, "ISH_GP_2"), + PINCTRL_PIN(205, "IMGCLKOUT_2"), + PINCTRL_PIN(206, "SATA_LEDB"), + PINCTRL_PIN(207, "IMGCLKOUT_3"), + PINCTRL_PIN(208, "ISH_GP_3"), + PINCTRL_PIN(209, "ISH_GP_4"), + PINCTRL_PIN(210, "ISH_GP_5"), + PINCTRL_PIN(211, "ISH_GP_6"), + PINCTRL_PIN(212, "ISH_GP_7"), + PINCTRL_PIN(213, "IMGCLKOUT_4"), + PINCTRL_PIN(214, "DDPA_CTRLCLK"), + PINCTRL_PIN(215, "DDPA_CTRLDATA"), + PINCTRL_PIN(216, "DDPB_CTRLCLK"), + PINCTRL_PIN(217, "DDPB_CTRLDATA"), + PINCTRL_PIN(218, "DDPC_CTRLCLK"), + PINCTRL_PIN(219, "DDPC_CTRLDATA"), + PINCTRL_PIN(220, "IMGCLKOUT_5"), + PINCTRL_PIN(221, "CNV_BRI_DT"), + PINCTRL_PIN(222, "CNV_BRI_RSP"), + PINCTRL_PIN(223, "CNV_RGI_DT"), + PINCTRL_PIN(224, "CNV_RGI_RSP"), + /* GPP_G */ + PINCTRL_PIN(225, "SD3_CMD"), + PINCTRL_PIN(226, "SD3_D0"), + PINCTRL_PIN(227, "SD3_D1"), + PINCTRL_PIN(228, "SD3_D2"), + PINCTRL_PIN(229, "SD3_D3"), + PINCTRL_PIN(230, "SD3_CDB"), + PINCTRL_PIN(231, "SD3_CLK"), + PINCTRL_PIN(232, "SD3_WP"), +}; + +static const struct intel_padgroup jsl_community0_gpps[] = { + JSL_GPP(0, 0, 19, 320), /* GPP_F */ + JSL_GPP(1, 20, 28, INTEL_GPIO_BASE_NOMAP), /* SPI */ + JSL_GPP(2, 29, 54, 32), /* GPP_B */ + JSL_GPP(3, 55, 75, 64), /* GPP_A */ + JSL_GPP(4, 76, 83, 96), /* GPP_S */ + JSL_GPP(5, 84, 91, 128), /* GPP_R */ +}; + +static const struct intel_padgroup jsl_community1_gpps[] = { + JSL_GPP(0, 92, 115, 160), /* GPP_H */ + JSL_GPP(1, 116, 141, 192), /* GPP_D */ + JSL_GPP(2, 142, 170, 224), /* vGPIO */ + JSL_GPP(3, 171, 194, 256), /* GPP_C */ +}; + +static const struct intel_padgroup jsl_community4_gpps[] = { + JSL_GPP(0, 195, 200, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */ + JSL_GPP(1, 201, 224, 288), /* GPP_E */ +}; + +static const struct intel_padgroup jsl_community5_gpps[] = { + JSL_GPP(0, 225, 232, INTEL_GPIO_BASE_ZERO), /* GPP_G */ +}; + +static const struct intel_community jsl_communities[] = { + JSL_COMMUNITY(0, 0, 91, jsl_community0_gpps), + JSL_COMMUNITY(1, 92, 194, jsl_community1_gpps), + JSL_COMMUNITY(2, 195, 224, jsl_community4_gpps), + JSL_COMMUNITY(3, 225, 232, jsl_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data jsl_soc_data = { + .pins = jsl_pins, + .npins = ARRAY_SIZE(jsl_pins), + .communities = jsl_communities, + .ncommunities = ARRAY_SIZE(jsl_communities), +}; + +static const struct acpi_device_id jsl_pinctrl_acpi_match[] = { + { "INT34C8", (kernel_ulong_t)&jsl_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, jsl_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(jsl_pinctrl_pm_ops); + +static struct platform_driver jsl_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "jasperlake-pinctrl", + .acpi_match_table = jsl_pinctrl_acpi_match, + .pm = &jsl_pinctrl_pm_ops, + }, +}; +module_platform_driver(jsl_pinctrl_driver); + +MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Jasper Lake PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c new file mode 100644 index 000000000..ad4b446d5 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Lewisburg pinctrl/GPIO driver + * + * Copyright (C) 2017, Intel Corporation + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define LBG_PAD_OWN 0x020 +#define LBG_PADCFGLOCK 0x060 +#define LBG_HOSTSW_OWN 0x080 +#define LBG_GPI_IS 0x100 +#define LBG_GPI_IE 0x110 + +#define LBG_COMMUNITY(b, s, e) \ + { \ + .barno = (b), \ + .padown_offset = LBG_PAD_OWN, \ + .padcfglock_offset = LBG_PADCFGLOCK, \ + .hostown_offset = LBG_HOSTSW_OWN, \ + .is_offset = LBG_GPI_IS, \ + .ie_offset = LBG_GPI_IE, \ + .gpp_size = 24, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + } + +/* Lewisburg */ +static const struct pinctrl_pin_desc lbg_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "RCINB"), + PINCTRL_PIN(1, "LAD_0"), + PINCTRL_PIN(2, "LAD_1"), + PINCTRL_PIN(3, "LAD_2"), + PINCTRL_PIN(4, "LAD_3"), + PINCTRL_PIN(5, "LFRAMEB"), + PINCTRL_PIN(6, "SERIRQ"), + PINCTRL_PIN(7, "PIRQAB"), + PINCTRL_PIN(8, "CLKRUNB"), + PINCTRL_PIN(9, "CLKOUT_LPC_0"), + PINCTRL_PIN(10, "CLKOUT_LPC_1"), + PINCTRL_PIN(11, "PMEB"), + PINCTRL_PIN(12, "BM_BUSYB"), + PINCTRL_PIN(13, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(14, "ESPI_RESETB"), + PINCTRL_PIN(15, "SUSACKB"), + PINCTRL_PIN(16, "CLKOUT_LPC_2"), + PINCTRL_PIN(17, "GPP_A_17"), + PINCTRL_PIN(18, "GPP_A_18"), + PINCTRL_PIN(19, "GPP_A_19"), + PINCTRL_PIN(20, "GPP_A_20"), + PINCTRL_PIN(21, "GPP_A_21"), + PINCTRL_PIN(22, "GPP_A_22"), + PINCTRL_PIN(23, "GPP_A_23"), + /* GPP_B */ + PINCTRL_PIN(24, "CORE_VID_0"), + PINCTRL_PIN(25, "CORE_VID_1"), + PINCTRL_PIN(26, "VRALERTB"), + PINCTRL_PIN(27, "CPU_GP_2"), + PINCTRL_PIN(28, "CPU_GP_3"), + PINCTRL_PIN(29, "SRCCLKREQB_0"), + PINCTRL_PIN(30, "SRCCLKREQB_1"), + PINCTRL_PIN(31, "SRCCLKREQB_2"), + PINCTRL_PIN(32, "SRCCLKREQB_3"), + PINCTRL_PIN(33, "SRCCLKREQB_4"), + PINCTRL_PIN(34, "SRCCLKREQB_5"), + PINCTRL_PIN(35, "GPP_B_11"), + PINCTRL_PIN(36, "SLP_S0B"), + PINCTRL_PIN(37, "PLTRSTB"), + PINCTRL_PIN(38, "SPKR"), + PINCTRL_PIN(39, "GPP_B_15"), + PINCTRL_PIN(40, "GPP_B_16"), + PINCTRL_PIN(41, "GPP_B_17"), + PINCTRL_PIN(42, "GPP_B_18"), + PINCTRL_PIN(43, "GPP_B_19"), + PINCTRL_PIN(44, "GPP_B_20"), + PINCTRL_PIN(45, "GPP_B_21"), + PINCTRL_PIN(46, "GPP_B_22"), + PINCTRL_PIN(47, "SML1ALERTB"), + /* GPP_F */ + PINCTRL_PIN(48, "SATAXPCIE_3"), + PINCTRL_PIN(49, "SATAXPCIE_4"), + PINCTRL_PIN(50, "SATAXPCIE_5"), + PINCTRL_PIN(51, "SATAXPCIE_6"), + PINCTRL_PIN(52, "SATAXPCIE_7"), + PINCTRL_PIN(53, "SATA_DEVSLP_3"), + PINCTRL_PIN(54, "SATA_DEVSLP_4"), + PINCTRL_PIN(55, "SATA_DEVSLP_5"), + PINCTRL_PIN(56, "SATA_DEVSLP_6"), + PINCTRL_PIN(57, "SATA_DEVSLP_7"), + PINCTRL_PIN(58, "SATA_SCLOCK"), + PINCTRL_PIN(59, "SATA_SLOAD"), + PINCTRL_PIN(60, "SATA_SDATAOUT1"), + PINCTRL_PIN(61, "SATA_SDATAOUT0"), + PINCTRL_PIN(62, "SSATA_LEDB"), + PINCTRL_PIN(63, "USB2_OCB_4"), + PINCTRL_PIN(64, "USB2_OCB_5"), + PINCTRL_PIN(65, "USB2_OCB_6"), + PINCTRL_PIN(66, "USB2_OCB_7"), + PINCTRL_PIN(67, "GBE_SMBUS_CLK"), + PINCTRL_PIN(68, "GBE_SMBDATA"), + PINCTRL_PIN(69, "GBE_SMBALRTN"), + PINCTRL_PIN(70, "SSATA_SCLOCK"), + PINCTRL_PIN(71, "SSATA_SLOAD"), + /* GPP_C */ + PINCTRL_PIN(72, "SMBCLK"), + PINCTRL_PIN(73, "SMBDATA"), + PINCTRL_PIN(74, "SMBALERTB"), + PINCTRL_PIN(75, "SML0CLK"), + PINCTRL_PIN(76, "SML0DATA"), + PINCTRL_PIN(77, "SML0ALERTB"), + PINCTRL_PIN(78, "SML1CLK"), + PINCTRL_PIN(79, "SML1DATA"), + PINCTRL_PIN(80, "GPP_C_8"), + PINCTRL_PIN(81, "GPP_C_9"), + PINCTRL_PIN(82, "GPP_C_10"), + PINCTRL_PIN(83, "GPP_C_11"), + PINCTRL_PIN(84, "GPP_C_12"), + PINCTRL_PIN(85, "GPP_C_13"), + PINCTRL_PIN(86, "GPP_C_14"), + PINCTRL_PIN(87, "GPP_C_15"), + PINCTRL_PIN(88, "GPP_C_16"), + PINCTRL_PIN(89, "GPP_C_17"), + PINCTRL_PIN(90, "GPP_C_18"), + PINCTRL_PIN(91, "GPP_C_19"), + PINCTRL_PIN(92, "GPP_C_20"), + PINCTRL_PIN(93, "GPP_C_21"), + PINCTRL_PIN(94, "GPP_C_22"), + PINCTRL_PIN(95, "GPP_C_23"), + /* GPP_D */ + PINCTRL_PIN(96, "GPP_D_0"), + PINCTRL_PIN(97, "GPP_D_1"), + PINCTRL_PIN(98, "GPP_D_2"), + PINCTRL_PIN(99, "GPP_D_3"), + PINCTRL_PIN(100, "GPP_D_4"), + PINCTRL_PIN(101, "SSP0_SFRM"), + PINCTRL_PIN(102, "SSP0_TXD"), + PINCTRL_PIN(103, "SSP0_RXD"), + PINCTRL_PIN(104, "SSP0_SCLK"), + PINCTRL_PIN(105, "SSATA_DEVSLP_3"), + PINCTRL_PIN(106, "SSATA_DEVSLP_4"), + PINCTRL_PIN(107, "SSATA_DEVSLP_5"), + PINCTRL_PIN(108, "SSATA_SDATAOUT1"), + PINCTRL_PIN(109, "SML0BCLK_SML0BCLKIE"), + PINCTRL_PIN(110, "SML0BDATA_SML0BDATAIE"), + PINCTRL_PIN(111, "SSATA_SDATAOUT0"), + PINCTRL_PIN(112, "SML0BALERTB_SML0BALERTBIE"), + PINCTRL_PIN(113, "DMIC_CLK_1"), + PINCTRL_PIN(114, "DMIC_DATA_1"), + PINCTRL_PIN(115, "DMIC_CLK_0"), + PINCTRL_PIN(116, "DMIC_DATA_0"), + PINCTRL_PIN(117, "IE_UART_RXD"), + PINCTRL_PIN(118, "IE_UART_TXD"), + PINCTRL_PIN(119, "GPP_D_23"), + /* GPP_E */ + PINCTRL_PIN(120, "SATAXPCIE_0"), + PINCTRL_PIN(121, "SATAXPCIE_1"), + PINCTRL_PIN(122, "SATAXPCIE_2"), + PINCTRL_PIN(123, "CPU_GP_0"), + PINCTRL_PIN(124, "SATA_DEVSLP_0"), + PINCTRL_PIN(125, "SATA_DEVSLP_1"), + PINCTRL_PIN(126, "SATA_DEVSLP_2"), + PINCTRL_PIN(127, "CPU_GP_1"), + PINCTRL_PIN(128, "SATA_LEDB"), + PINCTRL_PIN(129, "USB2_OCB_0"), + PINCTRL_PIN(130, "USB2_OCB_1"), + PINCTRL_PIN(131, "USB2_OCB_2"), + PINCTRL_PIN(132, "USB2_OCB_3"), + /* GPP_I */ + PINCTRL_PIN(133, "GBE_TDO"), + PINCTRL_PIN(134, "GBE_TCK"), + PINCTRL_PIN(135, "GBE_TMS"), + PINCTRL_PIN(136, "GBE_TDI"), + PINCTRL_PIN(137, "DO_RESET_INB"), + PINCTRL_PIN(138, "DO_RESET_OUTB"), + PINCTRL_PIN(139, "RESET_DONE"), + PINCTRL_PIN(140, "GBE_TRST_N"), + PINCTRL_PIN(141, "GBE_PCI_DIS"), + PINCTRL_PIN(142, "GBE_LAN_DIS"), + PINCTRL_PIN(143, "GPP_I_10"), + /* GPP_J */ + PINCTRL_PIN(144, "GBE_LED_0_0"), + PINCTRL_PIN(145, "GBE_LED_0_1"), + PINCTRL_PIN(146, "GBE_LED_1_0"), + PINCTRL_PIN(147, "GBE_LED_1_1"), + PINCTRL_PIN(148, "GBE_LED_2_0"), + PINCTRL_PIN(149, "GBE_LED_2_1"), + PINCTRL_PIN(150, "GBE_LED_3_0"), + PINCTRL_PIN(151, "GBE_LED_3_1"), + PINCTRL_PIN(152, "GBE_SCL_0"), + PINCTRL_PIN(153, "GBE_SDA_0"), + PINCTRL_PIN(154, "GBE_SCL_1"), + PINCTRL_PIN(155, "GBE_SDA_1"), + PINCTRL_PIN(156, "GBE_SCL_2"), + PINCTRL_PIN(157, "GBE_SDA_2"), + PINCTRL_PIN(158, "GBE_SCL_3"), + PINCTRL_PIN(159, "GBE_SDA_3"), + PINCTRL_PIN(160, "GBE_SDP_0_0"), + PINCTRL_PIN(161, "GBE_SDP_0_1"), + PINCTRL_PIN(162, "GBE_SDP_1_0"), + PINCTRL_PIN(163, "GBE_SDP_1_1"), + PINCTRL_PIN(164, "GBE_SDP_2_0"), + PINCTRL_PIN(165, "GBE_SDP_2_1"), + PINCTRL_PIN(166, "GBE_SDP_3_0"), + PINCTRL_PIN(167, "GBE_SDP_3_1"), + /* GPP_K */ + PINCTRL_PIN(168, "GBE_RMIICLK"), + PINCTRL_PIN(169, "GBE_RMII_RXD_0"), + PINCTRL_PIN(170, "GBE_RMII_RXD_1"), + PINCTRL_PIN(171, "GBE_RMII_CRS_DV"), + PINCTRL_PIN(172, "GBE_RMII_TX_EN"), + PINCTRL_PIN(173, "GBE_RMII_TXD_0"), + PINCTRL_PIN(174, "GBE_RMII_TXD_1"), + PINCTRL_PIN(175, "GBE_RMII_RX_ER"), + PINCTRL_PIN(176, "GBE_RMII_ARBIN"), + PINCTRL_PIN(177, "GBE_RMII_ARB_OUT"), + PINCTRL_PIN(178, "PE_RST_N"), + /* GPP_G */ + PINCTRL_PIN(179, "FAN_TACH_0"), + PINCTRL_PIN(180, "FAN_TACH_1"), + PINCTRL_PIN(181, "FAN_TACH_2"), + PINCTRL_PIN(182, "FAN_TACH_3"), + PINCTRL_PIN(183, "FAN_TACH_4"), + PINCTRL_PIN(184, "FAN_TACH_5"), + PINCTRL_PIN(185, "FAN_TACH_6"), + PINCTRL_PIN(186, "FAN_TACH_7"), + PINCTRL_PIN(187, "FAN_PWM_0"), + PINCTRL_PIN(188, "FAN_PWM_1"), + PINCTRL_PIN(189, "FAN_PWM_2"), + PINCTRL_PIN(190, "FAN_PWM_3"), + PINCTRL_PIN(191, "GSXDOUT"), + PINCTRL_PIN(192, "GSXSLOAD"), + PINCTRL_PIN(193, "GSXDIN"), + PINCTRL_PIN(194, "GSXSRESETB"), + PINCTRL_PIN(195, "GSXCLK"), + PINCTRL_PIN(196, "ADR_COMPLETE"), + PINCTRL_PIN(197, "NMIB"), + PINCTRL_PIN(198, "SMIB"), + PINCTRL_PIN(199, "SSATA_DEVSLP_0"), + PINCTRL_PIN(200, "SSATA_DEVSLP_1"), + PINCTRL_PIN(201, "SSATA_DEVSLP_2"), + PINCTRL_PIN(202, "SSATAXPCIE0_SSATAGP0"), + /* GPP_H */ + PINCTRL_PIN(203, "SRCCLKREQB_6"), + PINCTRL_PIN(204, "SRCCLKREQB_7"), + PINCTRL_PIN(205, "SRCCLKREQB_8"), + PINCTRL_PIN(206, "SRCCLKREQB_9"), + PINCTRL_PIN(207, "SRCCLKREQB_10"), + PINCTRL_PIN(208, "SRCCLKREQB_11"), + PINCTRL_PIN(209, "SRCCLKREQB_12"), + PINCTRL_PIN(210, "SRCCLKREQB_13"), + PINCTRL_PIN(211, "SRCCLKREQB_14"), + PINCTRL_PIN(212, "SRCCLKREQB_15"), + PINCTRL_PIN(213, "SML2CLK"), + PINCTRL_PIN(214, "SML2DATA"), + PINCTRL_PIN(215, "SML2ALERTB"), + PINCTRL_PIN(216, "SML3CLK"), + PINCTRL_PIN(217, "SML3DATA"), + PINCTRL_PIN(218, "SML3ALERTB"), + PINCTRL_PIN(219, "SML4CLK"), + PINCTRL_PIN(220, "SML4DATA"), + PINCTRL_PIN(221, "SML4ALERTB"), + PINCTRL_PIN(222, "SSATAXPCIE1_SSATAGP1"), + PINCTRL_PIN(223, "SSATAXPCIE2_SSATAGP2"), + PINCTRL_PIN(224, "SSATAXPCIE3_SSATAGP3"), + PINCTRL_PIN(225, "SSATAXPCIE4_SSATAGP4"), + PINCTRL_PIN(226, "SSATAXPCIE5_SSATAGP5"), + /* GPP_L */ + PINCTRL_PIN(227, "GPP_L_0"), + PINCTRL_PIN(228, "EC_CSME_INTR_OUT"), + PINCTRL_PIN(229, "VISA2CH0_D0"), + PINCTRL_PIN(230, "VISA2CH0_D1"), + PINCTRL_PIN(231, "VISA2CH0_D2"), + PINCTRL_PIN(232, "VISA2CH0_D3"), + PINCTRL_PIN(233, "VISA2CH0_D4"), + PINCTRL_PIN(234, "VISA2CH0_D5"), + PINCTRL_PIN(235, "VISA2CH0_D6"), + PINCTRL_PIN(236, "VISA2CH0_D7"), + PINCTRL_PIN(237, "VISA2CH0_CLK"), + PINCTRL_PIN(238, "VISA2CH1_D0"), + PINCTRL_PIN(239, "VISA2CH1_D1"), + PINCTRL_PIN(240, "VISA2CH1_D2"), + PINCTRL_PIN(241, "VISA2CH1_D3"), + PINCTRL_PIN(242, "VISA2CH1_D4"), + PINCTRL_PIN(243, "VISA2CH1_D5"), + PINCTRL_PIN(244, "VISA2CH1_D6"), + PINCTRL_PIN(245, "VISA2CH1_D7"), + PINCTRL_PIN(246, "VISA2CH1_CLK"), +}; + +static const struct intel_community lbg_communities[] = { + LBG_COMMUNITY(0, 0, 71), + LBG_COMMUNITY(1, 72, 132), + LBG_COMMUNITY(3, 133, 143), + LBG_COMMUNITY(4, 144, 178), + LBG_COMMUNITY(5, 179, 246), +}; + +static const struct intel_pinctrl_soc_data lbg_soc_data = { + .pins = lbg_pins, + .npins = ARRAY_SIZE(lbg_pins), + .communities = lbg_communities, + .ncommunities = ARRAY_SIZE(lbg_communities), +}; + +static INTEL_PINCTRL_PM_OPS(lbg_pinctrl_pm_ops); + +static const struct acpi_device_id lbg_pinctrl_acpi_match[] = { + { "INT3536", (kernel_ulong_t)&lbg_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, lbg_pinctrl_acpi_match); + +static struct platform_driver lbg_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "lewisburg-pinctrl", + .acpi_match_table = lbg_pinctrl_acpi_match, + .pm = &lbg_pinctrl_pm_ops, + }, +}; + +module_platform_driver(lbg_pinctrl_driver); + +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Lewisburg pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c new file mode 100644 index 000000000..96589d01f --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -0,0 +1,983 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Lynxpoint PCH pinctrl/GPIO driver + * + * Copyright (c) 2012, 2019, Intel Corporation + * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> + * Andy Shevchenko <andriy.shevchenko@linux.intel.com> + */ + +#include <linux/acpi.h> +#include <linux/bitops.h> +#include <linux/gpio/driver.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/slab.h> +#include <linux/types.h> + +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> + +#include "pinctrl-intel.h" + +#define COMMUNITY(p, n) \ + { \ + .pin_base = (p), \ + .npins = (n), \ + } + +static const struct pinctrl_pin_desc lptlp_pins[] = { + PINCTRL_PIN(0, "GP0_UART1_RXD"), + PINCTRL_PIN(1, "GP1_UART1_TXD"), + PINCTRL_PIN(2, "GP2_UART1_RTSB"), + PINCTRL_PIN(3, "GP3_UART1_CTSB"), + PINCTRL_PIN(4, "GP4_I2C0_SDA"), + PINCTRL_PIN(5, "GP5_I2C0_SCL"), + PINCTRL_PIN(6, "GP6_I2C1_SDA"), + PINCTRL_PIN(7, "GP7_I2C1_SCL"), + PINCTRL_PIN(8, "GP8"), + PINCTRL_PIN(9, "GP9"), + PINCTRL_PIN(10, "GP10"), + PINCTRL_PIN(11, "GP11_SMBALERTB"), + PINCTRL_PIN(12, "GP12_LANPHYPC"), + PINCTRL_PIN(13, "GP13"), + PINCTRL_PIN(14, "GP14"), + PINCTRL_PIN(15, "GP15"), + PINCTRL_PIN(16, "GP16_MGPIO9"), + PINCTRL_PIN(17, "GP17_MGPIO10"), + PINCTRL_PIN(18, "GP18_SRC0CLKRQB"), + PINCTRL_PIN(19, "GP19_SRC1CLKRQB"), + PINCTRL_PIN(20, "GP20_SRC2CLKRQB"), + PINCTRL_PIN(21, "GP21_SRC3CLKRQB"), + PINCTRL_PIN(22, "GP22_SRC4CLKRQB_TRST2"), + PINCTRL_PIN(23, "GP23_SRC5CLKRQB_TDI2"), + PINCTRL_PIN(24, "GP24_MGPIO0"), + PINCTRL_PIN(25, "GP25_USBWAKEOUTB"), + PINCTRL_PIN(26, "GP26_MGPIO5"), + PINCTRL_PIN(27, "GP27_MGPIO6"), + PINCTRL_PIN(28, "GP28_MGPIO7"), + PINCTRL_PIN(29, "GP29_SLP_WLANB_MGPIO3"), + PINCTRL_PIN(30, "GP30_SUSWARNB_SUSPWRDNACK_MGPIO1"), + PINCTRL_PIN(31, "GP31_ACPRESENT_MGPIO2"), + PINCTRL_PIN(32, "GP32_CLKRUNB"), + PINCTRL_PIN(33, "GP33_DEVSLP0"), + PINCTRL_PIN(34, "GP34_SATA0XPCIE6L3B_SATA0GP"), + PINCTRL_PIN(35, "GP35_SATA1XPCIE6L2B_SATA1GP"), + PINCTRL_PIN(36, "GP36_SATA2XPCIE6L1B_SATA2GP"), + PINCTRL_PIN(37, "GP37_SATA3XPCIE6L0B_SATA3GP"), + PINCTRL_PIN(38, "GP38_DEVSLP1"), + PINCTRL_PIN(39, "GP39_DEVSLP2"), + PINCTRL_PIN(40, "GP40_OC0B"), + PINCTRL_PIN(41, "GP41_OC1B"), + PINCTRL_PIN(42, "GP42_OC2B"), + PINCTRL_PIN(43, "GP43_OC3B"), + PINCTRL_PIN(44, "GP44"), + PINCTRL_PIN(45, "GP45_TMS2"), + PINCTRL_PIN(46, "GP46_TDO2"), + PINCTRL_PIN(47, "GP47"), + PINCTRL_PIN(48, "GP48"), + PINCTRL_PIN(49, "GP49"), + PINCTRL_PIN(50, "GP50"), + PINCTRL_PIN(51, "GP51_GSXDOUT"), + PINCTRL_PIN(52, "GP52_GSXSLOAD"), + PINCTRL_PIN(53, "GP53_GSXDIN"), + PINCTRL_PIN(54, "GP54_GSXSRESETB"), + PINCTRL_PIN(55, "GP55_GSXCLK"), + PINCTRL_PIN(56, "GP56"), + PINCTRL_PIN(57, "GP57"), + PINCTRL_PIN(58, "GP58"), + PINCTRL_PIN(59, "GP59"), + PINCTRL_PIN(60, "GP60_SML0ALERTB_MGPIO4"), + PINCTRL_PIN(61, "GP61_SUS_STATB"), + PINCTRL_PIN(62, "GP62_SUSCLK"), + PINCTRL_PIN(63, "GP63_SLP_S5B"), + PINCTRL_PIN(64, "GP64_SDIO_CLK"), + PINCTRL_PIN(65, "GP65_SDIO_CMD"), + PINCTRL_PIN(66, "GP66_SDIO_D0"), + PINCTRL_PIN(67, "GP67_SDIO_D1"), + PINCTRL_PIN(68, "GP68_SDIO_D2"), + PINCTRL_PIN(69, "GP69_SDIO_D3"), + PINCTRL_PIN(70, "GP70_SDIO_POWER_EN"), + PINCTRL_PIN(71, "GP71_MPHYPC"), + PINCTRL_PIN(72, "GP72_BATLOWB"), + PINCTRL_PIN(73, "GP73_SML1ALERTB_PCHHOTB_MGPIO8"), + PINCTRL_PIN(74, "GP74_SML1DATA_MGPIO12"), + PINCTRL_PIN(75, "GP75_SML1CLK_MGPIO11"), + PINCTRL_PIN(76, "GP76_BMBUSYB"), + PINCTRL_PIN(77, "GP77_PIRQAB"), + PINCTRL_PIN(78, "GP78_PIRQBB"), + PINCTRL_PIN(79, "GP79_PIRQCB"), + PINCTRL_PIN(80, "GP80_PIRQDB"), + PINCTRL_PIN(81, "GP81_SPKR"), + PINCTRL_PIN(82, "GP82_RCINB"), + PINCTRL_PIN(83, "GP83_GSPI0_CSB"), + PINCTRL_PIN(84, "GP84_GSPI0_CLK"), + PINCTRL_PIN(85, "GP85_GSPI0_MISO"), + PINCTRL_PIN(86, "GP86_GSPI0_MOSI"), + PINCTRL_PIN(87, "GP87_GSPI1_CSB"), + PINCTRL_PIN(88, "GP88_GSPI1_CLK"), + PINCTRL_PIN(89, "GP89_GSPI1_MISO"), + PINCTRL_PIN(90, "GP90_GSPI1_MOSI"), + PINCTRL_PIN(91, "GP91_UART0_RXD"), + PINCTRL_PIN(92, "GP92_UART0_TXD"), + PINCTRL_PIN(93, "GP93_UART0_RTSB"), + PINCTRL_PIN(94, "GP94_UART0_CTSB"), +}; + +static const struct intel_community lptlp_communities[] = { + COMMUNITY(0, 95), +}; + +static const struct intel_pinctrl_soc_data lptlp_soc_data = { + .pins = lptlp_pins, + .npins = ARRAY_SIZE(lptlp_pins), + .communities = lptlp_communities, + .ncommunities = ARRAY_SIZE(lptlp_communities), +}; + +/* LynxPoint chipset has support for 95 GPIO pins */ + +#define LP_NUM_GPIO 95 + +/* Bitmapped register offsets */ +#define LP_ACPI_OWNED 0x00 /* Bitmap, set by bios, 0: pin reserved for ACPI */ +#define LP_IRQ2IOXAPIC 0x10 /* Bitmap, set by bios, 1: pin routed to IOxAPIC */ +#define LP_GC 0x7C /* set APIC IRQ to IRQ14 or IRQ15 for all pins */ +#define LP_INT_STAT 0x80 +#define LP_INT_ENABLE 0x90 + +/* Each pin has two 32 bit config registers, starting at 0x100 */ +#define LP_CONFIG1 0x100 +#define LP_CONFIG2 0x104 + +/* LP_CONFIG1 reg bits */ +#define OUT_LVL_BIT BIT(31) +#define IN_LVL_BIT BIT(30) +#define TRIG_SEL_BIT BIT(4) /* 0: Edge, 1: Level */ +#define INT_INV_BIT BIT(3) /* Invert interrupt triggering */ +#define DIR_BIT BIT(2) /* 0: Output, 1: Input */ +#define USE_SEL_MASK GENMASK(1, 0) /* 0: Native, 1: GPIO, ... */ +#define USE_SEL_NATIVE (0 << 0) +#define USE_SEL_GPIO (1 << 0) + +/* LP_CONFIG2 reg bits */ +#define GPINDIS_BIT BIT(2) /* disable input sensing */ +#define GPIWP_MASK GENMASK(1, 0) /* weak pull options */ +#define GPIWP_NONE 0 /* none */ +#define GPIWP_DOWN 1 /* weak pull down */ +#define GPIWP_UP 2 /* weak pull up */ + +/* + * Lynxpoint gpios are controlled through both bitmapped registers and + * per gpio specific registers. The bitmapped registers are in chunks of + * 3 x 32bit registers to cover all 95 GPIOs + * + * per gpio specific registers consist of two 32bit registers per gpio + * (LP_CONFIG1 and LP_CONFIG2), with 95 GPIOs there's a total of + * 190 config registers. + * + * A simplified view of the register layout look like this: + * + * LP_ACPI_OWNED[31:0] gpio ownerships for gpios 0-31 (bitmapped registers) + * LP_ACPI_OWNED[63:32] gpio ownerships for gpios 32-63 + * LP_ACPI_OWNED[94:64] gpio ownerships for gpios 63-94 + * ... + * LP_INT_ENABLE[31:0] ... + * LP_INT_ENABLE[63:32] ... + * LP_INT_ENABLE[94:64] ... + * LP0_CONFIG1 (gpio 0) config1 reg for gpio 0 (per gpio registers) + * LP0_CONFIG2 (gpio 0) config2 reg for gpio 0 + * LP1_CONFIG1 (gpio 1) config1 reg for gpio 1 + * LP1_CONFIG2 (gpio 1) config2 reg for gpio 1 + * LP2_CONFIG1 (gpio 2) ... + * LP2_CONFIG2 (gpio 2) ... + * ... + * LP94_CONFIG1 (gpio 94) ... + * LP94_CONFIG2 (gpio 94) ... + * + * IOxAPIC redirection map applies only for gpio 8-10, 13-14, 45-55. + */ + +static struct intel_community *lp_get_community(struct intel_pinctrl *lg, + unsigned int pin) +{ + struct intel_community *comm; + int i; + + for (i = 0; i < lg->ncommunities; i++) { + comm = &lg->communities[i]; + if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) + return comm; + } + + return NULL; +} + +static void __iomem *lp_gpio_reg(struct gpio_chip *chip, unsigned int offset, + int reg) +{ + struct intel_pinctrl *lg = gpiochip_get_data(chip); + struct intel_community *comm; + int reg_offset; + + comm = lp_get_community(lg, offset); + if (!comm) + return NULL; + + offset -= comm->pin_base; + + if (reg == LP_CONFIG1 || reg == LP_CONFIG2) + /* per gpio specific config registers */ + reg_offset = offset * 8; + else + /* bitmapped registers */ + reg_offset = (offset / 32) * 4; + + return comm->regs + reg_offset + reg; +} + +static bool lp_gpio_acpi_use(struct intel_pinctrl *lg, unsigned int pin) +{ + void __iomem *acpi_use; + + acpi_use = lp_gpio_reg(&lg->chip, pin, LP_ACPI_OWNED); + if (!acpi_use) + return true; + + return !(ioread32(acpi_use) & BIT(pin % 32)); +} + +static bool lp_gpio_ioxapic_use(struct gpio_chip *chip, unsigned int offset) +{ + void __iomem *ioxapic_use = lp_gpio_reg(chip, offset, LP_IRQ2IOXAPIC); + u32 value; + + value = ioread32(ioxapic_use); + + if (offset >= 8 && offset <= 10) + return !!(value & BIT(offset - 8 + 0)); + if (offset >= 13 && offset <= 14) + return !!(value & BIT(offset - 13 + 3)); + if (offset >= 45 && offset <= 55) + return !!(value & BIT(offset - 45 + 5)); + + return false; +} + +static int lp_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->ngroups; +} + +static const char *lp_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->groups[selector].name; +} + +static int lp_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + *pins = lg->soc->groups[selector].pins; + *num_pins = lg->soc->groups[selector].npins; + + return 0; +} + +static void lp_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + u32 value, mode; + + value = ioread32(reg); + + mode = value & USE_SEL_MASK; + if (mode == USE_SEL_GPIO) + seq_puts(s, "GPIO "); + else + seq_printf(s, "mode %d ", mode); + + seq_printf(s, "0x%08x 0x%08x", value, ioread32(conf2)); + + if (lp_gpio_acpi_use(lg, pin)) + seq_puts(s, " [ACPI]"); +} + +static const struct pinctrl_ops lptlp_pinctrl_ops = { + .get_groups_count = lp_get_groups_count, + .get_group_name = lp_get_group_name, + .get_group_pins = lp_get_group_pins, + .pin_dbg_show = lp_pin_dbg_show, +}; + +static int lp_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->nfunctions; +} + +static const char *lp_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + return lg->soc->functions[selector].name; +} + +static int lp_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + + *groups = lg->soc->functions[selector].groups; + *num_groups = lg->soc->functions[selector].ngroups; + + return 0; +} + +static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pingroup *grp = &lg->soc->groups[group]; + unsigned long flags; + int i; + + raw_spin_lock_irqsave(&lg->lock, flags); + + /* Now enable the mux setting for each pin in the group */ + for (i = 0; i < grp->npins; i++) { + void __iomem *reg = lp_gpio_reg(&lg->chip, grp->pins[i], LP_CONFIG1); + u32 value; + + value = ioread32(reg); + + value &= ~USE_SEL_MASK; + if (grp->modes) + value |= grp->modes[i]; + else + value |= grp->mode; + + iowrite32(value, reg); + } + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static void lp_gpio_enable_input(void __iomem *reg) +{ + iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); +} + +static void lp_gpio_disable_input(void __iomem *reg) +{ + iowrite32(ioread32(reg) | GPINDIS_BIT, reg); +} + +static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + unsigned long flags; + u32 value; + + pm_runtime_get(lg->dev); + + raw_spin_lock_irqsave(&lg->lock, flags); + + /* + * Reconfigure pin to GPIO mode if needed and issue a warning, + * since we expect firmware to configure it properly. + */ + value = ioread32(reg); + if ((value & USE_SEL_MASK) != USE_SEL_GPIO) { + iowrite32((value & USE_SEL_MASK) | USE_SEL_GPIO, reg); + dev_warn(lg->dev, FW_BUG "pin %u forcibly reconfigured as GPIO\n", pin); + } + + /* Enable input sensing */ + lp_gpio_enable_input(conf2); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static void lp_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + + /* Disable input sensing */ + lp_gpio_disable_input(conf2); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + pm_runtime_put(lg->dev); +} + +static int lp_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *reg = lp_gpio_reg(&lg->chip, pin, LP_CONFIG1); + unsigned long flags; + u32 value; + + raw_spin_lock_irqsave(&lg->lock, flags); + + value = ioread32(reg); + value &= ~DIR_BIT; + if (input) { + value |= DIR_BIT; + } else { + /* + * Before making any direction modifications, do a check if GPIO + * is set for direct IRQ. On Lynxpoint, setting GPIO to output + * does not make sense, so let's at least warn the caller before + * they shoot themselves in the foot. + */ + WARN(lp_gpio_ioxapic_use(&lg->chip, pin), + "Potential Error: Setting GPIO to output with IOxAPIC redirection"); + } + iowrite32(value, reg); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static const struct pinmux_ops lptlp_pinmux_ops = { + .get_functions_count = lp_get_functions_count, + .get_function_name = lp_get_function_name, + .get_function_groups = lp_get_function_groups, + .set_mux = lp_pinmux_set_mux, + .gpio_request_enable = lp_gpio_request_enable, + .gpio_disable_free = lp_gpio_disable_free, + .gpio_set_direction = lp_gpio_set_direction, +}; + +static int lp_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned long flags; + u32 value, pull; + u16 arg = 0; + + raw_spin_lock_irqsave(&lg->lock, flags); + value = ioread32(conf2); + raw_spin_unlock_irqrestore(&lg->lock, flags); + + pull = value & GPIWP_MASK; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (pull) + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + if (pull != GPIWP_DOWN) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_PULL_UP: + if (pull != GPIWP_UP) + return -EINVAL; + + arg = 1; + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int lp_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct intel_pinctrl *lg = pinctrl_dev_get_drvdata(pctldev); + void __iomem *conf2 = lp_gpio_reg(&lg->chip, pin, LP_CONFIG2); + enum pin_config_param param; + unsigned long flags; + int i, ret = 0; + u32 value; + + raw_spin_lock_irqsave(&lg->lock, flags); + + value = ioread32(conf2); + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + value &= ~GPIWP_MASK; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + value &= ~GPIWP_MASK; + value |= GPIWP_DOWN; + break; + case PIN_CONFIG_BIAS_PULL_UP: + value &= ~GPIWP_MASK; + value |= GPIWP_UP; + break; + default: + ret = -ENOTSUPP; + } + + if (ret) + break; + } + + if (!ret) + iowrite32(value, conf2); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return ret; +} + +static const struct pinconf_ops lptlp_pinconf_ops = { + .is_generic = true, + .pin_config_get = lp_pin_config_get, + .pin_config_set = lp_pin_config_set, +}; + +static const struct pinctrl_desc lptlp_pinctrl_desc = { + .pctlops = &lptlp_pinctrl_ops, + .pmxops = &lptlp_pinmux_ops, + .confops = &lptlp_pinconf_ops, + .owner = THIS_MODULE, +}; + +static int lp_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + return !!(ioread32(reg) & IN_LVL_BIT); +} + +static void lp_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct intel_pinctrl *lg = gpiochip_get_data(chip); + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + + if (value) + iowrite32(ioread32(reg) | OUT_LVL_BIT, reg); + else + iowrite32(ioread32(reg) & ~OUT_LVL_BIT, reg); + + raw_spin_unlock_irqrestore(&lg->lock, flags); +} + +static int lp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) +{ + return pinctrl_gpio_direction_input(chip->base + offset); +} + +static int lp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, + int value) +{ + lp_gpio_set(chip, offset, value); + + return pinctrl_gpio_direction_output(chip->base + offset); +} + +static int lp_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + void __iomem *reg = lp_gpio_reg(chip, offset, LP_CONFIG1); + + if (ioread32(reg) & DIR_BIT) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + +static void lp_gpio_irq_handler(struct irq_desc *desc) +{ + struct irq_data *data = irq_desc_get_irq_data(desc); + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct intel_pinctrl *lg = gpiochip_get_data(gc); + struct irq_chip *chip = irq_data_get_irq_chip(data); + void __iomem *reg, *ena; + unsigned long pending; + u32 base, pin; + + /* check from GPIO controller which pin triggered the interrupt */ + for (base = 0; base < lg->chip.ngpio; base += 32) { + reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); + ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); + + /* Only interrupts that are enabled */ + pending = ioread32(reg) & ioread32(ena); + + for_each_set_bit(pin, &pending, 32) { + unsigned int irq; + + irq = irq_find_mapping(lg->chip.irq.domain, base + pin); + generic_handle_irq(irq); + } + } + chip->irq_eoi(data); +} + +static void lp_irq_ack(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *lg = gpiochip_get_data(gc); + u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_STAT); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + iowrite32(BIT(hwirq % 32), reg); + raw_spin_unlock_irqrestore(&lg->lock, flags); +} + +static void lp_irq_unmask(struct irq_data *d) +{ +} + +static void lp_irq_mask(struct irq_data *d) +{ +} + +static void lp_irq_enable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *lg = gpiochip_get_data(gc); + u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + iowrite32(ioread32(reg) | BIT(hwirq % 32), reg); + raw_spin_unlock_irqrestore(&lg->lock, flags); +} + +static void lp_irq_disable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *lg = gpiochip_get_data(gc); + u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE); + unsigned long flags; + + raw_spin_lock_irqsave(&lg->lock, flags); + iowrite32(ioread32(reg) & ~BIT(hwirq % 32), reg); + raw_spin_unlock_irqrestore(&lg->lock, flags); +} + +static int lp_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct intel_pinctrl *lg = gpiochip_get_data(gc); + u32 hwirq = irqd_to_hwirq(d); + void __iomem *reg = lp_gpio_reg(&lg->chip, hwirq, LP_CONFIG1); + unsigned long flags; + u32 value; + + if (hwirq >= lg->chip.ngpio) + return -EINVAL; + + /* Fail if BIOS reserved pin for ACPI use */ + if (lp_gpio_acpi_use(lg, hwirq)) { + dev_err(lg->dev, "pin %u can't be used as IRQ\n", hwirq); + return -EBUSY; + } + + raw_spin_lock_irqsave(&lg->lock, flags); + value = ioread32(reg); + + /* set both TRIG_SEL and INV bits to 0 for rising edge */ + if (type & IRQ_TYPE_EDGE_RISING) + value &= ~(TRIG_SEL_BIT | INT_INV_BIT); + + /* TRIG_SEL bit 0, INV bit 1 for falling edge */ + if (type & IRQ_TYPE_EDGE_FALLING) + value = (value | INT_INV_BIT) & ~TRIG_SEL_BIT; + + /* TRIG_SEL bit 1, INV bit 0 for level low */ + if (type & IRQ_TYPE_LEVEL_LOW) + value = (value | TRIG_SEL_BIT) & ~INT_INV_BIT; + + /* TRIG_SEL bit 1, INV bit 1 for level high */ + if (type & IRQ_TYPE_LEVEL_HIGH) + value |= TRIG_SEL_BIT | INT_INV_BIT; + + iowrite32(value, reg); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + + raw_spin_unlock_irqrestore(&lg->lock, flags); + + return 0; +} + +static struct irq_chip lp_irqchip = { + .name = "LP-GPIO", + .irq_ack = lp_irq_ack, + .irq_mask = lp_irq_mask, + .irq_unmask = lp_irq_unmask, + .irq_enable = lp_irq_enable, + .irq_disable = lp_irq_disable, + .irq_set_type = lp_irq_set_type, + .flags = IRQCHIP_SKIP_SET_WAKE, +}; + +static int lp_gpio_irq_init_hw(struct gpio_chip *chip) +{ + struct intel_pinctrl *lg = gpiochip_get_data(chip); + void __iomem *reg; + unsigned int base; + + for (base = 0; base < lg->chip.ngpio; base += 32) { + /* disable gpio pin interrupts */ + reg = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE); + iowrite32(0, reg); + /* Clear interrupt status register */ + reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); + iowrite32(0xffffffff, reg); + } + + return 0; +} + +static int lp_gpio_add_pin_ranges(struct gpio_chip *chip) +{ + struct intel_pinctrl *lg = gpiochip_get_data(chip); + struct device *dev = lg->dev; + int ret; + + ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins); + if (ret) + dev_err(dev, "failed to add GPIO pin range\n"); + + return ret; +} + +static int lp_gpio_probe(struct platform_device *pdev) +{ + const struct intel_pinctrl_soc_data *soc; + struct intel_pinctrl *lg; + struct gpio_chip *gc; + struct device *dev = &pdev->dev; + struct resource *io_rc; + void __iomem *regs; + unsigned int i; + int irq, ret; + + soc = (const struct intel_pinctrl_soc_data *)device_get_match_data(dev); + if (!soc) + return -ENODEV; + + lg = devm_kzalloc(dev, sizeof(*lg), GFP_KERNEL); + if (!lg) + return -ENOMEM; + + lg->dev = dev; + lg->soc = soc; + + lg->ncommunities = lg->soc->ncommunities; + lg->communities = devm_kcalloc(dev, lg->ncommunities, + sizeof(*lg->communities), GFP_KERNEL); + if (!lg->communities) + return -ENOMEM; + + lg->pctldesc = lptlp_pinctrl_desc; + lg->pctldesc.name = dev_name(dev); + lg->pctldesc.pins = lg->soc->pins; + lg->pctldesc.npins = lg->soc->npins; + + lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg); + if (IS_ERR(lg->pctldev)) { + dev_err(dev, "failed to register pinctrl driver\n"); + return PTR_ERR(lg->pctldev); + } + + platform_set_drvdata(pdev, lg); + + io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!io_rc) { + dev_err(dev, "missing IO resources\n"); + return -EINVAL; + } + + regs = devm_ioport_map(dev, io_rc->start, resource_size(io_rc)); + if (!regs) { + dev_err(dev, "failed mapping IO region %pR\n", &io_rc); + return -EBUSY; + } + + for (i = 0; i < lg->soc->ncommunities; i++) { + struct intel_community *comm = &lg->communities[i]; + + *comm = lg->soc->communities[i]; + + comm->regs = regs; + comm->pad_regs = regs + 0x100; + } + + raw_spin_lock_init(&lg->lock); + + gc = &lg->chip; + gc->label = dev_name(dev); + gc->owner = THIS_MODULE; + gc->request = gpiochip_generic_request; + gc->free = gpiochip_generic_free; + gc->direction_input = lp_gpio_direction_input; + gc->direction_output = lp_gpio_direction_output; + gc->get = lp_gpio_get; + gc->set = lp_gpio_set; + gc->get_direction = lp_gpio_get_direction; + gc->base = -1; + gc->ngpio = LP_NUM_GPIO; + gc->can_sleep = false; + gc->add_pin_ranges = lp_gpio_add_pin_ranges; + gc->parent = dev; + + /* set up interrupts */ + irq = platform_get_irq_optional(pdev, 0); + if (irq > 0) { + struct gpio_irq_chip *girq; + + girq = &gc->irq; + girq->chip = &lp_irqchip; + girq->init_hw = lp_gpio_irq_init_hw; + girq->parent_handler = lp_gpio_irq_handler; + girq->num_parents = 1; + girq->parents = devm_kcalloc(dev, girq->num_parents, + sizeof(*girq->parents), + GFP_KERNEL); + if (!girq->parents) + return -ENOMEM; + girq->parents[0] = irq; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + } + + ret = devm_gpiochip_add_data(dev, gc, lg); + if (ret) { + dev_err(dev, "failed adding lp-gpio chip\n"); + return ret; + } + + pm_runtime_enable(dev); + + return 0; +} + +static int lp_gpio_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + return 0; +} + +static int lp_gpio_runtime_suspend(struct device *dev) +{ + return 0; +} + +static int lp_gpio_runtime_resume(struct device *dev) +{ + return 0; +} + +static int lp_gpio_resume(struct device *dev) +{ + struct intel_pinctrl *lg = dev_get_drvdata(dev); + struct gpio_chip *chip = &lg->chip; + const char *dummy; + int i; + + /* on some hardware suspend clears input sensing, re-enable it here */ + for_each_requested_gpio(chip, i, dummy) + lp_gpio_enable_input(lp_gpio_reg(chip, i, LP_CONFIG2)); + + return 0; +} + +static const struct dev_pm_ops lp_gpio_pm_ops = { + .runtime_suspend = lp_gpio_runtime_suspend, + .runtime_resume = lp_gpio_runtime_resume, + .resume = lp_gpio_resume, +}; + +static const struct acpi_device_id lynxpoint_gpio_acpi_match[] = { + { "INT33C7", (kernel_ulong_t)&lptlp_soc_data }, + { "INT3437", (kernel_ulong_t)&lptlp_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match); + +static struct platform_driver lp_gpio_driver = { + .probe = lp_gpio_probe, + .remove = lp_gpio_remove, + .driver = { + .name = "lp_gpio", + .pm = &lp_gpio_pm_ops, + .acpi_match_table = lynxpoint_gpio_acpi_match, + }, +}; + +static int __init lp_gpio_init(void) +{ + return platform_driver_register(&lp_gpio_driver); +} + +static void __exit lp_gpio_exit(void) +{ + platform_driver_unregister(&lp_gpio_driver); +} + +subsys_initcall(lp_gpio_init); +module_exit(lp_gpio_exit); + +MODULE_AUTHOR("Mathias Nyman (Intel)"); +MODULE_AUTHOR("Andy Shevchenko (Intel)"); +MODULE_DESCRIPTION("Intel Lynxpoint pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:lp_gpio"); diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c new file mode 100644 index 000000000..3ae141e0b --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -0,0 +1,983 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Merrifield SoC pinctrl driver + * + * Copyright (C) 2016, Intel Corporation + * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + */ + +#include <linux/bits.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/platform_device.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> + +#include "pinctrl-intel.h" + +#define MRFLD_FAMILY_NR 64 +#define MRFLD_FAMILY_LEN 0x400 + +#define SLEW_OFFSET 0x000 +#define BUFCFG_OFFSET 0x100 +#define MISC_OFFSET 0x300 + +#define BUFCFG_PINMODE_SHIFT 0 +#define BUFCFG_PINMODE_MASK GENMASK(2, 0) +#define BUFCFG_PINMODE_GPIO 0 +#define BUFCFG_PUPD_VAL_SHIFT 4 +#define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4) +#define BUFCFG_PUPD_VAL_2K 0 +#define BUFCFG_PUPD_VAL_20K 1 +#define BUFCFG_PUPD_VAL_50K 2 +#define BUFCFG_PUPD_VAL_910 3 +#define BUFCFG_PU_EN BIT(8) +#define BUFCFG_PD_EN BIT(9) +#define BUFCFG_Px_EN_MASK GENMASK(9, 8) +#define BUFCFG_SLEWSEL BIT(10) +#define BUFCFG_OVINEN BIT(12) +#define BUFCFG_OVINEN_EN BIT(13) +#define BUFCFG_OVINEN_MASK GENMASK(13, 12) +#define BUFCFG_OVOUTEN BIT(14) +#define BUFCFG_OVOUTEN_EN BIT(15) +#define BUFCFG_OVOUTEN_MASK GENMASK(15, 14) +#define BUFCFG_INDATAOV_VAL BIT(16) +#define BUFCFG_INDATAOV_EN BIT(17) +#define BUFCFG_INDATAOV_MASK GENMASK(17, 16) +#define BUFCFG_OUTDATAOV_VAL BIT(18) +#define BUFCFG_OUTDATAOV_EN BIT(19) +#define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18) +#define BUFCFG_OD_EN BIT(21) + +/** + * struct mrfld_family - Intel pin family description + * @barno: MMIO BAR number where registers for this family reside + * @pin_base: Starting pin of pins in this family + * @npins: Number of pins in this family + * @protected: True if family is protected by access + * @regs: family specific common registers + */ +struct mrfld_family { + unsigned int barno; + unsigned int pin_base; + size_t npins; + bool protected; + void __iomem *regs; +}; + +#define MRFLD_FAMILY(b, s, e) \ + { \ + .barno = (b), \ + .pin_base = (s), \ + .npins = (e) - (s) + 1, \ + } + +#define MRFLD_FAMILY_PROTECTED(b, s, e) \ + { \ + .barno = (b), \ + .pin_base = (s), \ + .npins = (e) - (s) + 1, \ + .protected = true, \ + } + +static const struct pinctrl_pin_desc mrfld_pins[] = { + /* Family 0: OCP2SSC (0 pins) */ + /* Family 1: ULPI (13 pins) */ + PINCTRL_PIN(0, "ULPI_CLK"), + PINCTRL_PIN(1, "ULPI_D0"), + PINCTRL_PIN(2, "ULPI_D1"), + PINCTRL_PIN(3, "ULPI_D2"), + PINCTRL_PIN(4, "ULPI_D3"), + PINCTRL_PIN(5, "ULPI_D4"), + PINCTRL_PIN(6, "ULPI_D5"), + PINCTRL_PIN(7, "ULPI_D6"), + PINCTRL_PIN(8, "ULPI_D7"), + PINCTRL_PIN(9, "ULPI_DIR"), + PINCTRL_PIN(10, "ULPI_NXT"), + PINCTRL_PIN(11, "ULPI_REFCLK"), + PINCTRL_PIN(12, "ULPI_STP"), + /* Family 2: eMMC (24 pins) */ + PINCTRL_PIN(13, "EMMC_CLK"), + PINCTRL_PIN(14, "EMMC_CMD"), + PINCTRL_PIN(15, "EMMC_D0"), + PINCTRL_PIN(16, "EMMC_D1"), + PINCTRL_PIN(17, "EMMC_D2"), + PINCTRL_PIN(18, "EMMC_D3"), + PINCTRL_PIN(19, "EMMC_D4"), + PINCTRL_PIN(20, "EMMC_D5"), + PINCTRL_PIN(21, "EMMC_D6"), + PINCTRL_PIN(22, "EMMC_D7"), + PINCTRL_PIN(23, "EMMC_RST_N"), + PINCTRL_PIN(24, "GP154"), + PINCTRL_PIN(25, "GP155"), + PINCTRL_PIN(26, "GP156"), + PINCTRL_PIN(27, "GP157"), + PINCTRL_PIN(28, "GP158"), + PINCTRL_PIN(29, "GP159"), + PINCTRL_PIN(30, "GP160"), + PINCTRL_PIN(31, "GP161"), + PINCTRL_PIN(32, "GP162"), + PINCTRL_PIN(33, "GP163"), + PINCTRL_PIN(34, "GP97"), + PINCTRL_PIN(35, "GP14"), + PINCTRL_PIN(36, "GP15"), + /* Family 3: SDIO (20 pins) */ + PINCTRL_PIN(37, "GP77_SD_CD"), + PINCTRL_PIN(38, "GP78_SD_CLK"), + PINCTRL_PIN(39, "GP79_SD_CMD"), + PINCTRL_PIN(40, "GP80_SD_D0"), + PINCTRL_PIN(41, "GP81_SD_D1"), + PINCTRL_PIN(42, "GP82_SD_D2"), + PINCTRL_PIN(43, "GP83_SD_D3"), + PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"), + PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"), + PINCTRL_PIN(46, "GP86_SD_LS_D_DIR"), + PINCTRL_PIN(47, "GP88_SD_LS_SEL"), + PINCTRL_PIN(48, "GP87_SD_PD"), + PINCTRL_PIN(49, "GP89_SD_WP"), + PINCTRL_PIN(50, "GP90_SDIO_CLK"), + PINCTRL_PIN(51, "GP91_SDIO_CMD"), + PINCTRL_PIN(52, "GP92_SDIO_D0"), + PINCTRL_PIN(53, "GP93_SDIO_D1"), + PINCTRL_PIN(54, "GP94_SDIO_D2"), + PINCTRL_PIN(55, "GP95_SDIO_D3"), + PINCTRL_PIN(56, "GP96_SDIO_PD"), + /* Family 4: HSI (8 pins) */ + PINCTRL_PIN(57, "HSI_ACDATA"), + PINCTRL_PIN(58, "HSI_ACFLAG"), + PINCTRL_PIN(59, "HSI_ACREADY"), + PINCTRL_PIN(60, "HSI_ACWAKE"), + PINCTRL_PIN(61, "HSI_CADATA"), + PINCTRL_PIN(62, "HSI_CAFLAG"), + PINCTRL_PIN(63, "HSI_CAREADY"), + PINCTRL_PIN(64, "HSI_CAWAKE"), + /* Family 5: SSP Audio (14 pins) */ + PINCTRL_PIN(65, "GP70"), + PINCTRL_PIN(66, "GP71"), + PINCTRL_PIN(67, "GP32_I2S_0_CLK"), + PINCTRL_PIN(68, "GP33_I2S_0_FS"), + PINCTRL_PIN(69, "GP34_I2S_0_RXD"), + PINCTRL_PIN(70, "GP35_I2S_0_TXD"), + PINCTRL_PIN(71, "GP36_I2S_1_CLK"), + PINCTRL_PIN(72, "GP37_I2S_1_FS"), + PINCTRL_PIN(73, "GP38_I2S_1_RXD"), + PINCTRL_PIN(74, "GP39_I2S_1_TXD"), + PINCTRL_PIN(75, "GP40_I2S_2_CLK"), + PINCTRL_PIN(76, "GP41_I2S_2_FS"), + PINCTRL_PIN(77, "GP42_I2S_2_RXD"), + PINCTRL_PIN(78, "GP43_I2S_2_TXD"), + /* Family 6: GP SSP (22 pins) */ + PINCTRL_PIN(79, "GP120_SPI_0_CLK"), + PINCTRL_PIN(80, "GP121_SPI_0_SS"), + PINCTRL_PIN(81, "GP122_SPI_0_RXD"), + PINCTRL_PIN(82, "GP123_SPI_0_TXD"), + PINCTRL_PIN(83, "GP102_SPI_1_CLK"), + PINCTRL_PIN(84, "GP103_SPI_1_SS0"), + PINCTRL_PIN(85, "GP104_SPI_1_SS1"), + PINCTRL_PIN(86, "GP105_SPI_1_SS2"), + PINCTRL_PIN(87, "GP106_SPI_1_SS3"), + PINCTRL_PIN(88, "GP107_SPI_1_RXD"), + PINCTRL_PIN(89, "GP108_SPI_1_TXD"), + PINCTRL_PIN(90, "GP109_SPI_2_CLK"), + PINCTRL_PIN(91, "GP110_SPI_2_SS0"), + PINCTRL_PIN(92, "GP111_SPI_2_SS1"), + PINCTRL_PIN(93, "GP112_SPI_2_SS2"), + PINCTRL_PIN(94, "GP113_SPI_2_SS3"), + PINCTRL_PIN(95, "GP114_SPI_2_RXD"), + PINCTRL_PIN(96, "GP115_SPI_2_TXD"), + PINCTRL_PIN(97, "GP116_SPI_3_CLK"), + PINCTRL_PIN(98, "GP117_SPI_3_SS"), + PINCTRL_PIN(99, "GP118_SPI_3_RXD"), + PINCTRL_PIN(100, "GP119_SPI_3_TXD"), + /* Family 7: I2C (14 pins) */ + PINCTRL_PIN(101, "GP19_I2C_1_SCL"), + PINCTRL_PIN(102, "GP20_I2C_1_SDA"), + PINCTRL_PIN(103, "GP21_I2C_2_SCL"), + PINCTRL_PIN(104, "GP22_I2C_2_SDA"), + PINCTRL_PIN(105, "GP17_I2C_3_SCL_HDMI"), + PINCTRL_PIN(106, "GP18_I2C_3_SDA_HDMI"), + PINCTRL_PIN(107, "GP23_I2C_4_SCL"), + PINCTRL_PIN(108, "GP24_I2C_4_SDA"), + PINCTRL_PIN(109, "GP25_I2C_5_SCL"), + PINCTRL_PIN(110, "GP26_I2C_5_SDA"), + PINCTRL_PIN(111, "GP27_I2C_6_SCL"), + PINCTRL_PIN(112, "GP28_I2C_6_SDA"), + PINCTRL_PIN(113, "GP29_I2C_7_SCL"), + PINCTRL_PIN(114, "GP30_I2C_7_SDA"), + /* Family 8: UART (12 pins) */ + PINCTRL_PIN(115, "GP124_UART_0_CTS"), + PINCTRL_PIN(116, "GP125_UART_0_RTS"), + PINCTRL_PIN(117, "GP126_UART_0_RX"), + PINCTRL_PIN(118, "GP127_UART_0_TX"), + PINCTRL_PIN(119, "GP128_UART_1_CTS"), + PINCTRL_PIN(120, "GP129_UART_1_RTS"), + PINCTRL_PIN(121, "GP130_UART_1_RX"), + PINCTRL_PIN(122, "GP131_UART_1_TX"), + PINCTRL_PIN(123, "GP132_UART_2_CTS"), + PINCTRL_PIN(124, "GP133_UART_2_RTS"), + PINCTRL_PIN(125, "GP134_UART_2_RX"), + PINCTRL_PIN(126, "GP135_UART_2_TX"), + /* Family 9: GPIO South (19 pins) */ + PINCTRL_PIN(127, "GP177"), + PINCTRL_PIN(128, "GP178"), + PINCTRL_PIN(129, "GP179"), + PINCTRL_PIN(130, "GP180"), + PINCTRL_PIN(131, "GP181"), + PINCTRL_PIN(132, "GP182_PWM2"), + PINCTRL_PIN(133, "GP183_PWM3"), + PINCTRL_PIN(134, "GP184"), + PINCTRL_PIN(135, "GP185"), + PINCTRL_PIN(136, "GP186"), + PINCTRL_PIN(137, "GP187"), + PINCTRL_PIN(138, "GP188"), + PINCTRL_PIN(139, "GP189"), + PINCTRL_PIN(140, "GP64_FAST_INT0"), + PINCTRL_PIN(141, "GP65_FAST_INT1"), + PINCTRL_PIN(142, "GP66_FAST_INT2"), + PINCTRL_PIN(143, "GP67_FAST_INT3"), + PINCTRL_PIN(144, "GP12_PWM0"), + PINCTRL_PIN(145, "GP13_PWM1"), + /* Family 10: Camera Sideband (12 pins) */ + PINCTRL_PIN(146, "GP0"), + PINCTRL_PIN(147, "GP1"), + PINCTRL_PIN(148, "GP2"), + PINCTRL_PIN(149, "GP3"), + PINCTRL_PIN(150, "GP4"), + PINCTRL_PIN(151, "GP5"), + PINCTRL_PIN(152, "GP6"), + PINCTRL_PIN(153, "GP7"), + PINCTRL_PIN(154, "GP8"), + PINCTRL_PIN(155, "GP9"), + PINCTRL_PIN(156, "GP10"), + PINCTRL_PIN(157, "GP11"), + /* Family 11: Clock (22 pins) */ + PINCTRL_PIN(158, "GP137"), + PINCTRL_PIN(159, "GP138"), + PINCTRL_PIN(160, "GP139"), + PINCTRL_PIN(161, "GP140"), + PINCTRL_PIN(162, "GP141"), + PINCTRL_PIN(163, "GP142"), + PINCTRL_PIN(164, "GP16_HDMI_HPD"), + PINCTRL_PIN(165, "GP68_DSI_A_TE"), + PINCTRL_PIN(166, "GP69_DSI_C_TE"), + PINCTRL_PIN(167, "OSC_CLK_CTRL0"), + PINCTRL_PIN(168, "OSC_CLK_CTRL1"), + PINCTRL_PIN(169, "OSC_CLK0"), + PINCTRL_PIN(170, "OSC_CLK1"), + PINCTRL_PIN(171, "OSC_CLK2"), + PINCTRL_PIN(172, "OSC_CLK3"), + PINCTRL_PIN(173, "OSC_CLK4"), + PINCTRL_PIN(174, "RESETOUT"), + PINCTRL_PIN(175, "PMODE"), + PINCTRL_PIN(176, "PRDY"), + PINCTRL_PIN(177, "PREQ"), + PINCTRL_PIN(178, "GP190"), + PINCTRL_PIN(179, "GP191"), + /* Family 12: MSIC (15 pins) */ + PINCTRL_PIN(180, "I2C_0_SCL"), + PINCTRL_PIN(181, "I2C_0_SDA"), + PINCTRL_PIN(182, "IERR"), + PINCTRL_PIN(183, "JTAG_TCK"), + PINCTRL_PIN(184, "JTAG_TDI"), + PINCTRL_PIN(185, "JTAG_TDO"), + PINCTRL_PIN(186, "JTAG_TMS"), + PINCTRL_PIN(187, "JTAG_TRST"), + PINCTRL_PIN(188, "PROCHOT"), + PINCTRL_PIN(189, "RTC_CLK"), + PINCTRL_PIN(190, "SVID_ALERT"), + PINCTRL_PIN(191, "SVID_CLK"), + PINCTRL_PIN(192, "SVID_D"), + PINCTRL_PIN(193, "THERMTRIP"), + PINCTRL_PIN(194, "STANDBY"), + /* Family 13: Keyboard (20 pins) */ + PINCTRL_PIN(195, "GP44"), + PINCTRL_PIN(196, "GP45"), + PINCTRL_PIN(197, "GP46"), + PINCTRL_PIN(198, "GP47"), + PINCTRL_PIN(199, "GP48"), + PINCTRL_PIN(200, "GP49"), + PINCTRL_PIN(201, "GP50"), + PINCTRL_PIN(202, "GP51"), + PINCTRL_PIN(203, "GP52"), + PINCTRL_PIN(204, "GP53"), + PINCTRL_PIN(205, "GP54"), + PINCTRL_PIN(206, "GP55"), + PINCTRL_PIN(207, "GP56"), + PINCTRL_PIN(208, "GP57"), + PINCTRL_PIN(209, "GP58"), + PINCTRL_PIN(210, "GP59"), + PINCTRL_PIN(211, "GP60"), + PINCTRL_PIN(212, "GP61"), + PINCTRL_PIN(213, "GP62"), + PINCTRL_PIN(214, "GP63"), + /* Family 14: GPIO North (13 pins) */ + PINCTRL_PIN(215, "GP164"), + PINCTRL_PIN(216, "GP165"), + PINCTRL_PIN(217, "GP166"), + PINCTRL_PIN(218, "GP167"), + PINCTRL_PIN(219, "GP168_MJTAG_TCK"), + PINCTRL_PIN(220, "GP169_MJTAG_TDI"), + PINCTRL_PIN(221, "GP170_MJTAG_TDO"), + PINCTRL_PIN(222, "GP171_MJTAG_TMS"), + PINCTRL_PIN(223, "GP172_MJTAG_TRST"), + PINCTRL_PIN(224, "GP173"), + PINCTRL_PIN(225, "GP174"), + PINCTRL_PIN(226, "GP175"), + PINCTRL_PIN(227, "GP176"), + /* Family 15: PTI (5 pins) */ + PINCTRL_PIN(228, "GP72_PTI_CLK"), + PINCTRL_PIN(229, "GP73_PTI_D0"), + PINCTRL_PIN(230, "GP74_PTI_D1"), + PINCTRL_PIN(231, "GP75_PTI_D2"), + PINCTRL_PIN(232, "GP76_PTI_D3"), + /* Family 16: USB3 (0 pins) */ + /* Family 17: HSIC (0 pins) */ + /* Family 18: Broadcast (0 pins) */ +}; + +static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 }; +static const unsigned int mrfld_i2s2_pins[] = { 75, 76, 77, 78 }; +static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 }; +static const unsigned int mrfld_uart0_pins[] = { 115, 116, 117, 118 }; +static const unsigned int mrfld_uart1_pins[] = { 119, 120, 121, 122 }; +static const unsigned int mrfld_uart2_pins[] = { 123, 124, 125, 126 }; +static const unsigned int mrfld_pwm0_pins[] = { 144 }; +static const unsigned int mrfld_pwm1_pins[] = { 145 }; +static const unsigned int mrfld_pwm2_pins[] = { 132 }; +static const unsigned int mrfld_pwm3_pins[] = { 133 }; + +static const struct intel_pingroup mrfld_groups[] = { + PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1), + PIN_GROUP("i2s2_grp", mrfld_i2s2_pins, 1), + PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1), + PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1), + PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1), + PIN_GROUP("uart2_grp", mrfld_uart2_pins, 1), + PIN_GROUP("pwm0_grp", mrfld_pwm0_pins, 1), + PIN_GROUP("pwm1_grp", mrfld_pwm1_pins, 1), + PIN_GROUP("pwm2_grp", mrfld_pwm2_pins, 1), + PIN_GROUP("pwm3_grp", mrfld_pwm3_pins, 1), +}; + +static const char * const mrfld_sdio_groups[] = { "sdio_grp" }; +static const char * const mrfld_i2s2_groups[] = { "i2s2_grp" }; +static const char * const mrfld_spi5_groups[] = { "spi5_grp" }; +static const char * const mrfld_uart0_groups[] = { "uart0_grp" }; +static const char * const mrfld_uart1_groups[] = { "uart1_grp" }; +static const char * const mrfld_uart2_groups[] = { "uart2_grp" }; +static const char * const mrfld_pwm0_groups[] = { "pwm0_grp" }; +static const char * const mrfld_pwm1_groups[] = { "pwm1_grp" }; +static const char * const mrfld_pwm2_groups[] = { "pwm2_grp" }; +static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" }; + +static const struct intel_function mrfld_functions[] = { + FUNCTION("sdio", mrfld_sdio_groups), + FUNCTION("i2s2", mrfld_i2s2_groups), + FUNCTION("spi5", mrfld_spi5_groups), + FUNCTION("uart0", mrfld_uart0_groups), + FUNCTION("uart1", mrfld_uart1_groups), + FUNCTION("uart2", mrfld_uart2_groups), + FUNCTION("pwm0", mrfld_pwm0_groups), + FUNCTION("pwm1", mrfld_pwm1_groups), + FUNCTION("pwm2", mrfld_pwm2_groups), + FUNCTION("pwm3", mrfld_pwm3_groups), +}; + +static const struct mrfld_family mrfld_families[] = { + MRFLD_FAMILY(1, 0, 12), + MRFLD_FAMILY(2, 13, 36), + MRFLD_FAMILY(3, 37, 56), + MRFLD_FAMILY(4, 57, 64), + MRFLD_FAMILY(5, 65, 78), + MRFLD_FAMILY(6, 79, 100), + MRFLD_FAMILY_PROTECTED(7, 101, 114), + MRFLD_FAMILY(8, 115, 126), + MRFLD_FAMILY(9, 127, 145), + MRFLD_FAMILY(10, 146, 157), + MRFLD_FAMILY(11, 158, 179), + MRFLD_FAMILY_PROTECTED(12, 180, 194), + MRFLD_FAMILY(13, 195, 214), + MRFLD_FAMILY(14, 215, 227), + MRFLD_FAMILY(15, 228, 232), +}; + +/** + * struct mrfld_pinctrl - Intel Merrifield pinctrl private structure + * @dev: Pointer to the device structure + * @lock: Lock to serialize register access + * @pctldesc: Pin controller description + * @pctldev: Pointer to the pin controller device + * @families: Array of families this pinctrl handles + * @nfamilies: Number of families in the array + * @functions: Array of functions + * @nfunctions: Number of functions in the array + * @groups: Array of pin groups + * @ngroups: Number of groups in the array + * @pins: Array of pins this pinctrl controls + * @npins: Number of pins in the array + */ +struct mrfld_pinctrl { + struct device *dev; + raw_spinlock_t lock; + struct pinctrl_desc pctldesc; + struct pinctrl_dev *pctldev; + + /* Pin controller configuration */ + const struct mrfld_family *families; + size_t nfamilies; + const struct intel_function *functions; + size_t nfunctions; + const struct intel_pingroup *groups; + size_t ngroups; + const struct pinctrl_pin_desc *pins; + size_t npins; +}; + +#define pin_to_bufno(f, p) ((p) - (f)->pin_base) + +static const struct mrfld_family *mrfld_get_family(struct mrfld_pinctrl *mp, + unsigned int pin) +{ + const struct mrfld_family *family; + unsigned int i; + + for (i = 0; i < mp->nfamilies; i++) { + family = &mp->families[i]; + if (pin >= family->pin_base && + pin < family->pin_base + family->npins) + return family; + } + + dev_warn(mp->dev, "failed to find family for pin %u\n", pin); + return NULL; +} + +static bool mrfld_buf_available(struct mrfld_pinctrl *mp, unsigned int pin) +{ + const struct mrfld_family *family; + + family = mrfld_get_family(mp, pin); + if (!family) + return false; + + return !family->protected; +} + +static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin) +{ + const struct mrfld_family *family; + unsigned int bufno; + + family = mrfld_get_family(mp, pin); + if (!family) + return NULL; + + bufno = pin_to_bufno(family, pin); + return family->regs + BUFCFG_OFFSET + bufno * 4; +} + +static int mrfld_read_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin, u32 *value) +{ + void __iomem *bufcfg; + + if (!mrfld_buf_available(mp, pin)) + return -EBUSY; + + bufcfg = mrfld_get_bufcfg(mp, pin); + *value = readl(bufcfg); + + return 0; +} + +static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin, + u32 bits, u32 mask) +{ + void __iomem *bufcfg; + u32 value; + + bufcfg = mrfld_get_bufcfg(mp, pin); + value = readl(bufcfg); + + value &= ~mask; + value |= bits & mask; + + writel(value, bufcfg); +} + +static int mrfld_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->ngroups; +} + +static const char *mrfld_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->groups[group].name; +} + +static int mrfld_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, + const unsigned int **pins, unsigned int *npins) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + *pins = mp->groups[group].pins; + *npins = mp->groups[group].npins; + return 0; +} + +static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + u32 value, mode; + int ret; + + ret = mrfld_read_bufcfg(mp, pin, &value); + if (ret) { + seq_puts(s, "not available"); + return; + } + + mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT; + if (!mode) + seq_puts(s, "GPIO "); + else + seq_printf(s, "mode %d ", mode); + + seq_printf(s, "0x%08x", value); +} + +static const struct pinctrl_ops mrfld_pinctrl_ops = { + .get_groups_count = mrfld_get_groups_count, + .get_group_name = mrfld_get_group_name, + .get_group_pins = mrfld_get_group_pins, + .pin_dbg_show = mrfld_pin_dbg_show, +}; + +static int mrfld_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->nfunctions; +} + +static const char *mrfld_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->functions[function].name; +} + +static int mrfld_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char * const **groups, + unsigned int * const ngroups) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + *groups = mp->functions[function].groups; + *ngroups = mp->functions[function].ngroups; + return 0; +} + +static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, + unsigned int group) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pingroup *grp = &mp->groups[group]; + u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT; + u32 mask = BUFCFG_PINMODE_MASK; + unsigned long flags; + unsigned int i; + + /* + * All pins in the groups needs to be accessible and writable + * before we can enable the mux for this group. + */ + for (i = 0; i < grp->npins; i++) { + if (!mrfld_buf_available(mp, grp->pins[i])) + return -EBUSY; + } + + /* Now enable the mux setting for each pin in the group */ + raw_spin_lock_irqsave(&mp->lock, flags); + for (i = 0; i < grp->npins; i++) + mrfld_update_bufcfg(mp, grp->pins[i], bits, mask); + raw_spin_unlock_irqrestore(&mp->lock, flags); + + return 0; +} + +static int mrfld_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT; + u32 mask = BUFCFG_PINMODE_MASK; + unsigned long flags; + + if (!mrfld_buf_available(mp, pin)) + return -EBUSY; + + raw_spin_lock_irqsave(&mp->lock, flags); + mrfld_update_bufcfg(mp, pin, bits, mask); + raw_spin_unlock_irqrestore(&mp->lock, flags); + + return 0; +} + +static const struct pinmux_ops mrfld_pinmux_ops = { + .get_functions_count = mrfld_get_functions_count, + .get_function_name = mrfld_get_function_name, + .get_function_groups = mrfld_get_function_groups, + .set_mux = mrfld_pinmux_set_mux, + .gpio_request_enable = mrfld_gpio_request_enable, +}; + +static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 value, term; + u16 arg = 0; + int ret; + + ret = mrfld_read_bufcfg(mp, pin, &value); + if (ret) + return -ENOTSUPP; + + term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (value & BUFCFG_Px_EN_MASK) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN) + return -EINVAL; + + switch (term) { + case BUFCFG_PUPD_VAL_910: + arg = 910; + break; + case BUFCFG_PUPD_VAL_2K: + arg = 2000; + break; + case BUFCFG_PUPD_VAL_20K: + arg = 20000; + break; + case BUFCFG_PUPD_VAL_50K: + arg = 50000; + break; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN) + return -EINVAL; + + switch (term) { + case BUFCFG_PUPD_VAL_910: + arg = 910; + break; + case BUFCFG_PUPD_VAL_2K: + arg = 2000; + break; + case BUFCFG_PUPD_VAL_20K: + arg = 20000; + break; + case BUFCFG_PUPD_VAL_50K: + arg = 50000; + break; + } + + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(value & BUFCFG_OD_EN)) + return -EINVAL; + break; + + case PIN_CONFIG_SLEW_RATE: + if (!(value & BUFCFG_SLEWSEL)) + arg = 0; + else + arg = 1; + break; + + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin, + unsigned long config) +{ + unsigned int param = pinconf_to_config_param(config); + unsigned int arg = pinconf_to_config_argument(config); + u32 bits = 0, mask = 0; + unsigned long flags; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; + bits |= BUFCFG_PU_EN; + + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 20000; + + switch (arg) { + case 50000: + bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 20000: + bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 2000: + bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT; + break; + default: + return -EINVAL; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; + bits |= BUFCFG_PD_EN; + + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 20000; + + switch (arg) { + case 50000: + bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 20000: + bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 2000: + bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT; + break; + default: + return -EINVAL; + } + + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + mask |= BUFCFG_OD_EN; + if (arg) + bits |= BUFCFG_OD_EN; + break; + + case PIN_CONFIG_SLEW_RATE: + mask |= BUFCFG_SLEWSEL; + if (arg) + bits |= BUFCFG_SLEWSEL; + break; + } + + raw_spin_lock_irqsave(&mp->lock, flags); + mrfld_update_bufcfg(mp, pin, bits, mask); + raw_spin_unlock_irqrestore(&mp->lock, flags); + + return 0; +} + +static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfigs) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + unsigned int i; + int ret; + + if (!mrfld_buf_available(mp, pin)) + return -ENOTSUPP; + + for (i = 0; i < nconfigs; i++) { + switch (pinconf_to_config_param(configs[i])) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + case PIN_CONFIG_SLEW_RATE: + ret = mrfld_config_set_pin(mp, pin, configs[i]); + if (ret) + return ret; + break; + + default: + return -ENOTSUPP; + } + } + + return 0; +} + +static int mrfld_config_group_get(struct pinctrl_dev *pctldev, + unsigned int group, unsigned long *config) +{ + const unsigned int *pins; + unsigned int npins; + int ret; + + ret = mrfld_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + ret = mrfld_config_get(pctldev, pins[0], config); + if (ret) + return ret; + + return 0; +} + +static int mrfld_config_group_set(struct pinctrl_dev *pctldev, + unsigned int group, unsigned long *configs, + unsigned int num_configs) +{ + const unsigned int *pins; + unsigned int npins; + int i, ret; + + ret = mrfld_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + for (i = 0; i < npins; i++) { + ret = mrfld_config_set(pctldev, pins[i], configs, num_configs); + if (ret) + return ret; + } + + return 0; +} + +static const struct pinconf_ops mrfld_pinconf_ops = { + .is_generic = true, + .pin_config_get = mrfld_config_get, + .pin_config_set = mrfld_config_set, + .pin_config_group_get = mrfld_config_group_get, + .pin_config_group_set = mrfld_config_group_set, +}; + +static const struct pinctrl_desc mrfld_pinctrl_desc = { + .pctlops = &mrfld_pinctrl_ops, + .pmxops = &mrfld_pinmux_ops, + .confops = &mrfld_pinconf_ops, + .owner = THIS_MODULE, +}; + +static int mrfld_pinctrl_probe(struct platform_device *pdev) +{ + struct mrfld_family *families; + struct mrfld_pinctrl *mp; + void __iomem *regs; + size_t nfamilies; + unsigned int i; + + mp = devm_kzalloc(&pdev->dev, sizeof(*mp), GFP_KERNEL); + if (!mp) + return -ENOMEM; + + mp->dev = &pdev->dev; + raw_spin_lock_init(&mp->lock); + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + /* + * Make a copy of the families which we can use to hold pointers + * to the registers. + */ + nfamilies = ARRAY_SIZE(mrfld_families), + families = devm_kmemdup(&pdev->dev, mrfld_families, + sizeof(mrfld_families), + GFP_KERNEL); + if (!families) + return -ENOMEM; + + /* Splice memory resource by chunk per family */ + for (i = 0; i < nfamilies; i++) { + struct mrfld_family *family = &families[i]; + + family->regs = regs + family->barno * MRFLD_FAMILY_LEN; + } + + mp->families = families; + mp->nfamilies = nfamilies; + mp->functions = mrfld_functions; + mp->nfunctions = ARRAY_SIZE(mrfld_functions); + mp->groups = mrfld_groups; + mp->ngroups = ARRAY_SIZE(mrfld_groups); + mp->pctldesc = mrfld_pinctrl_desc; + mp->pctldesc.name = dev_name(&pdev->dev); + mp->pctldesc.pins = mrfld_pins; + mp->pctldesc.npins = ARRAY_SIZE(mrfld_pins); + + mp->pctldev = devm_pinctrl_register(&pdev->dev, &mp->pctldesc, mp); + if (IS_ERR(mp->pctldev)) { + dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + return PTR_ERR(mp->pctldev); + } + + platform_set_drvdata(pdev, mp); + return 0; +} + +static const struct acpi_device_id mrfld_acpi_table[] = { + { "INTC1002" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, mrfld_acpi_table); + +static struct platform_driver mrfld_pinctrl_driver = { + .probe = mrfld_pinctrl_probe, + .driver = { + .name = "pinctrl-merrifield", + .acpi_match_table = mrfld_acpi_table, + }, +}; + +static int __init mrfld_pinctrl_init(void) +{ + return platform_driver_register(&mrfld_pinctrl_driver); +} +subsys_initcall(mrfld_pinctrl_init); + +static void __exit mrfld_pinctrl_exit(void) +{ + platform_driver_unregister(&mrfld_pinctrl_driver); +} +module_exit(mrfld_pinctrl_exit); + +MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:pinctrl-merrifield"); diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c new file mode 100644 index 000000000..14eac924d --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -0,0 +1,619 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Sunrisepoint PCH pinctrl/GPIO driver + * + * Copyright (C) 2015, Intel Corporation + * Authors: Mathias Nyman <mathias.nyman@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define SPT_PAD_OWN 0x020 +#define SPT_H_PADCFGLOCK 0x090 +#define SPT_LP_PADCFGLOCK 0x0a0 +#define SPT_HOSTSW_OWN 0x0d0 +#define SPT_GPI_IS 0x100 +#define SPT_GPI_IE 0x120 + +#define SPT_COMMUNITY(b, s, e, pl, gs, gn, g, n) \ + { \ + .barno = (b), \ + .padown_offset = SPT_PAD_OWN, \ + .padcfglock_offset = (pl), \ + .hostown_offset = SPT_HOSTSW_OWN, \ + .is_offset = SPT_GPI_IS, \ + .ie_offset = SPT_GPI_IE, \ + .gpp_size = (gs), \ + .gpp_num_padown_regs = (gn), \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = (n), \ + } + +#define SPT_LP_COMMUNITY(b, s, e) \ + SPT_COMMUNITY(b, s, e, SPT_LP_PADCFGLOCK, 24, 4, NULL, 0) + +#define SPT_H_GPP(r, s, e, g) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ + } + +#define SPT_H_COMMUNITY(b, s, e, g) \ + SPT_COMMUNITY(b, s, e, SPT_H_PADCFGLOCK, 0, 0, g, ARRAY_SIZE(g)) + +/* Sunrisepoint-LP */ +static const struct pinctrl_pin_desc sptlp_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "RCINB"), + PINCTRL_PIN(1, "LAD_0"), + PINCTRL_PIN(2, "LAD_1"), + PINCTRL_PIN(3, "LAD_2"), + PINCTRL_PIN(4, "LAD_3"), + PINCTRL_PIN(5, "LFRAMEB"), + PINCTRL_PIN(6, "SERIQ"), + PINCTRL_PIN(7, "PIRQAB"), + PINCTRL_PIN(8, "CLKRUNB"), + PINCTRL_PIN(9, "CLKOUT_LPC_0"), + PINCTRL_PIN(10, "CLKOUT_LPC_1"), + PINCTRL_PIN(11, "PMEB"), + PINCTRL_PIN(12, "BM_BUSYB"), + PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"), + PINCTRL_PIN(14, "SUS_STATB"), + PINCTRL_PIN(15, "SUSACKB"), + PINCTRL_PIN(16, "SD_1P8_SEL"), + PINCTRL_PIN(17, "SD_PWR_EN_B"), + PINCTRL_PIN(18, "ISH_GP_0"), + PINCTRL_PIN(19, "ISH_GP_1"), + PINCTRL_PIN(20, "ISH_GP_2"), + PINCTRL_PIN(21, "ISH_GP_3"), + PINCTRL_PIN(22, "ISH_GP_4"), + PINCTRL_PIN(23, "ISH_GP_5"), + /* GPP_B */ + PINCTRL_PIN(24, "CORE_VID_0"), + PINCTRL_PIN(25, "CORE_VID_1"), + PINCTRL_PIN(26, "VRALERTB"), + PINCTRL_PIN(27, "CPU_GP_2"), + PINCTRL_PIN(28, "CPU_GP_3"), + PINCTRL_PIN(29, "SRCCLKREQB_0"), + PINCTRL_PIN(30, "SRCCLKREQB_1"), + PINCTRL_PIN(31, "SRCCLKREQB_2"), + PINCTRL_PIN(32, "SRCCLKREQB_3"), + PINCTRL_PIN(33, "SRCCLKREQB_4"), + PINCTRL_PIN(34, "SRCCLKREQB_5"), + PINCTRL_PIN(35, "EXT_PWR_GATEB"), + PINCTRL_PIN(36, "SLP_S0B"), + PINCTRL_PIN(37, "PLTRSTB"), + PINCTRL_PIN(38, "SPKR"), + PINCTRL_PIN(39, "GSPI0_CSB"), + PINCTRL_PIN(40, "GSPI0_CLK"), + PINCTRL_PIN(41, "GSPI0_MISO"), + PINCTRL_PIN(42, "GSPI0_MOSI"), + PINCTRL_PIN(43, "GSPI1_CSB"), + PINCTRL_PIN(44, "GSPI1_CLK"), + PINCTRL_PIN(45, "GSPI1_MISO"), + PINCTRL_PIN(46, "GSPI1_MOSI"), + PINCTRL_PIN(47, "SML1ALERTB"), + /* GPP_C */ + PINCTRL_PIN(48, "SMBCLK"), + PINCTRL_PIN(49, "SMBDATA"), + PINCTRL_PIN(50, "SMBALERTB"), + PINCTRL_PIN(51, "SML0CLK"), + PINCTRL_PIN(52, "SML0DATA"), + PINCTRL_PIN(53, "SML0ALERTB"), + PINCTRL_PIN(54, "SML1CLK"), + PINCTRL_PIN(55, "SML1DATA"), + PINCTRL_PIN(56, "UART0_RXD"), + PINCTRL_PIN(57, "UART0_TXD"), + PINCTRL_PIN(58, "UART0_RTSB"), + PINCTRL_PIN(59, "UART0_CTSB"), + PINCTRL_PIN(60, "UART1_RXD"), + PINCTRL_PIN(61, "UART1_TXD"), + PINCTRL_PIN(62, "UART1_RTSB"), + PINCTRL_PIN(63, "UART1_CTSB"), + PINCTRL_PIN(64, "I2C0_SDA"), + PINCTRL_PIN(65, "I2C0_SCL"), + PINCTRL_PIN(66, "I2C1_SDA"), + PINCTRL_PIN(67, "I2C1_SCL"), + PINCTRL_PIN(68, "UART2_RXD"), + PINCTRL_PIN(69, "UART2_TXD"), + PINCTRL_PIN(70, "UART2_RTSB"), + PINCTRL_PIN(71, "UART2_CTSB"), + /* GPP_D */ + PINCTRL_PIN(72, "SPI1_CSB"), + PINCTRL_PIN(73, "SPI1_CLK"), + PINCTRL_PIN(74, "SPI1_MISO_IO_1"), + PINCTRL_PIN(75, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(76, "FLASHTRIG"), + PINCTRL_PIN(77, "ISH_I2C0_SDA"), + PINCTRL_PIN(78, "ISH_I2C0_SCL"), + PINCTRL_PIN(79, "ISH_I2C1_SDA"), + PINCTRL_PIN(80, "ISH_I2C1_SCL"), + PINCTRL_PIN(81, "ISH_SPI_CSB"), + PINCTRL_PIN(82, "ISH_SPI_CLK"), + PINCTRL_PIN(83, "ISH_SPI_MISO"), + PINCTRL_PIN(84, "ISH_SPI_MOSI"), + PINCTRL_PIN(85, "ISH_UART0_RXD"), + PINCTRL_PIN(86, "ISH_UART0_TXD"), + PINCTRL_PIN(87, "ISH_UART0_RTSB"), + PINCTRL_PIN(88, "ISH_UART0_CTSB"), + PINCTRL_PIN(89, "DMIC_CLK_1"), + PINCTRL_PIN(90, "DMIC_DATA_1"), + PINCTRL_PIN(91, "DMIC_CLK_0"), + PINCTRL_PIN(92, "DMIC_DATA_0"), + PINCTRL_PIN(93, "SPI1_IO_2"), + PINCTRL_PIN(94, "SPI1_IO_3"), + PINCTRL_PIN(95, "SSP_MCLK"), + /* GPP_E */ + PINCTRL_PIN(96, "SATAXPCIE_0"), + PINCTRL_PIN(97, "SATAXPCIE_1"), + PINCTRL_PIN(98, "SATAXPCIE_2"), + PINCTRL_PIN(99, "CPU_GP_0"), + PINCTRL_PIN(100, "SATA_DEVSLP_0"), + PINCTRL_PIN(101, "SATA_DEVSLP_1"), + PINCTRL_PIN(102, "SATA_DEVSLP_2"), + PINCTRL_PIN(103, "CPU_GP_1"), + PINCTRL_PIN(104, "SATA_LEDB"), + PINCTRL_PIN(105, "USB2_OCB_0"), + PINCTRL_PIN(106, "USB2_OCB_1"), + PINCTRL_PIN(107, "USB2_OCB_2"), + PINCTRL_PIN(108, "USB2_OCB_3"), + PINCTRL_PIN(109, "DDSP_HPD_0"), + PINCTRL_PIN(110, "DDSP_HPD_1"), + PINCTRL_PIN(111, "DDSP_HPD_2"), + PINCTRL_PIN(112, "DDSP_HPD_3"), + PINCTRL_PIN(113, "EDP_HPD"), + PINCTRL_PIN(114, "DDPB_CTRLCLK"), + PINCTRL_PIN(115, "DDPB_CTRLDATA"), + PINCTRL_PIN(116, "DDPC_CTRLCLK"), + PINCTRL_PIN(117, "DDPC_CTRLDATA"), + PINCTRL_PIN(118, "DDPD_CTRLCLK"), + PINCTRL_PIN(119, "DDPD_CTRLDATA"), + /* GPP_F */ + PINCTRL_PIN(120, "SSP2_SCLK"), + PINCTRL_PIN(121, "SSP2_SFRM"), + PINCTRL_PIN(122, "SSP2_TXD"), + PINCTRL_PIN(123, "SSP2_RXD"), + PINCTRL_PIN(124, "I2C2_SDA"), + PINCTRL_PIN(125, "I2C2_SCL"), + PINCTRL_PIN(126, "I2C3_SDA"), + PINCTRL_PIN(127, "I2C3_SCL"), + PINCTRL_PIN(128, "I2C4_SDA"), + PINCTRL_PIN(129, "I2C4_SCL"), + PINCTRL_PIN(130, "I2C5_SDA"), + PINCTRL_PIN(131, "I2C5_SCL"), + PINCTRL_PIN(132, "EMMC_CMD"), + PINCTRL_PIN(133, "EMMC_DATA_0"), + PINCTRL_PIN(134, "EMMC_DATA_1"), + PINCTRL_PIN(135, "EMMC_DATA_2"), + PINCTRL_PIN(136, "EMMC_DATA_3"), + PINCTRL_PIN(137, "EMMC_DATA_4"), + PINCTRL_PIN(138, "EMMC_DATA_5"), + PINCTRL_PIN(139, "EMMC_DATA_6"), + PINCTRL_PIN(140, "EMMC_DATA_7"), + PINCTRL_PIN(141, "EMMC_RCLK"), + PINCTRL_PIN(142, "EMMC_CLK"), + PINCTRL_PIN(143, "GPP_F_23"), + /* GPP_G */ + PINCTRL_PIN(144, "SD_CMD"), + PINCTRL_PIN(145, "SD_DATA_0"), + PINCTRL_PIN(146, "SD_DATA_1"), + PINCTRL_PIN(147, "SD_DATA_2"), + PINCTRL_PIN(148, "SD_DATA_3"), + PINCTRL_PIN(149, "SD_CDB"), + PINCTRL_PIN(150, "SD_CLK"), + PINCTRL_PIN(151, "SD_WP"), +}; + +static const unsigned sptlp_spi0_pins[] = { 39, 40, 41, 42 }; +static const unsigned sptlp_spi1_pins[] = { 43, 44, 45, 46 }; +static const unsigned sptlp_uart0_pins[] = { 56, 57, 58, 59 }; +static const unsigned sptlp_uart1_pins[] = { 60, 61, 62, 63 }; +static const unsigned sptlp_uart2_pins[] = { 68, 69, 71, 71 }; +static const unsigned sptlp_i2c0_pins[] = { 64, 65 }; +static const unsigned sptlp_i2c1_pins[] = { 66, 67 }; +static const unsigned sptlp_i2c2_pins[] = { 124, 125 }; +static const unsigned sptlp_i2c3_pins[] = { 126, 127 }; +static const unsigned sptlp_i2c4_pins[] = { 128, 129 }; +static const unsigned sptlp_i2c4b_pins[] = { 85, 86 }; +static const unsigned sptlp_i2c5_pins[] = { 130, 131 }; +static const unsigned sptlp_ssp2_pins[] = { 120, 121, 122, 123 }; +static const unsigned sptlp_emmc_pins[] = { + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, +}; +static const unsigned sptlp_sd_pins[] = { + 144, 145, 146, 147, 148, 149, 150, 151, +}; + +static const struct intel_pingroup sptlp_groups[] = { + PIN_GROUP("spi0_grp", sptlp_spi0_pins, 1), + PIN_GROUP("spi1_grp", sptlp_spi1_pins, 1), + PIN_GROUP("uart0_grp", sptlp_uart0_pins, 1), + PIN_GROUP("uart1_grp", sptlp_uart1_pins, 1), + PIN_GROUP("uart2_grp", sptlp_uart2_pins, 1), + PIN_GROUP("i2c0_grp", sptlp_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", sptlp_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", sptlp_i2c2_pins, 1), + PIN_GROUP("i2c3_grp", sptlp_i2c3_pins, 1), + PIN_GROUP("i2c4_grp", sptlp_i2c4_pins, 1), + PIN_GROUP("i2c4b_grp", sptlp_i2c4b_pins, 3), + PIN_GROUP("i2c5_grp", sptlp_i2c5_pins, 1), + PIN_GROUP("ssp2_grp", sptlp_ssp2_pins, 1), + PIN_GROUP("emmc_grp", sptlp_emmc_pins, 1), + PIN_GROUP("sd_grp", sptlp_sd_pins, 1), +}; + +static const char * const sptlp_spi0_groups[] = { "spi0_grp" }; +static const char * const sptlp_spi1_groups[] = { "spi0_grp" }; +static const char * const sptlp_uart0_groups[] = { "uart0_grp" }; +static const char * const sptlp_uart1_groups[] = { "uart1_grp" }; +static const char * const sptlp_uart2_groups[] = { "uart2_grp" }; +static const char * const sptlp_i2c0_groups[] = { "i2c0_grp" }; +static const char * const sptlp_i2c1_groups[] = { "i2c1_grp" }; +static const char * const sptlp_i2c2_groups[] = { "i2c2_grp" }; +static const char * const sptlp_i2c3_groups[] = { "i2c3_grp" }; +static const char * const sptlp_i2c4_groups[] = { "i2c4_grp", "i2c4b_grp" }; +static const char * const sptlp_i2c5_groups[] = { "i2c5_grp" }; +static const char * const sptlp_ssp2_groups[] = { "ssp2_grp" }; +static const char * const sptlp_emmc_groups[] = { "emmc_grp" }; +static const char * const sptlp_sd_groups[] = { "sd_grp" }; + +static const struct intel_function sptlp_functions[] = { + FUNCTION("spi0", sptlp_spi0_groups), + FUNCTION("spi1", sptlp_spi1_groups), + FUNCTION("uart0", sptlp_uart0_groups), + FUNCTION("uart1", sptlp_uart1_groups), + FUNCTION("uart2", sptlp_uart2_groups), + FUNCTION("i2c0", sptlp_i2c0_groups), + FUNCTION("i2c1", sptlp_i2c1_groups), + FUNCTION("i2c2", sptlp_i2c2_groups), + FUNCTION("i2c3", sptlp_i2c3_groups), + FUNCTION("i2c4", sptlp_i2c4_groups), + FUNCTION("i2c5", sptlp_i2c5_groups), + FUNCTION("ssp2", sptlp_ssp2_groups), + FUNCTION("emmc", sptlp_emmc_groups), + FUNCTION("sd", sptlp_sd_groups), +}; + +static const struct intel_community sptlp_communities[] = { + SPT_LP_COMMUNITY(0, 0, 47), + SPT_LP_COMMUNITY(1, 48, 119), + SPT_LP_COMMUNITY(2, 120, 151), +}; + +static const struct intel_pinctrl_soc_data sptlp_soc_data = { + .pins = sptlp_pins, + .npins = ARRAY_SIZE(sptlp_pins), + .groups = sptlp_groups, + .ngroups = ARRAY_SIZE(sptlp_groups), + .functions = sptlp_functions, + .nfunctions = ARRAY_SIZE(sptlp_functions), + .communities = sptlp_communities, + .ncommunities = ARRAY_SIZE(sptlp_communities), +}; + +/* Sunrisepoint-H */ +static const struct pinctrl_pin_desc spth_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "RCINB"), + PINCTRL_PIN(1, "LAD_0"), + PINCTRL_PIN(2, "LAD_1"), + PINCTRL_PIN(3, "LAD_2"), + PINCTRL_PIN(4, "LAD_3"), + PINCTRL_PIN(5, "LFRAMEB"), + PINCTRL_PIN(6, "SERIQ"), + PINCTRL_PIN(7, "PIRQAB"), + PINCTRL_PIN(8, "CLKRUNB"), + PINCTRL_PIN(9, "CLKOUT_LPC_0"), + PINCTRL_PIN(10, "CLKOUT_LPC_1"), + PINCTRL_PIN(11, "PMEB"), + PINCTRL_PIN(12, "BM_BUSYB"), + PINCTRL_PIN(13, "SUSWARNB_SUS_PWRDNACK"), + PINCTRL_PIN(14, "SUS_STATB"), + PINCTRL_PIN(15, "SUSACKB"), + PINCTRL_PIN(16, "CLKOUT_48"), + PINCTRL_PIN(17, "ISH_GP_7"), + PINCTRL_PIN(18, "ISH_GP_0"), + PINCTRL_PIN(19, "ISH_GP_1"), + PINCTRL_PIN(20, "ISH_GP_2"), + PINCTRL_PIN(21, "ISH_GP_3"), + PINCTRL_PIN(22, "ISH_GP_4"), + PINCTRL_PIN(23, "ISH_GP_5"), + /* GPP_B */ + PINCTRL_PIN(24, "CORE_VID_0"), + PINCTRL_PIN(25, "CORE_VID_1"), + PINCTRL_PIN(26, "VRALERTB"), + PINCTRL_PIN(27, "CPU_GP_2"), + PINCTRL_PIN(28, "CPU_GP_3"), + PINCTRL_PIN(29, "SRCCLKREQB_0"), + PINCTRL_PIN(30, "SRCCLKREQB_1"), + PINCTRL_PIN(31, "SRCCLKREQB_2"), + PINCTRL_PIN(32, "SRCCLKREQB_3"), + PINCTRL_PIN(33, "SRCCLKREQB_4"), + PINCTRL_PIN(34, "SRCCLKREQB_5"), + PINCTRL_PIN(35, "EXT_PWR_GATEB"), + PINCTRL_PIN(36, "SLP_S0B"), + PINCTRL_PIN(37, "PLTRSTB"), + PINCTRL_PIN(38, "SPKR"), + PINCTRL_PIN(39, "GSPI0_CSB"), + PINCTRL_PIN(40, "GSPI0_CLK"), + PINCTRL_PIN(41, "GSPI0_MISO"), + PINCTRL_PIN(42, "GSPI0_MOSI"), + PINCTRL_PIN(43, "GSPI1_CSB"), + PINCTRL_PIN(44, "GSPI1_CLK"), + PINCTRL_PIN(45, "GSPI1_MISO"), + PINCTRL_PIN(46, "GSPI1_MOSI"), + PINCTRL_PIN(47, "SML1ALERTB"), + /* GPP_C */ + PINCTRL_PIN(48, "SMBCLK"), + PINCTRL_PIN(49, "SMBDATA"), + PINCTRL_PIN(50, "SMBALERTB"), + PINCTRL_PIN(51, "SML0CLK"), + PINCTRL_PIN(52, "SML0DATA"), + PINCTRL_PIN(53, "SML0ALERTB"), + PINCTRL_PIN(54, "SML1CLK"), + PINCTRL_PIN(55, "SML1DATA"), + PINCTRL_PIN(56, "UART0_RXD"), + PINCTRL_PIN(57, "UART0_TXD"), + PINCTRL_PIN(58, "UART0_RTSB"), + PINCTRL_PIN(59, "UART0_CTSB"), + PINCTRL_PIN(60, "UART1_RXD"), + PINCTRL_PIN(61, "UART1_TXD"), + PINCTRL_PIN(62, "UART1_RTSB"), + PINCTRL_PIN(63, "UART1_CTSB"), + PINCTRL_PIN(64, "I2C0_SDA"), + PINCTRL_PIN(65, "I2C0_SCL"), + PINCTRL_PIN(66, "I2C1_SDA"), + PINCTRL_PIN(67, "I2C1_SCL"), + PINCTRL_PIN(68, "UART2_RXD"), + PINCTRL_PIN(69, "UART2_TXD"), + PINCTRL_PIN(70, "UART2_RTSB"), + PINCTRL_PIN(71, "UART2_CTSB"), + /* GPP_D */ + PINCTRL_PIN(72, "SPI1_CSB"), + PINCTRL_PIN(73, "SPI1_CLK"), + PINCTRL_PIN(74, "SPI1_MISO_IO_1"), + PINCTRL_PIN(75, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(76, "ISH_I2C2_SDA"), + PINCTRL_PIN(77, "SSP0_SFRM"), + PINCTRL_PIN(78, "SSP0_TXD"), + PINCTRL_PIN(79, "SSP0_RXD"), + PINCTRL_PIN(80, "SSP0_SCLK"), + PINCTRL_PIN(81, "ISH_SPI_CSB"), + PINCTRL_PIN(82, "ISH_SPI_CLK"), + PINCTRL_PIN(83, "ISH_SPI_MISO"), + PINCTRL_PIN(84, "ISH_SPI_MOSI"), + PINCTRL_PIN(85, "ISH_UART0_RXD"), + PINCTRL_PIN(86, "ISH_UART0_TXD"), + PINCTRL_PIN(87, "ISH_UART0_RTSB"), + PINCTRL_PIN(88, "ISH_UART0_CTSB"), + PINCTRL_PIN(89, "DMIC_CLK_1"), + PINCTRL_PIN(90, "DMIC_DATA_1"), + PINCTRL_PIN(91, "DMIC_CLK_0"), + PINCTRL_PIN(92, "DMIC_DATA_0"), + PINCTRL_PIN(93, "SPI1_IO_2"), + PINCTRL_PIN(94, "SPI1_IO_3"), + PINCTRL_PIN(95, "ISH_I2C2_SCL"), + /* GPP_E */ + PINCTRL_PIN(96, "SATAXPCIE_0"), + PINCTRL_PIN(97, "SATAXPCIE_1"), + PINCTRL_PIN(98, "SATAXPCIE_2"), + PINCTRL_PIN(99, "CPU_GP_0"), + PINCTRL_PIN(100, "SATA_DEVSLP_0"), + PINCTRL_PIN(101, "SATA_DEVSLP_1"), + PINCTRL_PIN(102, "SATA_DEVSLP_2"), + PINCTRL_PIN(103, "CPU_GP_1"), + PINCTRL_PIN(104, "SATA_LEDB"), + PINCTRL_PIN(105, "USB2_OCB_0"), + PINCTRL_PIN(106, "USB2_OCB_1"), + PINCTRL_PIN(107, "USB2_OCB_2"), + PINCTRL_PIN(108, "USB2_OCB_3"), + /* GPP_F */ + PINCTRL_PIN(109, "SATAXPCIE_3"), + PINCTRL_PIN(110, "SATAXPCIE_4"), + PINCTRL_PIN(111, "SATAXPCIE_5"), + PINCTRL_PIN(112, "SATAXPCIE_6"), + PINCTRL_PIN(113, "SATAXPCIE_7"), + PINCTRL_PIN(114, "SATA_DEVSLP_3"), + PINCTRL_PIN(115, "SATA_DEVSLP_4"), + PINCTRL_PIN(116, "SATA_DEVSLP_5"), + PINCTRL_PIN(117, "SATA_DEVSLP_6"), + PINCTRL_PIN(118, "SATA_DEVSLP_7"), + PINCTRL_PIN(119, "SATA_SCLOCK"), + PINCTRL_PIN(120, "SATA_SLOAD"), + PINCTRL_PIN(121, "SATA_SDATAOUT1"), + PINCTRL_PIN(122, "SATA_SDATAOUT0"), + PINCTRL_PIN(123, "GPP_F_14"), + PINCTRL_PIN(124, "USB_OCB_4"), + PINCTRL_PIN(125, "USB_OCB_5"), + PINCTRL_PIN(126, "USB_OCB_6"), + PINCTRL_PIN(127, "USB_OCB_7"), + PINCTRL_PIN(128, "L_VDDEN"), + PINCTRL_PIN(129, "L_BKLTEN"), + PINCTRL_PIN(130, "L_BKLTCTL"), + PINCTRL_PIN(131, "GPP_F_22"), + PINCTRL_PIN(132, "GPP_F_23"), + /* GPP_G */ + PINCTRL_PIN(133, "FAN_TACH_0"), + PINCTRL_PIN(134, "FAN_TACH_1"), + PINCTRL_PIN(135, "FAN_TACH_2"), + PINCTRL_PIN(136, "FAN_TACH_3"), + PINCTRL_PIN(137, "FAN_TACH_4"), + PINCTRL_PIN(138, "FAN_TACH_5"), + PINCTRL_PIN(139, "FAN_TACH_6"), + PINCTRL_PIN(140, "FAN_TACH_7"), + PINCTRL_PIN(141, "FAN_PWM_0"), + PINCTRL_PIN(142, "FAN_PWM_1"), + PINCTRL_PIN(143, "FAN_PWM_2"), + PINCTRL_PIN(144, "FAN_PWM_3"), + PINCTRL_PIN(145, "GSXDOUT"), + PINCTRL_PIN(146, "GSXSLOAD"), + PINCTRL_PIN(147, "GSXDIN"), + PINCTRL_PIN(148, "GSXRESETB"), + PINCTRL_PIN(149, "GSXCLK"), + PINCTRL_PIN(150, "ADR_COMPLETE"), + PINCTRL_PIN(151, "NMIB"), + PINCTRL_PIN(152, "SMIB"), + PINCTRL_PIN(153, "GPP_G_20"), + PINCTRL_PIN(154, "GPP_G_21"), + PINCTRL_PIN(155, "GPP_G_22"), + PINCTRL_PIN(156, "GPP_G_23"), + /* GPP_H */ + PINCTRL_PIN(157, "SRCCLKREQB_6"), + PINCTRL_PIN(158, "SRCCLKREQB_7"), + PINCTRL_PIN(159, "SRCCLKREQB_8"), + PINCTRL_PIN(160, "SRCCLKREQB_9"), + PINCTRL_PIN(161, "SRCCLKREQB_10"), + PINCTRL_PIN(162, "SRCCLKREQB_11"), + PINCTRL_PIN(163, "SRCCLKREQB_12"), + PINCTRL_PIN(164, "SRCCLKREQB_13"), + PINCTRL_PIN(165, "SRCCLKREQB_14"), + PINCTRL_PIN(166, "SRCCLKREQB_15"), + PINCTRL_PIN(167, "SML2CLK"), + PINCTRL_PIN(168, "SML2DATA"), + PINCTRL_PIN(169, "SML2ALERTB"), + PINCTRL_PIN(170, "SML3CLK"), + PINCTRL_PIN(171, "SML3DATA"), + PINCTRL_PIN(172, "SML3ALERTB"), + PINCTRL_PIN(173, "SML4CLK"), + PINCTRL_PIN(174, "SML4DATA"), + PINCTRL_PIN(175, "SML4ALERTB"), + PINCTRL_PIN(176, "ISH_I2C0_SDA"), + PINCTRL_PIN(177, "ISH_I2C0_SCL"), + PINCTRL_PIN(178, "ISH_I2C1_SDA"), + PINCTRL_PIN(179, "ISH_I2C1_SCL"), + PINCTRL_PIN(180, "GPP_H_23"), + /* GPP_I */ + PINCTRL_PIN(181, "DDSP_HDP_0"), + PINCTRL_PIN(182, "DDSP_HDP_1"), + PINCTRL_PIN(183, "DDSP_HDP_2"), + PINCTRL_PIN(184, "DDSP_HDP_3"), + PINCTRL_PIN(185, "EDP_HPD"), + PINCTRL_PIN(186, "DDPB_CTRLCLK"), + PINCTRL_PIN(187, "DDPB_CTRLDATA"), + PINCTRL_PIN(188, "DDPC_CTRLCLK"), + PINCTRL_PIN(189, "DDPC_CTRLDATA"), + PINCTRL_PIN(190, "DDPD_CTRLCLK"), + PINCTRL_PIN(191, "DDPD_CTRLDATA"), +}; + +static const unsigned spth_spi0_pins[] = { 39, 40, 41, 42 }; +static const unsigned spth_spi1_pins[] = { 43, 44, 45, 46 }; +static const unsigned spth_uart0_pins[] = { 56, 57, 58, 59 }; +static const unsigned spth_uart1_pins[] = { 60, 61, 62, 63 }; +static const unsigned spth_uart2_pins[] = { 68, 69, 71, 71 }; +static const unsigned spth_i2c0_pins[] = { 64, 65 }; +static const unsigned spth_i2c1_pins[] = { 66, 67 }; +static const unsigned spth_i2c2_pins[] = { 76, 95 }; + +static const struct intel_pingroup spth_groups[] = { + PIN_GROUP("spi0_grp", spth_spi0_pins, 1), + PIN_GROUP("spi1_grp", spth_spi1_pins, 1), + PIN_GROUP("uart0_grp", spth_uart0_pins, 1), + PIN_GROUP("uart1_grp", spth_uart1_pins, 1), + PIN_GROUP("uart2_grp", spth_uart2_pins, 1), + PIN_GROUP("i2c0_grp", spth_i2c0_pins, 1), + PIN_GROUP("i2c1_grp", spth_i2c1_pins, 1), + PIN_GROUP("i2c2_grp", spth_i2c2_pins, 2), +}; + +static const char * const spth_spi0_groups[] = { "spi0_grp" }; +static const char * const spth_spi1_groups[] = { "spi0_grp" }; +static const char * const spth_uart0_groups[] = { "uart0_grp" }; +static const char * const spth_uart1_groups[] = { "uart1_grp" }; +static const char * const spth_uart2_groups[] = { "uart2_grp" }; +static const char * const spth_i2c0_groups[] = { "i2c0_grp" }; +static const char * const spth_i2c1_groups[] = { "i2c1_grp" }; +static const char * const spth_i2c2_groups[] = { "i2c2_grp" }; + +static const struct intel_function spth_functions[] = { + FUNCTION("spi0", spth_spi0_groups), + FUNCTION("spi1", spth_spi1_groups), + FUNCTION("uart0", spth_uart0_groups), + FUNCTION("uart1", spth_uart1_groups), + FUNCTION("uart2", spth_uart2_groups), + FUNCTION("i2c0", spth_i2c0_groups), + FUNCTION("i2c1", spth_i2c1_groups), + FUNCTION("i2c2", spth_i2c2_groups), +}; + +static const struct intel_padgroup spth_community0_gpps[] = { + SPT_H_GPP(0, 0, 23, 0), /* GPP_A */ + SPT_H_GPP(1, 24, 47, 24), /* GPP_B */ +}; + +static const struct intel_padgroup spth_community1_gpps[] = { + SPT_H_GPP(0, 48, 71, 48), /* GPP_C */ + SPT_H_GPP(1, 72, 95, 72), /* GPP_D */ + SPT_H_GPP(2, 96, 108, 96), /* GPP_E */ + SPT_H_GPP(3, 109, 132, 120), /* GPP_F */ + SPT_H_GPP(4, 133, 156, 144), /* GPP_G */ + SPT_H_GPP(5, 157, 180, 168), /* GPP_H */ +}; + +static const struct intel_padgroup spth_community3_gpps[] = { + SPT_H_GPP(0, 181, 191, 192), /* GPP_I */ +}; + +static const struct intel_community spth_communities[] = { + SPT_H_COMMUNITY(0, 0, 47, spth_community0_gpps), + SPT_H_COMMUNITY(1, 48, 180, spth_community1_gpps), + SPT_H_COMMUNITY(2, 181, 191, spth_community3_gpps), +}; + +static const struct intel_pinctrl_soc_data spth_soc_data = { + .pins = spth_pins, + .npins = ARRAY_SIZE(spth_pins), + .groups = spth_groups, + .ngroups = ARRAY_SIZE(spth_groups), + .functions = spth_functions, + .nfunctions = ARRAY_SIZE(spth_functions), + .communities = spth_communities, + .ncommunities = ARRAY_SIZE(spth_communities), +}; + +static const struct acpi_device_id spt_pinctrl_acpi_match[] = { + { "INT344B", (kernel_ulong_t)&sptlp_soc_data }, + { "INT3451", (kernel_ulong_t)&spth_soc_data }, + { "INT345D", (kernel_ulong_t)&spth_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, spt_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(spt_pinctrl_pm_ops); + +static struct platform_driver spt_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "sunrisepoint-pinctrl", + .acpi_match_table = spt_pinctrl_acpi_match, + .pm = &spt_pinctrl_pm_ops, + }, +}; + +static int __init spt_pinctrl_init(void) +{ + return platform_driver_register(&spt_pinctrl_driver); +} +subsys_initcall(spt_pinctrl_init); + +static void __exit spt_pinctrl_exit(void) +{ + platform_driver_unregister(&spt_pinctrl_driver); +} +module_exit(spt_pinctrl_exit); + +MODULE_AUTHOR("Mathias Nyman <mathias.nyman@linux.intel.com>"); +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Sunrisepoint PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c new file mode 100644 index 000000000..bed769d99 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -0,0 +1,771 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Tiger Lake PCH pinctrl/GPIO driver + * + * Copyright (C) 2019 - 2020, Intel Corporation + * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * Mika Westerberg <mika.westerberg@linux.intel.com> + */ + +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-intel.h" + +#define TGL_PAD_OWN 0x020 +#define TGL_LP_PADCFGLOCK 0x080 +#define TGL_H_PADCFGLOCK 0x090 +#define TGL_LP_HOSTSW_OWN 0x0b0 +#define TGL_H_HOSTSW_OWN 0x0c0 +#define TGL_GPI_IS 0x100 +#define TGL_GPI_IE 0x120 + +#define TGL_GPP(r, s, e, g) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ + } + +#define TGL_COMMUNITY(b, s, e, pl, ho, g) \ + { \ + .barno = (b), \ + .padown_offset = TGL_PAD_OWN, \ + .padcfglock_offset = (pl), \ + .hostown_offset = (ho), \ + .is_offset = TGL_GPI_IS, \ + .ie_offset = TGL_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +#define TGL_LP_COMMUNITY(b, s, e, g) \ + TGL_COMMUNITY(b, s, e, TGL_LP_PADCFGLOCK, TGL_LP_HOSTSW_OWN, g) + +#define TGL_H_COMMUNITY(b, s, e, g) \ + TGL_COMMUNITY(b, s, e, TGL_H_PADCFGLOCK, TGL_H_HOSTSW_OWN, g) + +/* Tiger Lake-LP */ +static const struct pinctrl_pin_desc tgllp_pins[] = { + /* GPP_B */ + PINCTRL_PIN(0, "CORE_VID_0"), + PINCTRL_PIN(1, "CORE_VID_1"), + PINCTRL_PIN(2, "VRALERTB"), + PINCTRL_PIN(3, "CPU_GP_2"), + PINCTRL_PIN(4, "CPU_GP_3"), + PINCTRL_PIN(5, "ISH_I2C0_SDA"), + PINCTRL_PIN(6, "ISH_I2C0_SCL"), + PINCTRL_PIN(7, "ISH_I2C1_SDA"), + PINCTRL_PIN(8, "ISH_I2C1_SCL"), + PINCTRL_PIN(9, "I2C5_SDA"), + PINCTRL_PIN(10, "I2C5_SCL"), + PINCTRL_PIN(11, "PMCALERTB"), + PINCTRL_PIN(12, "SLP_S0B"), + PINCTRL_PIN(13, "PLTRSTB"), + PINCTRL_PIN(14, "SPKR"), + PINCTRL_PIN(15, "GSPI0_CS0B"), + PINCTRL_PIN(16, "GSPI0_CLK"), + PINCTRL_PIN(17, "GSPI0_MISO"), + PINCTRL_PIN(18, "GSPI0_MOSI"), + PINCTRL_PIN(19, "GSPI1_CS0B"), + PINCTRL_PIN(20, "GSPI1_CLK"), + PINCTRL_PIN(21, "GSPI1_MISO"), + PINCTRL_PIN(22, "GSPI1_MOSI"), + PINCTRL_PIN(23, "SML1ALERTB"), + PINCTRL_PIN(24, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(25, "GSPI1_CLK_LOOPBK"), + /* GPP_T */ + PINCTRL_PIN(26, "I2C6_SDA"), + PINCTRL_PIN(27, "I2C6_SCL"), + PINCTRL_PIN(28, "I2C7_SDA"), + PINCTRL_PIN(29, "I2C7_SCL"), + PINCTRL_PIN(30, "UART4_RXD"), + PINCTRL_PIN(31, "UART4_TXD"), + PINCTRL_PIN(32, "UART4_RTSB"), + PINCTRL_PIN(33, "UART4_CTSB"), + PINCTRL_PIN(34, "UART5_RXD"), + PINCTRL_PIN(35, "UART5_TXD"), + PINCTRL_PIN(36, "UART5_RTSB"), + PINCTRL_PIN(37, "UART5_CTSB"), + PINCTRL_PIN(38, "UART6_RXD"), + PINCTRL_PIN(39, "UART6_TXD"), + PINCTRL_PIN(40, "UART6_RTSB"), + PINCTRL_PIN(41, "UART6_CTSB"), + /* GPP_A */ + PINCTRL_PIN(42, "ESPI_IO_0"), + PINCTRL_PIN(43, "ESPI_IO_1"), + PINCTRL_PIN(44, "ESPI_IO_2"), + PINCTRL_PIN(45, "ESPI_IO_3"), + PINCTRL_PIN(46, "ESPI_CSB"), + PINCTRL_PIN(47, "ESPI_CLK"), + PINCTRL_PIN(48, "ESPI_RESETB"), + PINCTRL_PIN(49, "I2S2_SCLK"), + PINCTRL_PIN(50, "I2S2_SFRM"), + PINCTRL_PIN(51, "I2S2_TXD"), + PINCTRL_PIN(52, "I2S2_RXD"), + PINCTRL_PIN(53, "PMC_I2C_SDA"), + PINCTRL_PIN(54, "SATAXPCIE_1"), + PINCTRL_PIN(55, "PMC_I2C_SCL"), + PINCTRL_PIN(56, "USB2_OCB_1"), + PINCTRL_PIN(57, "USB2_OCB_2"), + PINCTRL_PIN(58, "USB2_OCB_3"), + PINCTRL_PIN(59, "DDSP_HPD_C"), + PINCTRL_PIN(60, "DDSP_HPD_B"), + PINCTRL_PIN(61, "DDSP_HPD_1"), + PINCTRL_PIN(62, "DDSP_HPD_2"), + PINCTRL_PIN(63, "GPPC_A_21"), + PINCTRL_PIN(64, "GPPC_A_22"), + PINCTRL_PIN(65, "I2S1_SCLK"), + PINCTRL_PIN(66, "ESPI_CLK_LOOPBK"), + /* GPP_S */ + PINCTRL_PIN(67, "SNDW0_CLK"), + PINCTRL_PIN(68, "SNDW0_DATA"), + PINCTRL_PIN(69, "SNDW1_CLK"), + PINCTRL_PIN(70, "SNDW1_DATA"), + PINCTRL_PIN(71, "SNDW2_CLK"), + PINCTRL_PIN(72, "SNDW2_DATA"), + PINCTRL_PIN(73, "SNDW3_CLK"), + PINCTRL_PIN(74, "SNDW3_DATA"), + /* GPP_H */ + PINCTRL_PIN(75, "GPPC_H_0"), + PINCTRL_PIN(76, "GPPC_H_1"), + PINCTRL_PIN(77, "GPPC_H_2"), + PINCTRL_PIN(78, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(79, "I2C2_SDA"), + PINCTRL_PIN(80, "I2C2_SCL"), + PINCTRL_PIN(81, "I2C3_SDA"), + PINCTRL_PIN(82, "I2C3_SCL"), + PINCTRL_PIN(83, "I2C4_SDA"), + PINCTRL_PIN(84, "I2C4_SCL"), + PINCTRL_PIN(85, "SRCCLKREQB_4"), + PINCTRL_PIN(86, "SRCCLKREQB_5"), + PINCTRL_PIN(87, "M2_SKT2_CFG_0"), + PINCTRL_PIN(88, "M2_SKT2_CFG_1"), + PINCTRL_PIN(89, "M2_SKT2_CFG_2"), + PINCTRL_PIN(90, "M2_SKT2_CFG_3"), + PINCTRL_PIN(91, "DDPB_CTRLCLK"), + PINCTRL_PIN(92, "DDPB_CTRLDATA"), + PINCTRL_PIN(93, "CPU_C10_GATEB"), + PINCTRL_PIN(94, "TIME_SYNC_0"), + PINCTRL_PIN(95, "IMGCLKOUT_1"), + PINCTRL_PIN(96, "IMGCLKOUT_2"), + PINCTRL_PIN(97, "IMGCLKOUT_3"), + PINCTRL_PIN(98, "IMGCLKOUT_4"), + /* GPP_D */ + PINCTRL_PIN(99, "ISH_GP_0"), + PINCTRL_PIN(100, "ISH_GP_1"), + PINCTRL_PIN(101, "ISH_GP_2"), + PINCTRL_PIN(102, "ISH_GP_3"), + PINCTRL_PIN(103, "IMGCLKOUT_0"), + PINCTRL_PIN(104, "SRCCLKREQB_0"), + PINCTRL_PIN(105, "SRCCLKREQB_1"), + PINCTRL_PIN(106, "SRCCLKREQB_2"), + PINCTRL_PIN(107, "SRCCLKREQB_3"), + PINCTRL_PIN(108, "ISH_SPI_CSB"), + PINCTRL_PIN(109, "ISH_SPI_CLK"), + PINCTRL_PIN(110, "ISH_SPI_MISO"), + PINCTRL_PIN(111, "ISH_SPI_MOSI"), + PINCTRL_PIN(112, "ISH_UART0_RXD"), + PINCTRL_PIN(113, "ISH_UART0_TXD"), + PINCTRL_PIN(114, "ISH_UART0_RTSB"), + PINCTRL_PIN(115, "ISH_UART0_CTSB"), + PINCTRL_PIN(116, "ISH_GP_4"), + PINCTRL_PIN(117, "ISH_GP_5"), + PINCTRL_PIN(118, "I2S_MCLK1_OUT"), + PINCTRL_PIN(119, "GSPI2_CLK_LOOPBK"), + /* GPP_U */ + PINCTRL_PIN(120, "UART3_RXD"), + PINCTRL_PIN(121, "UART3_TXD"), + PINCTRL_PIN(122, "UART3_RTSB"), + PINCTRL_PIN(123, "UART3_CTSB"), + PINCTRL_PIN(124, "GSPI3_CS0B"), + PINCTRL_PIN(125, "GSPI3_CLK"), + PINCTRL_PIN(126, "GSPI3_MISO"), + PINCTRL_PIN(127, "GSPI3_MOSI"), + PINCTRL_PIN(128, "GSPI4_CS0B"), + PINCTRL_PIN(129, "GSPI4_CLK"), + PINCTRL_PIN(130, "GSPI4_MISO"), + PINCTRL_PIN(131, "GSPI4_MOSI"), + PINCTRL_PIN(132, "GSPI5_CS0B"), + PINCTRL_PIN(133, "GSPI5_CLK"), + PINCTRL_PIN(134, "GSPI5_MISO"), + PINCTRL_PIN(135, "GSPI5_MOSI"), + PINCTRL_PIN(136, "GSPI6_CS0B"), + PINCTRL_PIN(137, "GSPI6_CLK"), + PINCTRL_PIN(138, "GSPI6_MISO"), + PINCTRL_PIN(139, "GSPI6_MOSI"), + PINCTRL_PIN(140, "GSPI3_CLK_LOOPBK"), + PINCTRL_PIN(141, "GSPI4_CLK_LOOPBK"), + PINCTRL_PIN(142, "GSPI5_CLK_LOOPBK"), + PINCTRL_PIN(143, "GSPI6_CLK_LOOPBK"), + /* vGPIO */ + PINCTRL_PIN(144, "CNV_BTEN"), + PINCTRL_PIN(145, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(146, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(147, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(148, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(149, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(150, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(151, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(152, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(153, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(154, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(155, "vUART0_TXD"), + PINCTRL_PIN(156, "vUART0_RXD"), + PINCTRL_PIN(157, "vUART0_CTS_B"), + PINCTRL_PIN(158, "vUART0_RTS_B"), + PINCTRL_PIN(159, "vISH_UART0_TXD"), + PINCTRL_PIN(160, "vISH_UART0_RXD"), + PINCTRL_PIN(161, "vISH_UART0_CTS_B"), + PINCTRL_PIN(162, "vISH_UART0_RTS_B"), + PINCTRL_PIN(163, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(164, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(165, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(166, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(167, "vI2S2_SCLK"), + PINCTRL_PIN(168, "vI2S2_SFRM"), + PINCTRL_PIN(169, "vI2S2_TXD"), + PINCTRL_PIN(170, "vI2S2_RXD"), + /* GPP_C */ + PINCTRL_PIN(171, "SMBCLK"), + PINCTRL_PIN(172, "SMBDATA"), + PINCTRL_PIN(173, "SMBALERTB"), + PINCTRL_PIN(174, "SML0CLK"), + PINCTRL_PIN(175, "SML0DATA"), + PINCTRL_PIN(176, "SML0ALERTB"), + PINCTRL_PIN(177, "SML1CLK"), + PINCTRL_PIN(178, "SML1DATA"), + PINCTRL_PIN(179, "UART0_RXD"), + PINCTRL_PIN(180, "UART0_TXD"), + PINCTRL_PIN(181, "UART0_RTSB"), + PINCTRL_PIN(182, "UART0_CTSB"), + PINCTRL_PIN(183, "UART1_RXD"), + PINCTRL_PIN(184, "UART1_TXD"), + PINCTRL_PIN(185, "UART1_RTSB"), + PINCTRL_PIN(186, "UART1_CTSB"), + PINCTRL_PIN(187, "I2C0_SDA"), + PINCTRL_PIN(188, "I2C0_SCL"), + PINCTRL_PIN(189, "I2C1_SDA"), + PINCTRL_PIN(190, "I2C1_SCL"), + PINCTRL_PIN(191, "UART2_RXD"), + PINCTRL_PIN(192, "UART2_TXD"), + PINCTRL_PIN(193, "UART2_RTSB"), + PINCTRL_PIN(194, "UART2_CTSB"), + /* GPP_F */ + PINCTRL_PIN(195, "CNV_BRI_DT"), + PINCTRL_PIN(196, "CNV_BRI_RSP"), + PINCTRL_PIN(197, "CNV_RGI_DT"), + PINCTRL_PIN(198, "CNV_RGI_RSP"), + PINCTRL_PIN(199, "CNV_RF_RESET_B"), + PINCTRL_PIN(200, "GPPC_F_5"), + PINCTRL_PIN(201, "CNV_PA_BLANKING"), + PINCTRL_PIN(202, "GPPC_F_7"), + PINCTRL_PIN(203, "I2S_MCLK2_INOUT"), + PINCTRL_PIN(204, "BOOTMPC"), + PINCTRL_PIN(205, "GPPC_F_10"), + PINCTRL_PIN(206, "GPPC_F_11"), + PINCTRL_PIN(207, "GSXDOUT"), + PINCTRL_PIN(208, "GSXSLOAD"), + PINCTRL_PIN(209, "GSXDIN"), + PINCTRL_PIN(210, "GSXSRESETB"), + PINCTRL_PIN(211, "GSXCLK"), + PINCTRL_PIN(212, "GMII_MDC"), + PINCTRL_PIN(213, "GMII_MDIO"), + PINCTRL_PIN(214, "SRCCLKREQB_6"), + PINCTRL_PIN(215, "EXT_PWR_GATEB"), + PINCTRL_PIN(216, "EXT_PWR_GATE2B"), + PINCTRL_PIN(217, "VNN_CTRL"), + PINCTRL_PIN(218, "V1P05_CTRL"), + PINCTRL_PIN(219, "GPPF_CLK_LOOPBACK"), + /* HVCMOS */ + PINCTRL_PIN(220, "L_BKLTEN"), + PINCTRL_PIN(221, "L_BKLTCTL"), + PINCTRL_PIN(222, "L_VDDEN"), + PINCTRL_PIN(223, "SYS_PWROK"), + PINCTRL_PIN(224, "SYS_RESETB"), + PINCTRL_PIN(225, "MLK_RSTB"), + /* GPP_E */ + PINCTRL_PIN(226, "SATAXPCIE_0"), + PINCTRL_PIN(227, "SPI1_IO_2"), + PINCTRL_PIN(228, "SPI1_IO_3"), + PINCTRL_PIN(229, "CPU_GP_0"), + PINCTRL_PIN(230, "SATA_DEVSLP_0"), + PINCTRL_PIN(231, "SATA_DEVSLP_1"), + PINCTRL_PIN(232, "GPPC_E_6"), + PINCTRL_PIN(233, "CPU_GP_1"), + PINCTRL_PIN(234, "SPI1_CS1B"), + PINCTRL_PIN(235, "USB2_OCB_0"), + PINCTRL_PIN(236, "SPI1_CSB"), + PINCTRL_PIN(237, "SPI1_CLK"), + PINCTRL_PIN(238, "SPI1_MISO_IO_1"), + PINCTRL_PIN(239, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(240, "DDSP_HPD_A"), + PINCTRL_PIN(241, "ISH_GP_6"), + PINCTRL_PIN(242, "ISH_GP_7"), + PINCTRL_PIN(243, "GPPC_E_17"), + PINCTRL_PIN(244, "DDP1_CTRLCLK"), + PINCTRL_PIN(245, "DDP1_CTRLDATA"), + PINCTRL_PIN(246, "DDP2_CTRLCLK"), + PINCTRL_PIN(247, "DDP2_CTRLDATA"), + PINCTRL_PIN(248, "DDPA_CTRLCLK"), + PINCTRL_PIN(249, "DDPA_CTRLDATA"), + PINCTRL_PIN(250, "SPI1_CLK_LOOPBK"), + /* JTAG */ + PINCTRL_PIN(251, "JTAG_TDO"), + PINCTRL_PIN(252, "JTAGX"), + PINCTRL_PIN(253, "PRDYB"), + PINCTRL_PIN(254, "PREQB"), + PINCTRL_PIN(255, "CPU_TRSTB"), + PINCTRL_PIN(256, "JTAG_TDI"), + PINCTRL_PIN(257, "JTAG_TMS"), + PINCTRL_PIN(258, "JTAG_TCK"), + PINCTRL_PIN(259, "DBG_PMODE"), + /* GPP_R */ + PINCTRL_PIN(260, "HDA_BCLK"), + PINCTRL_PIN(261, "HDA_SYNC"), + PINCTRL_PIN(262, "HDA_SDO"), + PINCTRL_PIN(263, "HDA_SDI_0"), + PINCTRL_PIN(264, "HDA_RSTB"), + PINCTRL_PIN(265, "HDA_SDI_1"), + PINCTRL_PIN(266, "GPP_R_6"), + PINCTRL_PIN(267, "GPP_R_7"), + /* SPI */ + PINCTRL_PIN(268, "SPI0_IO_2"), + PINCTRL_PIN(269, "SPI0_IO_3"), + PINCTRL_PIN(270, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(271, "SPI0_MISO_IO_1"), + PINCTRL_PIN(272, "SPI0_TPM_CSB"), + PINCTRL_PIN(273, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(274, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(275, "SPI0_CLK"), + PINCTRL_PIN(276, "SPI0_CLK_LOOPBK"), +}; + +static const struct intel_padgroup tgllp_community0_gpps[] = { + TGL_GPP(0, 0, 25, 0), /* GPP_B */ + TGL_GPP(1, 26, 41, 32), /* GPP_T */ + TGL_GPP(2, 42, 66, 64), /* GPP_A */ +}; + +static const struct intel_padgroup tgllp_community1_gpps[] = { + TGL_GPP(0, 67, 74, 96), /* GPP_S */ + TGL_GPP(1, 75, 98, 128), /* GPP_H */ + TGL_GPP(2, 99, 119, 160), /* GPP_D */ + TGL_GPP(3, 120, 143, 192), /* GPP_U */ + TGL_GPP(4, 144, 170, 224), /* vGPIO */ +}; + +static const struct intel_padgroup tgllp_community4_gpps[] = { + TGL_GPP(0, 171, 194, 256), /* GPP_C */ + TGL_GPP(1, 195, 219, 288), /* GPP_F */ + TGL_GPP(2, 220, 225, INTEL_GPIO_BASE_NOMAP), /* HVCMOS */ + TGL_GPP(3, 226, 250, 320), /* GPP_E */ + TGL_GPP(4, 251, 259, INTEL_GPIO_BASE_NOMAP), /* JTAG */ +}; + +static const struct intel_padgroup tgllp_community5_gpps[] = { + TGL_GPP(0, 260, 267, 352), /* GPP_R */ + TGL_GPP(1, 268, 276, INTEL_GPIO_BASE_NOMAP), /* SPI */ +}; + +static const struct intel_community tgllp_communities[] = { + TGL_LP_COMMUNITY(0, 0, 66, tgllp_community0_gpps), + TGL_LP_COMMUNITY(1, 67, 170, tgllp_community1_gpps), + TGL_LP_COMMUNITY(2, 171, 259, tgllp_community4_gpps), + TGL_LP_COMMUNITY(3, 260, 276, tgllp_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data tgllp_soc_data = { + .pins = tgllp_pins, + .npins = ARRAY_SIZE(tgllp_pins), + .communities = tgllp_communities, + .ncommunities = ARRAY_SIZE(tgllp_communities), +}; + +/* Tiger Lake-H */ +static const struct pinctrl_pin_desc tglh_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "SPI0_IO_2"), + PINCTRL_PIN(1, "SPI0_IO_3"), + PINCTRL_PIN(2, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(3, "SPI0_MISO_IO_1"), + PINCTRL_PIN(4, "SPI0_TPM_CSB"), + PINCTRL_PIN(5, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(6, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(7, "SPI0_CLK"), + PINCTRL_PIN(8, "ESPI_IO_0"), + PINCTRL_PIN(9, "ESPI_IO_1"), + PINCTRL_PIN(10, "ESPI_IO_2"), + PINCTRL_PIN(11, "ESPI_IO_3"), + PINCTRL_PIN(12, "ESPI_CS0B"), + PINCTRL_PIN(13, "ESPI_CLK"), + PINCTRL_PIN(14, "ESPI_RESETB"), + PINCTRL_PIN(15, "ESPI_CS1B"), + PINCTRL_PIN(16, "ESPI_CS2B"), + PINCTRL_PIN(17, "ESPI_CS3B"), + PINCTRL_PIN(18, "ESPI_ALERT0B"), + PINCTRL_PIN(19, "ESPI_ALERT1B"), + PINCTRL_PIN(20, "ESPI_ALERT2B"), + PINCTRL_PIN(21, "ESPI_ALERT3B"), + PINCTRL_PIN(22, "GPPC_A_14"), + PINCTRL_PIN(23, "SPI0_CLK_LOOPBK"), + PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"), + /* GPP_R */ + PINCTRL_PIN(25, "HDA_BCLK"), + PINCTRL_PIN(26, "HDA_SYNC"), + PINCTRL_PIN(27, "HDA_SDO"), + PINCTRL_PIN(28, "HDA_SDI_0"), + PINCTRL_PIN(29, "HDA_RSTB"), + PINCTRL_PIN(30, "HDA_SDI_1"), + PINCTRL_PIN(31, "GPP_R_6"), + PINCTRL_PIN(32, "GPP_R_7"), + PINCTRL_PIN(33, "GPP_R_8"), + PINCTRL_PIN(34, "PCIE_LNK_DOWN"), + PINCTRL_PIN(35, "ISH_UART0_RTSB"), + PINCTRL_PIN(36, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(37, "CLKOUT_48"), + PINCTRL_PIN(38, "ISH_GP_7"), + PINCTRL_PIN(39, "ISH_GP_0"), + PINCTRL_PIN(40, "ISH_GP_1"), + PINCTRL_PIN(41, "ISH_GP_2"), + PINCTRL_PIN(42, "ISH_GP_3"), + PINCTRL_PIN(43, "ISH_GP_4"), + PINCTRL_PIN(44, "ISH_GP_5"), + /* GPP_B */ + PINCTRL_PIN(45, "GSPI0_CS1B"), + PINCTRL_PIN(46, "GSPI1_CS1B"), + PINCTRL_PIN(47, "VRALERTB"), + PINCTRL_PIN(48, "CPU_GP_2"), + PINCTRL_PIN(49, "CPU_GP_3"), + PINCTRL_PIN(50, "SRCCLKREQB_0"), + PINCTRL_PIN(51, "SRCCLKREQB_1"), + PINCTRL_PIN(52, "SRCCLKREQB_2"), + PINCTRL_PIN(53, "SRCCLKREQB_3"), + PINCTRL_PIN(54, "SRCCLKREQB_4"), + PINCTRL_PIN(55, "SRCCLKREQB_5"), + PINCTRL_PIN(56, "I2S_MCLK"), + PINCTRL_PIN(57, "SLP_S0B"), + PINCTRL_PIN(58, "PLTRSTB"), + PINCTRL_PIN(59, "SPKR"), + PINCTRL_PIN(60, "GSPI0_CS0B"), + PINCTRL_PIN(61, "GSPI0_CLK"), + PINCTRL_PIN(62, "GSPI0_MISO"), + PINCTRL_PIN(63, "GSPI0_MOSI"), + PINCTRL_PIN(64, "GSPI1_CS0B"), + PINCTRL_PIN(65, "GSPI1_CLK"), + PINCTRL_PIN(66, "GSPI1_MISO"), + PINCTRL_PIN(67, "GSPI1_MOSI"), + PINCTRL_PIN(68, "SML1ALERTB"), + PINCTRL_PIN(69, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(70, "GSPI1_CLK_LOOPBK"), + /* vGPIO_0 */ + PINCTRL_PIN(71, "ESPI_USB_OCB_0"), + PINCTRL_PIN(72, "ESPI_USB_OCB_1"), + PINCTRL_PIN(73, "ESPI_USB_OCB_2"), + PINCTRL_PIN(74, "ESPI_USB_OCB_3"), + PINCTRL_PIN(75, "USB_CPU_OCB_0"), + PINCTRL_PIN(76, "USB_CPU_OCB_1"), + PINCTRL_PIN(77, "USB_CPU_OCB_2"), + PINCTRL_PIN(78, "USB_CPU_OCB_3"), + /* GPP_D */ + PINCTRL_PIN(79, "SPI1_CSB"), + PINCTRL_PIN(80, "SPI1_CLK"), + PINCTRL_PIN(81, "SPI1_MISO_IO_1"), + PINCTRL_PIN(82, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(83, "SML1CLK"), + PINCTRL_PIN(84, "I2S2_SFRM"), + PINCTRL_PIN(85, "I2S2_TXD"), + PINCTRL_PIN(86, "I2S2_RXD"), + PINCTRL_PIN(87, "I2S2_SCLK"), + PINCTRL_PIN(88, "SML0CLK"), + PINCTRL_PIN(89, "SML0DATA"), + PINCTRL_PIN(90, "GPP_D_11"), + PINCTRL_PIN(91, "ISH_UART0_CTSB"), + PINCTRL_PIN(92, "SPI1_IO_2"), + PINCTRL_PIN(93, "SPI1_IO_3"), + PINCTRL_PIN(94, "SML1DATA"), + PINCTRL_PIN(95, "GSPI3_CS0B"), + PINCTRL_PIN(96, "GSPI3_CLK"), + PINCTRL_PIN(97, "GSPI3_MISO"), + PINCTRL_PIN(98, "GSPI3_MOSI"), + PINCTRL_PIN(99, "UART3_RXD"), + PINCTRL_PIN(100, "UART3_TXD"), + PINCTRL_PIN(101, "UART3_RTSB"), + PINCTRL_PIN(102, "UART3_CTSB"), + PINCTRL_PIN(103, "SPI1_CLK_LOOPBK"), + PINCTRL_PIN(104, "GSPI3_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(105, "SMBCLK"), + PINCTRL_PIN(106, "SMBDATA"), + PINCTRL_PIN(107, "SMBALERTB"), + PINCTRL_PIN(108, "ISH_UART0_RXD"), + PINCTRL_PIN(109, "ISH_UART0_TXD"), + PINCTRL_PIN(110, "SML0ALERTB"), + PINCTRL_PIN(111, "ISH_I2C2_SDA"), + PINCTRL_PIN(112, "ISH_I2C2_SCL"), + PINCTRL_PIN(113, "UART0_RXD"), + PINCTRL_PIN(114, "UART0_TXD"), + PINCTRL_PIN(115, "UART0_RTSB"), + PINCTRL_PIN(116, "UART0_CTSB"), + PINCTRL_PIN(117, "UART1_RXD"), + PINCTRL_PIN(118, "UART1_TXD"), + PINCTRL_PIN(119, "UART1_RTSB"), + PINCTRL_PIN(120, "UART1_CTSB"), + PINCTRL_PIN(121, "I2C0_SDA"), + PINCTRL_PIN(122, "I2C0_SCL"), + PINCTRL_PIN(123, "I2C1_SDA"), + PINCTRL_PIN(124, "I2C1_SCL"), + PINCTRL_PIN(125, "UART2_RXD"), + PINCTRL_PIN(126, "UART2_TXD"), + PINCTRL_PIN(127, "UART2_RTSB"), + PINCTRL_PIN(128, "UART2_CTSB"), + /* GPP_S */ + PINCTRL_PIN(129, "SNDW1_CLK"), + PINCTRL_PIN(130, "SNDW1_DATA"), + PINCTRL_PIN(131, "SNDW2_CLK"), + PINCTRL_PIN(132, "SNDW2_DATA"), + PINCTRL_PIN(133, "SNDW3_CLK"), + PINCTRL_PIN(134, "SNDW3_DATA"), + PINCTRL_PIN(135, "SNDW4_CLK"), + PINCTRL_PIN(136, "SNDW4_DATA"), + /* GPP_G */ + PINCTRL_PIN(137, "DDPA_CTRLCLK"), + PINCTRL_PIN(138, "DDPA_CTRLDATA"), + PINCTRL_PIN(139, "DNX_FORCE_RELOAD"), + PINCTRL_PIN(140, "GMII_MDC_0"), + PINCTRL_PIN(141, "GMII_MDIO_0"), + PINCTRL_PIN(142, "SLP_DRAMB"), + PINCTRL_PIN(143, "GPPC_G_6"), + PINCTRL_PIN(144, "GPPC_G_7"), + PINCTRL_PIN(145, "ISH_SPI_CSB"), + PINCTRL_PIN(146, "ISH_SPI_CLK"), + PINCTRL_PIN(147, "ISH_SPI_MISO"), + PINCTRL_PIN(148, "ISH_SPI_MOSI"), + PINCTRL_PIN(149, "DDP1_CTRLCLK"), + PINCTRL_PIN(150, "DDP1_CTRLDATA"), + PINCTRL_PIN(151, "DDP2_CTRLCLK"), + PINCTRL_PIN(152, "DDP2_CTRLDATA"), + PINCTRL_PIN(153, "GSPI2_CLK_LOOPBK"), + /* vGPIO */ + PINCTRL_PIN(154, "CNV_BTEN"), + PINCTRL_PIN(155, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(156, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(157, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(158, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(159, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(160, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(161, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(162, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(163, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(164, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(165, "vUART0_TXD"), + PINCTRL_PIN(166, "vUART0_RXD"), + PINCTRL_PIN(167, "vUART0_CTS_B"), + PINCTRL_PIN(168, "vUART0_RTS_B"), + PINCTRL_PIN(169, "vISH_UART0_TXD"), + PINCTRL_PIN(170, "vISH_UART0_RXD"), + PINCTRL_PIN(171, "vISH_UART0_CTS_B"), + PINCTRL_PIN(172, "vISH_UART0_RTS_B"), + PINCTRL_PIN(173, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(174, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(175, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(176, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(177, "vI2S2_SCLK"), + PINCTRL_PIN(178, "vI2S2_SFRM"), + PINCTRL_PIN(179, "vI2S2_TXD"), + PINCTRL_PIN(180, "vI2S2_RXD"), + /* GPP_E */ + PINCTRL_PIN(181, "SATAXPCIE_0"), + PINCTRL_PIN(182, "SATAXPCIE_1"), + PINCTRL_PIN(183, "SATAXPCIE_2"), + PINCTRL_PIN(184, "CPU_GP_0"), + PINCTRL_PIN(185, "SATA_DEVSLP_0"), + PINCTRL_PIN(186, "SATA_DEVSLP_1"), + PINCTRL_PIN(187, "SATA_DEVSLP_2"), + PINCTRL_PIN(188, "CPU_GP_1"), + PINCTRL_PIN(189, "SATA_LEDB"), + PINCTRL_PIN(190, "USB2_OCB_0"), + PINCTRL_PIN(191, "USB2_OCB_1"), + PINCTRL_PIN(192, "USB2_OCB_2"), + PINCTRL_PIN(193, "USB2_OCB_3"), + /* GPP_F */ + PINCTRL_PIN(194, "SATAXPCIE_3"), + PINCTRL_PIN(195, "SATAXPCIE_4"), + PINCTRL_PIN(196, "SATAXPCIE_5"), + PINCTRL_PIN(197, "SATAXPCIE_6"), + PINCTRL_PIN(198, "SATAXPCIE_7"), + PINCTRL_PIN(199, "SATA_DEVSLP_3"), + PINCTRL_PIN(200, "SATA_DEVSLP_4"), + PINCTRL_PIN(201, "SATA_DEVSLP_5"), + PINCTRL_PIN(202, "SATA_DEVSLP_6"), + PINCTRL_PIN(203, "SATA_DEVSLP_7"), + PINCTRL_PIN(204, "SATA_SCLOCK"), + PINCTRL_PIN(205, "SATA_SLOAD"), + PINCTRL_PIN(206, "SATA_SDATAOUT1"), + PINCTRL_PIN(207, "SATA_SDATAOUT0"), + PINCTRL_PIN(208, "PS_ONB"), + PINCTRL_PIN(209, "M2_SKT2_CFG_0"), + PINCTRL_PIN(210, "M2_SKT2_CFG_1"), + PINCTRL_PIN(211, "M2_SKT2_CFG_2"), + PINCTRL_PIN(212, "M2_SKT2_CFG_3"), + PINCTRL_PIN(213, "L_VDDEN"), + PINCTRL_PIN(214, "L_BKLTEN"), + PINCTRL_PIN(215, "L_BKLTCTL"), + PINCTRL_PIN(216, "VNN_CTRL"), + PINCTRL_PIN(217, "GPP_F_23"), + /* GPP_H */ + PINCTRL_PIN(218, "SRCCLKREQB_6"), + PINCTRL_PIN(219, "SRCCLKREQB_7"), + PINCTRL_PIN(220, "SRCCLKREQB_8"), + PINCTRL_PIN(221, "SRCCLKREQB_9"), + PINCTRL_PIN(222, "SRCCLKREQB_10"), + PINCTRL_PIN(223, "SRCCLKREQB_11"), + PINCTRL_PIN(224, "SRCCLKREQB_12"), + PINCTRL_PIN(225, "SRCCLKREQB_13"), + PINCTRL_PIN(226, "SRCCLKREQB_14"), + PINCTRL_PIN(227, "SRCCLKREQB_15"), + PINCTRL_PIN(228, "SML2CLK"), + PINCTRL_PIN(229, "SML2DATA"), + PINCTRL_PIN(230, "SML2ALERTB"), + PINCTRL_PIN(231, "SML3CLK"), + PINCTRL_PIN(232, "SML3DATA"), + PINCTRL_PIN(233, "SML3ALERTB"), + PINCTRL_PIN(234, "SML4CLK"), + PINCTRL_PIN(235, "SML4DATA"), + PINCTRL_PIN(236, "SML4ALERTB"), + PINCTRL_PIN(237, "ISH_I2C0_SDA"), + PINCTRL_PIN(238, "ISH_I2C0_SCL"), + PINCTRL_PIN(239, "ISH_I2C1_SDA"), + PINCTRL_PIN(240, "ISH_I2C1_SCL"), + PINCTRL_PIN(241, "TIME_SYNC_0"), + /* GPP_J */ + PINCTRL_PIN(242, "CNV_PA_BLANKING"), + PINCTRL_PIN(243, "CPU_C10_GATEB"), + PINCTRL_PIN(244, "CNV_BRI_DT"), + PINCTRL_PIN(245, "CNV_BRI_RSP"), + PINCTRL_PIN(246, "CNV_RGI_DT"), + PINCTRL_PIN(247, "CNV_RGI_RSP"), + PINCTRL_PIN(248, "CNV_MFUART2_RXD"), + PINCTRL_PIN(249, "CNV_MFUART2_TXD"), + PINCTRL_PIN(250, "GPP_J_8"), + PINCTRL_PIN(251, "GPP_J_9"), + /* GPP_K */ + PINCTRL_PIN(252, "GSXDOUT"), + PINCTRL_PIN(253, "GSXSLOAD"), + PINCTRL_PIN(254, "GSXDIN"), + PINCTRL_PIN(255, "GSXSRESETB"), + PINCTRL_PIN(256, "GSXCLK"), + PINCTRL_PIN(257, "ADR_COMPLETE"), + PINCTRL_PIN(258, "DDSP_HPD_A"), + PINCTRL_PIN(259, "DDSP_HPD_B"), + PINCTRL_PIN(260, "CORE_VID_0"), + PINCTRL_PIN(261, "CORE_VID_1"), + PINCTRL_PIN(262, "DDSP_HPD_C"), + PINCTRL_PIN(263, "GPP_K_11"), + PINCTRL_PIN(264, "SYS_PWROK"), + PINCTRL_PIN(265, "SYS_RESETB"), + PINCTRL_PIN(266, "MLK_RSTB"), + /* GPP_I */ + PINCTRL_PIN(267, "PMCALERTB"), + PINCTRL_PIN(268, "DDSP_HPD_1"), + PINCTRL_PIN(269, "DDSP_HPD_2"), + PINCTRL_PIN(270, "DDSP_HPD_3"), + PINCTRL_PIN(271, "DDSP_HPD_4"), + PINCTRL_PIN(272, "DDPB_CTRLCLK"), + PINCTRL_PIN(273, "DDPB_CTRLDATA"), + PINCTRL_PIN(274, "DDPC_CTRLCLK"), + PINCTRL_PIN(275, "DDPC_CTRLDATA"), + PINCTRL_PIN(276, "FUSA_DIAGTEST_EN"), + PINCTRL_PIN(277, "FUSA_DIAGTEST_MODE"), + PINCTRL_PIN(278, "USB2_OCB_4"), + PINCTRL_PIN(279, "USB2_OCB_5"), + PINCTRL_PIN(280, "USB2_OCB_6"), + PINCTRL_PIN(281, "USB2_OCB_7"), + /* JTAG */ + PINCTRL_PIN(282, "JTAG_TDO"), + PINCTRL_PIN(283, "JTAGX"), + PINCTRL_PIN(284, "PRDYB"), + PINCTRL_PIN(285, "PREQB"), + PINCTRL_PIN(286, "JTAG_TDI"), + PINCTRL_PIN(287, "JTAG_TMS"), + PINCTRL_PIN(288, "JTAG_TCK"), + PINCTRL_PIN(289, "DBG_PMODE"), + PINCTRL_PIN(290, "CPU_TRSTB"), +}; + +static const struct intel_padgroup tglh_community0_gpps[] = { + TGL_GPP(0, 0, 24, 0), /* GPP_A */ + TGL_GPP(1, 25, 44, 32), /* GPP_R */ + TGL_GPP(2, 45, 70, 64), /* GPP_B */ + TGL_GPP(3, 71, 78, 96), /* vGPIO_0 */ +}; + +static const struct intel_padgroup tglh_community1_gpps[] = { + TGL_GPP(0, 79, 104, 128), /* GPP_D */ + TGL_GPP(1, 105, 128, 160), /* GPP_C */ + TGL_GPP(2, 129, 136, 192), /* GPP_S */ + TGL_GPP(3, 137, 153, 224), /* GPP_G */ + TGL_GPP(4, 154, 180, 256), /* vGPIO */ +}; + +static const struct intel_padgroup tglh_community3_gpps[] = { + TGL_GPP(0, 181, 193, 288), /* GPP_E */ + TGL_GPP(1, 194, 217, 320), /* GPP_F */ +}; + +static const struct intel_padgroup tglh_community4_gpps[] = { + TGL_GPP(0, 218, 241, 352), /* GPP_H */ + TGL_GPP(1, 242, 251, 384), /* GPP_J */ + TGL_GPP(2, 252, 266, 416), /* GPP_K */ +}; + +static const struct intel_padgroup tglh_community5_gpps[] = { + TGL_GPP(0, 267, 281, 448), /* GPP_I */ + TGL_GPP(1, 282, 290, INTEL_GPIO_BASE_NOMAP), /* JTAG */ +}; + +static const struct intel_community tglh_communities[] = { + TGL_H_COMMUNITY(0, 0, 78, tglh_community0_gpps), + TGL_H_COMMUNITY(1, 79, 180, tglh_community1_gpps), + TGL_H_COMMUNITY(2, 181, 217, tglh_community3_gpps), + TGL_H_COMMUNITY(3, 218, 266, tglh_community4_gpps), + TGL_H_COMMUNITY(4, 267, 290, tglh_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data tglh_soc_data = { + .pins = tglh_pins, + .npins = ARRAY_SIZE(tglh_pins), + .communities = tglh_communities, + .ncommunities = ARRAY_SIZE(tglh_communities), +}; + +static const struct acpi_device_id tgl_pinctrl_acpi_match[] = { + { "INT34C5", (kernel_ulong_t)&tgllp_soc_data }, + { "INT34C6", (kernel_ulong_t)&tglh_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(tgl_pinctrl_pm_ops); + +static struct platform_driver tgl_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "tigerlake-pinctrl", + .acpi_match_table = tgl_pinctrl_acpi_match, + .pm = &tgl_pinctrl_pm_ops, + }, +}; + +module_platform_driver(tgl_pinctrl_driver); + +MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); +MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Tiger Lake PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); |