blob: 6b296c057763dc93f64ec8b34b7e5a51da2c02e5 [file] [log] [blame]
Stefan Reinauere1ae4b22012-04-27 23:20:58 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <string.h>
Kyösti Mälkkie3ddee02014-05-03 10:45:28 +030021#include <bootmode.h>
Stefan Reinauere1ae4b22012-04-27 23:20:58 +020022#include <arch/io.h>
Stefan Reinauere1ae4b22012-04-27 23:20:58 +020023#include <device/device.h>
24#include <device/pci.h>
Stefan Reinauere1ae4b22012-04-27 23:20:58 +020025#include <southbridge/intel/bd82x6x/pch.h>
26
27#define GPIO_SPI_WP 68
28#define GPIO_REC_MODE 42
29#define GPIO_DEV_MODE 17
30
31#define FLAG_SPI_WP 0
32#define FLAG_REC_MODE 1
33#define FLAG_DEV_MODE 2
34
35#ifndef __PRE_RAM__
Stefan Reinauer3e4e3032013-03-20 14:08:04 -070036#include <boot/coreboot_tables.h>
Stefan Reinauere1ae4b22012-04-27 23:20:58 +020037
Vadim Bendebury6b3d09e2012-08-28 14:37:57 -070038#define GPIO_COUNT 6
Stefan Reinauere1ae4b22012-04-27 23:20:58 +020039
40void fill_lb_gpios(struct lb_gpios *gpios)
41{
42 device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
43 u16 gen_pmcon_1 = pci_read_config32(dev, GEN_PMCON_1);
44
45 gpios->size = sizeof(*gpios) + (GPIO_COUNT * sizeof(struct lb_gpio));
46 gpios->count = GPIO_COUNT;
47
48 /* Write Protect: GPIO68 = CHP3_SPI_WP */
49 gpios->gpios[0].port = GPIO_SPI_WP;
50 gpios->gpios[0].polarity = ACTIVE_HIGH;
51 gpios->gpios[0].value =
52 (pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1f, 2)),
53 SATA_SP) >> FLAG_SPI_WP) & 1;
54 strncpy((char *)gpios->gpios[0].name,"write protect",
55 GPIO_MAX_NAME_LENGTH);
56
57 /* Recovery: GPIO42 = CHP3_REC_MODE# */
58 gpios->gpios[1].port = GPIO_REC_MODE;
59 gpios->gpios[1].polarity = ACTIVE_LOW;
60 gpios->gpios[1].value = !get_recovery_mode_switch();
61 strncpy((char *)gpios->gpios[1].name,"recovery", GPIO_MAX_NAME_LENGTH);
62
63 /* Developer: GPIO17 = KBC3_DVP_MODE */
64 gpios->gpios[2].port = GPIO_DEV_MODE;
65 gpios->gpios[2].polarity = ACTIVE_HIGH;
66 gpios->gpios[2].value = get_developer_mode_switch();
67 strncpy((char *)gpios->gpios[2].name,"developer", GPIO_MAX_NAME_LENGTH);
68
69 /* Hard code the lid switch GPIO to open. */
70 gpios->gpios[3].port = 100;
71 gpios->gpios[3].polarity = ACTIVE_HIGH;
72 gpios->gpios[3].value = 1;
73 strncpy((char *)gpios->gpios[3].name,"lid", GPIO_MAX_NAME_LENGTH);
74
75 /* Power Button */
76 gpios->gpios[4].port = 101;
77 gpios->gpios[4].polarity = ACTIVE_LOW;
78 gpios->gpios[4].value = (gen_pmcon_1 >> 9) & 1;
79 strncpy((char *)gpios->gpios[4].name,"power", GPIO_MAX_NAME_LENGTH);
Vadim Bendebury6b3d09e2012-08-28 14:37:57 -070080
81 /* Did we load the VGA Option ROM? */
82 gpios->gpios[5].port = -1; /* Indicate that this is a pseudo GPIO */
83 gpios->gpios[5].polarity = ACTIVE_HIGH;
Kyösti Mälkkiab56b3b2013-11-28 16:44:51 +020084 gpios->gpios[5].value = gfx_get_init_done();
Vadim Bendebury6b3d09e2012-08-28 14:37:57 -070085 strncpy((char *)gpios->gpios[5].name,"oprom", GPIO_MAX_NAME_LENGTH);
Stefan Reinauere1ae4b22012-04-27 23:20:58 +020086}
87#endif
88
89int get_developer_mode_switch(void)
90{
91 device_t dev;
92#ifdef __PRE_RAM__
93 dev = PCI_DEV(0, 0x1f, 2);
94#else
95 dev = dev_find_slot(0, PCI_DEVFN(0x1f, 2));
96#endif
97 return (pci_read_config32(dev, SATA_SP) >> FLAG_DEV_MODE) & 1;
98}
99
100int get_recovery_mode_switch(void)
101{
102 device_t dev;
103#ifdef __PRE_RAM__
104 dev = PCI_DEV(0, 0x1f, 2);
105#else
106 dev = dev_find_slot(0, PCI_DEVFN(0x1f, 2));
107#endif
108 return (pci_read_config32(dev, SATA_SP) >> FLAG_REC_MODE) & 1;
109}
110
Kyösti Mälkkie3ddee02014-05-03 10:45:28 +0300111void init_bootmode_straps(void)
Stefan Reinauere1ae4b22012-04-27 23:20:58 +0200112{
Kyösti Mälkkie3ddee02014-05-03 10:45:28 +0300113#ifdef __PRE_RAM__
Stefan Reinauere1ae4b22012-04-27 23:20:58 +0200114 u16 gpio_base = pci_read_config32(PCH_LPC_DEV, GPIO_BASE) & 0xfffe;
115 u32 gp_lvl3 = inl(gpio_base + GP_LVL3);
116 u32 gp_lvl2 = inl(gpio_base + GP_LVL2);
117 u32 gp_lvl = inl(gpio_base + GP_LVL);
118 u32 flags = 0;
119
120 /* Write Protect: GPIO68 = CHP3_SPI_WP, active high */
121 if (gp_lvl3 & (1 << (GPIO_SPI_WP-64)))
122 flags |= (1 << FLAG_SPI_WP);
123 /* Recovery: GPIO42 = CHP3_REC_MODE#, active low */
124 if (!(gp_lvl2 & (1 << (GPIO_REC_MODE-32))))
125 flags |= (1 << FLAG_REC_MODE);
126 /* Developer: GPIO17 = KBC3_DVP_MODE, active high */
127 if (gp_lvl & (1 << GPIO_DEV_MODE))
128 flags |= (1 << FLAG_DEV_MODE);
129
130 pci_write_config32(PCI_DEV(0, 0x1f, 2), SATA_SP, flags);
Stefan Reinauere1ae4b22012-04-27 23:20:58 +0200131#endif
Kyösti Mälkkie3ddee02014-05-03 10:45:28 +0300132}