From 27351b93c07e62a1b23dd492b625f0eca6e9283a Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Fri, 6 Dec 2013 16:58:10 -0800 Subject: [PATCH] baytrail: gpio: Make GPIO inputs MMIO by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Linux kernel driver cannot handle Baytrail legacy GPIOs, so make the default input GPIO type MMIO. BUG=chrome-os-partner:24408 TEST=Manual on Rambi. Run "echo 169 > /sys/class/gpio/export; cat /sys/class/gpio/gpio169/value", verify GPIO value changes based upon mic jack status. BRANCH=None Change-Id: I27870ce8b7ecae9228e06e48c8759409c824c2eb Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/179169 Reviewed-by: Aaron Durbin Signed-off-by: Aaron Durbin Reviewed-on: http://review.coreboot.org/4992 Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/soc/intel/baytrail/baytrail/gpio.h | 72 ++++++++++++++++---------- src/soc/intel/baytrail/gpio.c | 24 +++++++-- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/src/soc/intel/baytrail/baytrail/gpio.h b/src/soc/intel/baytrail/baytrail/gpio.h index e6f38662e4..e7cc344c38 100644 --- a/src/soc/intel/baytrail/baytrail/gpio.h +++ b/src/soc/intel/baytrail/baytrail/gpio.h @@ -59,7 +59,7 @@ #define GPSSUS_COUNT 44 /* GPIO legacy IO register settings */ -#define GPIO_USE_PAD 0 +#define GPIO_USE_MMIO 0 #define GPIO_USE_LEGACY 1 #define GPIO_DIR_OUTPUT 0 @@ -155,32 +155,35 @@ * if not set correctly, even if the pin isn't configured as GPIO. */ #define PAD_VAL_DEFAULT PAD_VAL_INPUT -/* Configure GPIOs as legacy by default. GPNCORE doesn't support - * legacy config -- so also configure the pad regs as GPIO. We rely upon - * the fact that all GPNCORE pads are function 0 GPIO. */ +/* Configure GPIOs as MMIO by default */ #define GPIO_INPUT_PU_10K \ - { .pad_conf0 = PAD_PU_10K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT \ - | PAD_FUNC0, \ + { .pad_conf0 = PAD_PU_10K | PAD_PULL_UP | PAD_CONFIG0_DEFAULT, \ .pad_conf1 = PAD_CONFIG1_DEFAULT, \ .pad_val = PAD_VAL_INPUT, \ - .use_sel = GPIO_USE_LEGACY, \ - .io_sel = GPIO_DIR_INPUT } + .use_sel = GPIO_USE_MMIO, \ + .is_gpio = 1 } #define GPIO_INPUT_PD_10K \ - { .pad_conf0 = PAD_PU_10K | PAD_PULL_DOWN | PAD_CONFIG0_DEFAULT \ - | PAD_FUNC0, \ + { .pad_conf0 = PAD_PU_10K | PAD_PULL_DOWN | PAD_CONFIG0_DEFAULT, \ .pad_conf1 = PAD_CONFIG1_DEFAULT, \ .pad_val = PAD_VAL_INPUT, \ - .use_sel = GPIO_USE_LEGACY, \ - .io_sel = GPIO_DIR_INPUT } + .use_sel = GPIO_USE_MMIO, \ + .is_gpio = 1 } #define GPIO_INPUT_NOPU \ - { .pad_conf0 = PAD_PU_10K | PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT \ - | PAD_FUNC0, \ + { .pad_conf0 = PAD_PU_10K | PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \ + .pad_conf1 = PAD_CONFIG1_DEFAULT, \ + .pad_val = PAD_VAL_INPUT, \ + .use_sel = GPIO_USE_MMIO, \ + .is_gpio = 1 } + +#define GPIO_INPUT_LEGACY_NOPU \ + { .pad_conf0 = PAD_PU_10K | PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \ .pad_conf1 = PAD_CONFIG1_DEFAULT, \ .pad_val = PAD_VAL_INPUT, \ .use_sel = GPIO_USE_LEGACY, \ - .io_sel = GPIO_DIR_INPUT } + .io_sel = GPIO_DIR_INPUT, \ + .is_gpio = 1 } /* Direct / dedicated IRQ input - pass signal directly to apic */ #define GPIO_DIRQ \ @@ -192,25 +195,25 @@ #define GPIO_OUT_LOW \ { .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT \ - | PAD_FUNC0, \ .pad_conf1 = PAD_CONFIG1_DEFAULT, \ .pad_val = PAD_VAL_OUTPUT | PAD_VAL_LOW, \ .use_sel = GPIO_USE_LEGACY, \ .io_sel = GPIO_DIR_OUTPUT, \ - .gp_lvl = GPIO_LEVEL_LOW } + .gp_lvl = GPIO_LEVEL_LOW, \ + .is_gpio = 1 } #define GPIO_OUT_HIGH \ - { .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT \ - | PAD_FUNC0, \ + { .pad_conf0 = PAD_PULL_DISABLE | PAD_CONFIG0_DEFAULT, \ .pad_conf1 = PAD_CONFIG1_DEFAULT, \ .pad_val = PAD_VAL_OUTPUT | PAD_VAL_HIGH, \ .use_sel = GPIO_USE_LEGACY, \ .io_sel = GPIO_DIR_OUTPUT, \ - .gp_lvl = GPIO_LEVEL_HIGH } + .gp_lvl = GPIO_LEVEL_HIGH, \ + .is_gpio = 1 } /* Define no-pull / PU / PD configs for each functional config option */ #define GPIO_FUNC(_func, _pudir, _str) \ - { .use_sel = GPIO_USE_PAD, \ + { .use_sel = GPIO_USE_MMIO, \ .pad_conf0 = PAD_FUNC##_func | PAD_##_pudir | PAD_PU_##_str | \ PAD_CONFIG0_DEFAULT, \ .pad_conf1 = PAD_CONFIG1_DEFAULT, \ @@ -251,15 +254,29 @@ { .pad_conf0 = GPIO_LIST_END } /* Common default GPIO settings */ -#define GPIO_INPUT GPIO_INPUT_NOPU -#define GPIO_INPUT_PU GPIO_INPUT_PU_10K -#define GPIO_INPUT_PD GPIO_INPUT_PD_10K -#define GPIO_NC GPIO_INPUT_PU_10K -#define GPIO_DEFAULT GPIO_FUNC0 +#define GPIO_INPUT GPIO_INPUT_NOPU +#define GPIO_INPUT_LEGACY GPIO_INPUT_LEGACY_NOPU +#define GPIO_INPUT_PU GPIO_INPUT_PU_10K +#define GPIO_INPUT_PD GPIO_INPUT_PD_10K +#define GPIO_NC GPIO_INPUT_PU_10K +#define GPIO_DEFAULT GPIO_FUNC0 /* 16 DirectIRQs per supported bank */ #define GPIO_MAX_DIRQS 16 +/* Most pins are GPIO function 0. Some banks have a range of pins with GPIO + * function 1. Indicate first / last GPIOs with function 1. */ +#define GPIO_NONE 255 +/* All NCORE GPIOs are function 0 */ +#define GPNCORE_GPIO_F1_RANGE_START GPIO_NONE +#define GPNCORE_GPIO_F1_RANGE_END GPIO_NONE +/* SCORE GPIO [92:93] are function 1 */ +#define GPSCORE_GPIO_F1_RANGE_START 92 +#define GPSCORE_GPIO_F1_RANGE_END 93 +/* SSUS GPIO [11:21] are function 1 */ +#define GPSSUS_GPIO_F1_RANGE_START 11 +#define GPSSUS_GPIO_F1_RANGE_END 21 + struct soc_gpio_map { u32 pad_conf0; u32 pad_conf1; @@ -271,6 +288,7 @@ struct soc_gpio_map { u8 tne : 1; u8 wake_en : 1; u8 smi : 1; + u8 is_gpio : 1; } __attribute__ ((packed)); struct soc_gpio_config { @@ -288,6 +306,8 @@ struct gpio_bank { const int legacy_base; const unsigned long pad_base; const u8 has_wake_en :1; + const u8 gpio_f1_range_start; + const u8 gpio_f1_range_end; }; void setup_soc_gpios(struct soc_gpio_config *config); diff --git a/src/soc/intel/baytrail/gpio.c b/src/soc/intel/baytrail/gpio.c index a3c2faaa49..aa495914e5 100644 --- a/src/soc/intel/baytrail/gpio.c +++ b/src/soc/intel/baytrail/gpio.c @@ -60,6 +60,8 @@ static const struct gpio_bank gpncore_bank = { .legacy_base = GP_LEGACY_BASE_NONE, .pad_base = GPNCORE_PAD_BASE, .has_wake_en = 0, + .gpio_f1_range_start = GPNCORE_GPIO_F1_RANGE_START, + .gpio_f1_range_end = GPNCORE_GPIO_F1_RANGE_END, }; static const struct gpio_bank gpscore_bank = { @@ -68,6 +70,8 @@ static const struct gpio_bank gpscore_bank = { .legacy_base = GPSCORE_LEGACY_BASE, .pad_base = GPSCORE_PAD_BASE, .has_wake_en = 0, + .gpio_f1_range_start = GPSCORE_GPIO_F1_RANGE_START, + .gpio_f1_range_end = GPSCORE_GPIO_F1_RANGE_END, }; static const struct gpio_bank gpssus_bank = { @@ -76,6 +80,8 @@ static const struct gpio_bank gpssus_bank = { .legacy_base = GPSSUS_LEGACY_BASE, .pad_base = GPSSUS_PAD_BASE, .has_wake_en = 1, + .gpio_f1_range_start = GPSSUS_GPIO_F1_RANGE_START, + .gpio_f1_range_end = GPSSUS_GPIO_F1_RANGE_END, }; static void setup_gpios(const struct soc_gpio_map *gpios, @@ -83,7 +89,7 @@ static void setup_gpios(const struct soc_gpio_map *gpios, { const struct soc_gpio_map *config; int gpio = 0; - u32 reg; + u32 reg, pad_conf0; u8 set, bit; u32 use_sel[4] = {0}; @@ -120,13 +126,23 @@ static void setup_gpios(const struct soc_gpio_map *gpios, /* Pad configuration registers */ reg = bank->pad_base + 16 * bank->gpio_to_pad[gpio]; + /* Add correct func to GPIO pad config */ + pad_conf0 = config->pad_conf0; + if (config->is_gpio) + { + if (gpio >= bank->gpio_f1_range_start && + gpio <= bank->gpio_f1_range_end) + pad_conf0 |= PAD_FUNC1; + else + pad_conf0 |= PAD_FUNC0; + } + #ifdef GPIO_DEBUG printk(BIOS_DEBUG, "Write Pad: Base(%x) - %x %x %x\n", - reg, config->pad_conf0, config->pad_conf1, - config->pad_val ); + reg, pad_conf0, config->pad_conf1, config->pad_val); #endif - write32(reg + PAD_CONF0_REG, config->pad_conf0); + write32(reg + PAD_CONF0_REG, pad_conf0); write32(reg + PAD_CONF1_REG, config->pad_conf1); write32(reg + PAD_VAL_REG, config->pad_val); }