aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Kconfig9
-rw-r--r--src/include/gpiolib.h47
-rw-r--r--src/lib/Makefile.inc1
-rw-r--r--src/lib/tristate_gpios.c79
-rw-r--r--src/mainboard/google/nyan_big/boardid.c8
-rw-r--r--src/mainboard/google/nyan_blaze/boardid.c8
-rw-r--r--src/soc/nvidia/tegra/gpio.c68
-rw-r--r--src/soc/nvidia/tegra/gpio.h23
-rw-r--r--src/soc/qualcomm/ipq806x/include/gpio.h2
9 files changed, 155 insertions, 90 deletions
diff --git a/src/Kconfig b/src/Kconfig
index 26141fe3a2..25184eb887 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -1122,6 +1122,13 @@ config DEBUG_COVERAGE
If enabled, the code coverage hooks in coreboot will output some
information about the coverage data that is dumped.
+config TERTIARY_BOARD_ID
+ bool "Interpret board ID GPIOs as tertiary inputs"
+ default n
+ help
+ Consider each GPIO as being in one of three states: pulled down (0),
+ pulled up (1), or not connected (2)
+
endmenu
# These probably belong somewhere else, but they are needed somewhere.
@@ -1184,4 +1191,4 @@ config MAX_REBOOT_CNT
help
Internal option that sets the maximum number of bootblock executions allowed
with the normal image enabled before assuming the normal image is defective
- and switching to the fallback image. \ No newline at end of file
+ and switching to the fallback image.
diff --git a/src/include/gpiolib.h b/src/include/gpiolib.h
new file mode 100644
index 0000000000..daec3b66bd
--- /dev/null
+++ b/src/include/gpiolib.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SRC_INCLUDE_GPIOLIB_H__
+#define __SRC_INCLUDE_GPIOLIB_H__
+
+/* A generic type, use accessor macros to actually access the hardware. */
+typedef unsigned gpio_t;
+
+/*
+ * Read the value presented by the set of GPIOs, when each pin is interpreted
+ * as a number in 0..2 range depending on the external pullup situation.
+ *
+ * Depending on the third parameter, the return value is either a set of two
+ * bit fields, each representing one GPIO value, or a number where each GPIO is
+ * included multiplied by 3^gpio_num, resulting in a true tertiary value.
+ *
+ */
+int gpio_board_id(gpio_t gpio[], int num_gpio, int tertiary);
+
+/*
+ * The following functions are not provided by the common library, but must be
+ * implemented by the appropriate SOC/board instead.
+ */
+int gpio_get_in_value(gpio_t gpio);
+void gpio_set_out_value(gpio_t gpio, int value);
+void gpio_input_pulldown(gpio_t gpio);
+void gpio_input_pullup(gpio_t gpio);
+void gpio_input(gpio_t gpio);
+
+#endif
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index d1e3a92b21..1e70e2e01a 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -57,6 +57,7 @@ ifeq ($(CONFIG_COMPILER_GCC),y)
romstage-$(CONFIG_ARCH_ROMSTAGE_X86_32) += gcc.c
ramstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
endif
+romstage-$(CONFIG_TERTIARY_BOARD_ID) += tristate_gpios.c
ramstage-y += hardwaremain.c
ramstage-y += selfboot.c
diff --git a/src/lib/tristate_gpios.c b/src/lib/tristate_gpios.c
new file mode 100644
index 0000000000..b1ebbc0f71
--- /dev/null
+++ b/src/lib/tristate_gpios.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <delay.h>
+#include <gpiolib.h>
+
+int gpio_board_id(gpio_t gpio[], int num_gpio, int tertiary)
+{
+ /*
+ * GPIOs which are tied to stronger external pull up or pull down
+ * will stay there regardless of the internal pull up or pull
+ * down setting.
+ *
+ * GPIOs which are floating will go to whatever level they're
+ * internally pulled to.
+ */
+
+ int temp;
+ int index;
+ int id = 0;
+ char value[num_gpio];
+
+ /* Enable internal pull up */
+ for (index = 0; index < num_gpio; ++index)
+ gpio_input_pullup(gpio[index]);
+
+ /* Wait until signals become stable */
+ udelay(10);
+
+ /* Get gpio values at internal pull up */
+ for (index = 0; index < num_gpio; ++index)
+ value[index] = gpio_get_in_value(gpio[index]);
+
+ /* Enable internal pull down */
+ for (index = 0; index < num_gpio; ++index)
+ gpio_input_pulldown(gpio[index]);
+
+ /* Wait until signals become stable */
+ udelay(10);
+
+ /*
+ * Get gpio values at internal pull down.
+ * Compare with gpio pull up value and then
+ * determine a gpio final value/state:
+ * 0: pull down
+ * 1: pull up
+ * 2: floating
+ */
+ for (index = 0; index < num_gpio; ++index) {
+ if (tertiary)
+ id *= 3;
+ else
+ id <<= 2;
+ temp = gpio_get_in_value(gpio[index]);
+ id += ((value[index] ^ temp) << 1) | temp;
+ }
+
+ /* Disable pull up / pull down to conserve power */
+ for (index = 0; index < num_gpio; ++index)
+ gpio_input(gpio[index]);
+
+ return id;
+}
diff --git a/src/mainboard/google/nyan_big/boardid.c b/src/mainboard/google/nyan_big/boardid.c
index c7bd2e6a1d..c79af45812 100644
--- a/src/mainboard/google/nyan_big/boardid.c
+++ b/src/mainboard/google/nyan_big/boardid.c
@@ -29,15 +29,9 @@ uint8_t board_id(void)
if (id < 0) {
gpio_t gpio[] = {GPIO(Q3), GPIO(T1), GPIO(X1), GPIO(X4)};
- int value[ARRAY_SIZE(gpio)];
- gpio_get_in_tristate_values(gpio, ARRAY_SIZE(gpio), value);
+ id = gpio_board_id(gpio, ARRAY_SIZE(gpio), 0);
- /* A gpio state is encoded in every two-bit */
- id = value[0] << 0 |
- value[1] << 2 |
- value[2] << 4 |
- value[3] << 6;
printk(BIOS_SPEW, "Board TRISTATE ID: %#x.\n", id);
}
diff --git a/src/mainboard/google/nyan_blaze/boardid.c b/src/mainboard/google/nyan_blaze/boardid.c
index c7bd2e6a1d..c79af45812 100644
--- a/src/mainboard/google/nyan_blaze/boardid.c
+++ b/src/mainboard/google/nyan_blaze/boardid.c
@@ -29,15 +29,9 @@ uint8_t board_id(void)
if (id < 0) {
gpio_t gpio[] = {GPIO(Q3), GPIO(T1), GPIO(X1), GPIO(X4)};
- int value[ARRAY_SIZE(gpio)];
- gpio_get_in_tristate_values(gpio, ARRAY_SIZE(gpio), value);
+ id = gpio_board_id(gpio, ARRAY_SIZE(gpio), 0);
- /* A gpio state is encoded in every two-bit */
- id = value[0] << 0 |
- value[1] << 2 |
- value[2] << 4 |
- value[3] << 6;
printk(BIOS_SPEW, "Board TRISTATE ID: %#x.\n", id);
}
diff --git a/src/soc/nvidia/tegra/gpio.c b/src/soc/nvidia/tegra/gpio.c
index b10cded12d..17b90aa1d9 100644
--- a/src/soc/nvidia/tegra/gpio.c
+++ b/src/soc/nvidia/tegra/gpio.c
@@ -23,6 +23,7 @@
#include <stddef.h>
#include <stdint.h>
#include <delay.h>
+#include <gpiolib.h>
#include "gpio.h"
#include "pinmux.h"
@@ -175,58 +176,6 @@ int gpio_get_in_value(gpio_t gpio)
return (port & (1 << bit)) != 0;
}
-int gpio_get_in_tristate_values(gpio_t gpio[], int num_gpio, int value[])
-{
- /*
- * GPIOs which are tied to stronger external pull up or pull down
- * will stay there regardless of the internal pull up or pull
- * down setting.
- *
- * GPIOs which are floating will go to whatever level they're
- * internally pulled to.
- */
-
- int temp;
- int index;
-
- /* Enable internal pull up */
- for (index = 0; index < num_gpio; ++index)
- gpio_input_pullup(gpio[index]);
-
- /* Wait until signals become stable */
- udelay(10);
-
- /* Get gpio values at internal pull up */
- for (index = 0; index < num_gpio; ++index)
- value[index] = gpio_get_in_value(gpio[index]);
-
- /* Enable internal pull down */
- for (index = 0; index < num_gpio; ++index)
- gpio_input_pulldown(gpio[index]);
-
- /* Wait until signals become stable */
- udelay(10);
-
- /*
- * Get gpio values at internal pull down.
- * Compare with gpio pull up value and then
- * determine a gpio final value/state:
- * 0: pull down
- * 1: pull up
- * 2: floating
- */
- for (index = 0; index < num_gpio; ++index) {
- temp = gpio_get_in_value(gpio[index]);
- value[index] = ((value[index] ^ temp) << 1) | temp;
- }
-
- /* Disable pull up / pull down to conserve power */
- for (index = 0; index < num_gpio; ++index)
- gpio_input(gpio[index]);
-
- return 0;
-}
-
int gpio_get_int_status(gpio_t gpio)
{
int bit = gpio % GPIO_GPIOS_PER_PORT;
@@ -279,3 +228,18 @@ void gpio_set_int_clear(gpio_t gpio)
offsetof(struct gpio_bank, int_clear),
1 << bit, 1 << bit);
}
+
+void gpio_input_pulldown(gpio_t gpio)
+{
+ __gpio_input(gpio, PINMUX_PULL_DOWN);
+}
+
+void gpio_input_pullup(gpio_t gpio)
+{
+ __gpio_input(gpio, PINMUX_PULL_UP);
+}
+
+void gpio_input(gpio_t gpio)
+{
+ __gpio_input(gpio, PINMUX_PULL_NONE);
+}
diff --git a/src/soc/nvidia/tegra/gpio.h b/src/soc/nvidia/tegra/gpio.h
index 5f6833af79..43f898958e 100644
--- a/src/soc/nvidia/tegra/gpio.h
+++ b/src/soc/nvidia/tegra/gpio.h
@@ -21,12 +21,10 @@
#define __SOC_NVIDIA_TEGRA_GPIO_H__
#include <stdint.h>
+#include <gpiolib.h>
#include "pinmux.h"
-/* Wrapper type for GPIOs. Always use GPIO() macro to generate. */
-typedef u32 gpio_t;
-
#define GPIO_PINMUX_SHIFT 16
#define GPIO(name) ((gpio_t)(GPIO_##name##_INDEX | \
(PINMUX_GPIO_##name << GPIO_PINMUX_SHIFT)))
@@ -46,21 +44,6 @@ static inline void gpio_output_open_drain(gpio_t gpio, int value)
__gpio_output(gpio, value, PINMUX_OPEN_DRAIN);
}
-static inline void gpio_input(gpio_t gpio)
-{
- __gpio_input(gpio, PINMUX_PULL_NONE);
-}
-
-static inline void gpio_input_pulldown(gpio_t gpio)
-{
- __gpio_input(gpio, PINMUX_PULL_DOWN);
-}
-
-static inline void gpio_input_pullup(gpio_t gpio)
-{
- __gpio_input(gpio, PINMUX_PULL_UP);
-}
-
/* Functions to modify specific GPIO control values. */
enum gpio_mode {
@@ -77,12 +60,8 @@ int gpio_get_lock(gpio_t gpio);
void gpio_set_out_enable(gpio_t gpio, int enable);
int gpio_get_out_enable(gpio_t gpio);
-void gpio_set_out_value(gpio_t gpio, int value);
int gpio_get_out_value(gpio_t gpio);
-int gpio_get_in_value(gpio_t gpio);
-int gpio_get_in_tristate_values(gpio_t gpio[], int num_gpio, int value[]);
-
int gpio_get_int_status(gpio_t gpio);
void gpio_set_int_enable(gpio_t gpio, int enable);
diff --git a/src/soc/qualcomm/ipq806x/include/gpio.h b/src/soc/qualcomm/ipq806x/include/gpio.h
index c1cefd4a8b..1f35aa7061 100644
--- a/src/soc/qualcomm/ipq806x/include/gpio.h
+++ b/src/soc/qualcomm/ipq806x/include/gpio.h
@@ -33,7 +33,7 @@
#ifndef __SOC_QUALCOMM_IPQ806X_GPIO_H_
#define __SOC_QUALCOMM_IPQ806X_GPIO_H_
-typedef unsigned int gpio_t;
+#include <gpiolib.h>
#define GPIO_FUNC_ENABLE 1
#define GPIO_FUNC_DISABLE 0