storm: add code for detecting rec/dev/write protect switches' status

The gpio access code has been moved to a separate file to match other
platforms. Accessor functions are added to read different switches
state. They will be read by verstage, when it is enabled, and by
ramstage, for passing the values to depthcharge.

It is unfortunate that the gpio values are not being cached and can
change by the time CBMEM table is filled, but we have to live with
that for now.

BUG=chrome-os-partner:33756,chrome-os-partner:34161
BRANCH=storm
TEST=none yet.

Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Change-Id: I940b54cd3cf046b94d57d59d370e634a70a8bbeb
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/229426
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Daisuke Nojiri 2014-11-12 14:44:13 -08:00 committed by chrome-internal-fetch
commit 7e15aa281a
3 changed files with 109 additions and 50 deletions

View file

@ -24,6 +24,7 @@ romstage-y += cdp.c
ramstage-y += boardid.c
ramstage-y += cdp.c
ramstage-y += chromeos.c
ramstage-y += mainboard.c
bootblock-y += memlayout.ld

View file

@ -0,0 +1,108 @@
/*
* 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 <boot/coreboot_tables.h>
#include <console/console.h>
#include <delay.h>
#include <gpio.h>
#include <string.h>
#include <vendorcode/google/chromeos/chromeos.h>
#define FAKE_GPIO_NUM -1
struct gpio_desc {
gpio_t gpio_num;
const char *gpio_name;
uint32_t fake_value;
};
/* Actual GPIO switch names */
#define DEVELOPER_GPIO_NAME "developer"
#define RECOVERY_GPIO_NAME "recovery"
#define WRITE_PROTECT_GPIO_NAME "write protect"
static const struct gpio_desc descriptors[] = {
{ 15, DEVELOPER_GPIO_NAME },
{ 16, RECOVERY_GPIO_NAME },
{ 17, WRITE_PROTECT_GPIO_NAME },
{ FAKE_GPIO_NUM, "power", 1 }, /* Power never pressed. */
{ FAKE_GPIO_NUM, "lid", 0 } /* Lid always open. */
};
static void fill_lb_gpio(struct lb_gpio *pgpio, const struct gpio_desc *pdesc)
{
gpio_t gpio_num = pdesc->gpio_num;
pgpio->port = gpio_num;
if (gpio_num == FAKE_GPIO_NUM) {
pgpio->value = pdesc->fake_value;
} else {
gpio_tlmm_config_set(gpio_num, GPIO_FUNC_DISABLE,
GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
udelay(10); /* Should be enough to settle. */
pgpio->value = gpio_get(gpio_num);
}
pgpio->polarity = ACTIVE_LOW;
strncpy((char *)pgpio->name, pdesc->gpio_name, sizeof(pgpio->name));
printk(BIOS_INFO, "%s: %s: port %d value %d\n",
__func__, pgpio->name, pgpio->port, pgpio->value);
}
void fill_lb_gpios(struct lb_gpios *gpios)
{
int i;
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
fill_lb_gpio(gpios->gpios + i, descriptors + i);
gpios->size = sizeof(*gpios) + sizeof(struct lb_gpio) * i;
gpios->count = i;
}
static int get_switch_value(const char *switch_name)
{
int i;
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
if (!strcmp(descriptors[i].gpio_name, switch_name)) {
struct lb_gpio gpio;
fill_lb_gpio(&gpio, descriptors + i);
return gpio.value ^ !gpio.polarity;
}
return -1;
}
int get_developer_mode_switch(void)
{
return get_switch_value(DEVELOPER_GPIO_NAME);
}
int get_recovery_mode_switch(void)
{
return get_switch_value(RECOVERY_GPIO_NAME);
}
int get_write_protect_state(void)
{
return get_switch_value(WRITE_PROTECT_GPIO_NAME);
}

View file

@ -20,13 +20,11 @@
#include <arch/cache.h>
#include <boardid.h>
#include <boot/coreboot_tables.h>
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <gpio.h>
#include <soc/clock.h>
#include <soc/usb.h>
#include <string.h>
#include <symbols.h>
#include <vendorcode/google/chromeos/chromeos.h>
@ -145,51 +143,3 @@ void lb_board(struct lb_header *header)
/* Retrieve the switch interface MAC addressses. */
lb_table_add_macs_from_vpd(header);
}
#define FAKE_GPIO_NUM -1
struct gpio_desc {
gpio_t gpio_num;
const char *gpio_name;
uint32_t fake_value;
};
static const struct gpio_desc descriptors[] = {
{ 15, "developer" },
{ 16, "recovery" },
{ 17, "write protect" },
{ FAKE_GPIO_NUM, "power", 1 }, /* Power never pressed. */
{ FAKE_GPIO_NUM, "lid", 0 } /* Lid always open. */
};
static void fill_lb_gpio(struct lb_gpio *pgpio, const struct gpio_desc *pdesc)
{
gpio_t gpio_num = pdesc->gpio_num;
pgpio->port = gpio_num;
if (gpio_num == FAKE_GPIO_NUM) {
pgpio->value = pdesc->fake_value;
} else {
gpio_tlmm_config_set(gpio_num, GPIO_FUNC_DISABLE,
GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
udelay(10); /* Should be enough to settle. */
pgpio->value = gpio_get(gpio_num);
}
pgpio->polarity = ACTIVE_LOW;
strncpy((char *)pgpio->name, pdesc->gpio_name, sizeof(pgpio->name));
printk(BIOS_INFO, "%s: %s: port %d value %d\n",
__func__, pgpio->name, pgpio->port, pgpio->value);
}
void fill_lb_gpios(struct lb_gpios *gpios)
{
int i;
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
fill_lb_gpio(gpios->gpios + i, descriptors + i);
gpios->size = sizeof(*gpios) + sizeof(struct lb_gpio) * i;
gpios->count = i;
}