summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2013-12-06 16:58:10 -0800
committerKyösti Mälkki <kyosti.malkki@gmail.com>2014-05-08 07:07:17 +0200
commit27351b93c07e62a1b23dd492b625f0eca6e9283a (patch)
tree72a0904a7c1ad37fa3d5450460e8ee5f8f05fcf9
parent70cc9084a51e7f276b20d146fdab5fda6884febb (diff)
downloadcoreboot-27351b93c07e62a1b23dd492b625f0eca6e9283a.tar.xz
baytrail: gpio: Make GPIO inputs MMIO by default
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 <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/179169 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/4992 Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Tested-by: build bot (Jenkins)
-rw-r--r--src/soc/intel/baytrail/baytrail/gpio.h72
-rw-r--r--src/soc/intel/baytrail/gpio.c24
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);
}