9 changes: 5 additions & 4 deletions src/cpu/x86/mp_init.c
Expand Up @@ -18,6 +18,7 @@
#include <stdint.h>
#include <rmodule.h>
#include <arch/cpu.h>
#include <commonlib/helpers.h>
#include <cpu/cpu.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/cache.h>
Expand Down Expand Up @@ -229,11 +230,11 @@ static void asmlinkage ap_init(unsigned int cpu)

static void setup_default_sipi_vector_params(struct sipi_params *sp)
{
sp->gdt = (uint32_t)&gdt;
sp->gdtlimit = (uint32_t)&gdt_end - (u32)&gdt - 1;
sp->idt_ptr = (uint32_t)&idtarg;
sp->gdt = (uintptr_t)&gdt;
sp->gdtlimit = (uintptr_t)&gdt_end - (uintptr_t)&gdt - 1;
sp->idt_ptr = (uintptr_t)&idtarg;
sp->stack_size = CONFIG_STACK_SIZE;
sp->stack_top = (uint32_t)&_estack;
sp->stack_top = ALIGN_DOWN((uintptr_t)&_estack, CONFIG_STACK_SIZE);
/* Adjust the stack top to take into account cpu_info. */
sp->stack_top -= sizeof(struct cpu_info);
}
Expand Down
1 change: 0 additions & 1 deletion src/cpu/x86/pae/pgtbl.c
Expand Up @@ -20,7 +20,6 @@
#include <cpu/x86/cr.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/pae.h>
#include <rules.h>
#include <string.h>
#include <symbols.h>

Expand Down
79 changes: 43 additions & 36 deletions src/device/pci_device.c
Expand Up @@ -989,33 +989,33 @@ static void set_pci_ops(struct device *dev)
/**
* See if we have already allocated a device structure for a given devfn.
*
* Given a linked list of PCI device structures and a devfn number, find the
* device structure correspond to the devfn, if present. This function also
* removes the device structure from the linked list.
* Given a PCI bus structure and a devfn number, find the device structure
* corresponding to the devfn, if present. Then move the device structure
* as the last child on the bus.
*
* @param list The device structure list.
* @param bus Pointer to the bus structure.
* @param devfn A device/function number.
* @return Pointer to the device structure found or NULL if we have not
* allocated a device for this devfn yet.
*/
static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
static struct device *pci_scan_get_dev(struct bus *bus, unsigned int devfn)
{
struct device *dev;

dev = 0;
for (; *list; list = &(*list)->sibling) {
if ((*list)->path.type != DEVICE_PATH_PCI) {
struct device *dev, **prev;

prev = &bus->children;
for (dev = bus->children; dev; dev = dev->sibling) {
if (dev->path.type == DEVICE_PATH_PCI) {
if (dev->path.pci.devfn == devfn) {
/* Unlink from the list. */
*prev = dev->sibling;
dev->sibling = NULL;
break;
}
} else {
printk(BIOS_ERR, "child %s not a PCI device\n",
dev_path(*list));
continue;
}
if ((*list)->path.pci.devfn == devfn) {
/* Unlink from the list. */
dev = *list;
*list = (*list)->sibling;
dev->sibling = NULL;
break;
dev_path(dev));
}
prev = &dev->sibling;
}

/*
Expand All @@ -1027,15 +1027,15 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
if (dev) {
struct device *child;

/* Find the last child of our parent. */
for (child = dev->bus->children; child && child->sibling;)
/* Find the last child on the bus. */
for (child = bus->children; child && child->sibling;)
child = child->sibling;

/* Place the device on the list of children of its parent. */
/* Place the device as last on the bus. */
if (child)
child->sibling = dev;
else
dev->bus->children = dev;
bus->children = dev;
}

return dev;
Expand Down Expand Up @@ -1180,7 +1180,8 @@ void pci_scan_bus(struct bus *bus, unsigned min_devfn,
unsigned max_devfn)
{
unsigned int devfn;
struct device *old_devices;
struct device *dev, **prev;
int once = 0;

printk(BIOS_DEBUG, "PCI: pci_scan_bus for bus %02x\n", bus->secondary);

Expand All @@ -1193,20 +1194,15 @@ void pci_scan_bus(struct bus *bus, unsigned min_devfn,
max_devfn=0xff;
}

old_devices = bus->children;
bus->children = NULL;

post_code(0x24);

/*
* Probe all devices/functions on this bus with some optimization for
* non-existence and single function devices.
*/
for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
struct device *dev;

/* First thing setup the device structure. */
dev = pci_scan_get_dev(&old_devices, devfn);
dev = pci_scan_get_dev(bus, devfn);

/* See if a device is present and setup the device structure. */
dev = pci_probe_dev(dev, bus, devfn);
Expand All @@ -1228,15 +1224,26 @@ void pci_scan_bus(struct bus *bus, unsigned min_devfn,
* Warn if any leftover static devices are are found.
* There's probably a problem in devicetree.cb.
*/
if (old_devices) {
struct device *left;
printk(BIOS_WARNING, "PCI: Left over static devices:\n");
for (left = old_devices; left; left = left->sibling)
printk(BIOS_WARNING, "%s\n", dev_path(left));

printk(BIOS_WARNING, "PCI: Check your devicetree.cb.\n");
prev = &bus->children;
for (dev = bus->children; dev; dev = dev->sibling) {
/* If we read valid vendor id, it is not leftover device. */
if (dev->vendor != 0) {
prev = &dev->sibling;
continue;
}

/* Unlink it from list. */
*prev = dev->sibling;

if (!once++)
printk(BIOS_WARNING, "PCI: Leftover static devices:\n");
printk(BIOS_WARNING, "%s\n", dev_path(dev));
}

if (once)
printk(BIOS_WARNING, "PCI: Check your devicetree.cb.\n");

/*
* For all children that implement scan_bus() (i.e. bridges)
* scan the bus behind that child.
Expand Down
2 changes: 1 addition & 1 deletion src/device/pci_ops_mmconf.c
Expand Up @@ -15,7 +15,7 @@
#include <device/pci.h>
#include <device/pci_ops.h>

#if !defined(CONFIG_MMCONF_BASE_ADDRESS) || !CONFIG_MMCONF_BASE_ADDRESS
#if (CONFIG_MMCONF_BASE_ADDRESS == 0)
#error "CONFIG_MMCONF_BASE_ADDRESS needs to be non-zero!"
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/elog/boot_count.c
Expand Up @@ -30,7 +30,7 @@
# include "option_table.h"
# define BOOT_COUNT_CMOS_OFFSET (CMOS_VSTART_boot_count_offset >> 3)
#else
# if defined(CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET) && CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET
# if (CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET != 0)
# define BOOT_COUNT_CMOS_OFFSET CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET
# else
# error "Must configure CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET"
Expand Down
15 changes: 12 additions & 3 deletions src/drivers/generic/adau7002/adau7002.c
Expand Up @@ -29,6 +29,9 @@

static void adau7002_fill_ssdt(struct device *dev)
{
struct drivers_generic_adau7002_config *config;
struct acpi_dp *dp;

if (!dev || !dev->enabled)
return;

Expand All @@ -45,6 +48,12 @@ static void adau7002_fill_ssdt(struct device *dev)
acpigen_write_name_string("_DDN", dev->chip_ops->name);
acpigen_write_STA(acpi_device_status(dev));

/* _DSD for devicetree properties */
config = dev->chip_info;
dp = acpi_dp_new_table("_DSD");
acpi_dp_add_integer(dp, "wakeup-delay-ms", config->wakeup_delay);
acpi_dp_write(dp);

acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */

Expand All @@ -63,8 +72,8 @@ static struct device_operations adau7002_ops = {
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &adau7002_acpi_name,
.acpi_fill_ssdt_generator = &adau7002_fill_ssdt,
.acpi_name = adau7002_acpi_name,
.acpi_fill_ssdt_generator = adau7002_fill_ssdt,
#endif
};

Expand All @@ -75,5 +84,5 @@ static void adau7002_enable(struct device *dev)

struct chip_operations drivers_generic_adau7002_ops = {
CHIP_NAME("Analog Digital DMIC")
.enable_dev = &adau7002_enable
.enable_dev = adau7002_enable
};
2 changes: 2 additions & 0 deletions src/drivers/generic/adau7002/chip.h
Expand Up @@ -17,6 +17,8 @@
#define __I2C_GENERIC_ADAU7002_CHIP_H__

struct drivers_generic_adau7002_config {
/* Delay */
unsigned int wakeup_delay;
};

#endif /* __I2C_GENERIC_ADAU7002_CHIP_H__ */
6 changes: 3 additions & 3 deletions src/drivers/generic/generic/generic.c
Expand Up @@ -83,8 +83,8 @@ static struct device_operations generic_dev_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &generic_dev_acpi_name,
.acpi_fill_ssdt_generator = &generic_dev_fill_ssdt_generator,
.acpi_name = generic_dev_acpi_name,
.acpi_fill_ssdt_generator = generic_dev_fill_ssdt_generator,
};

static void generic_dev_enable(struct device *dev)
Expand All @@ -94,5 +94,5 @@ static void generic_dev_enable(struct device *dev)

struct chip_operations drivers_generic_generic_ops = {
CHIP_NAME("Generic Device")
.enable_dev = &generic_dev_enable
.enable_dev = generic_dev_enable
};
9 changes: 9 additions & 0 deletions src/drivers/generic/gpio_keys/chip.h
Expand Up @@ -30,6 +30,13 @@ enum {
SW_PEN_INSERTED = 0xf,
};

/* Trigger for wakeup event action */
enum {
EV_ACT_ANY,
EV_ACT_ASSERTED,
EV_ACT_DEASSERTED,
};

/* Details of the child node defining key */
struct key_info {
/* Device name of the child node - Mandatory */
Expand All @@ -47,6 +54,8 @@ struct key_info {
bool is_wakeup_source;
/* Wake GPE */
unsigned int wake;
/* Trigger for Wakeup Event Action as defined in EV_ACT_* enum */
unsigned int wakeup_event_action;
/* Can this key be disabled? */
bool can_be_disabled;
/* Debounce interval time in milliseconds */
Expand Down
12 changes: 8 additions & 4 deletions src/drivers/generic/gpio_keys/gpio_keys.c
Expand Up @@ -43,8 +43,12 @@ static struct acpi_dp *gpio_keys_add_child_node(
if (key->is_wakeup_source)
acpi_dp_add_integer(dsd, "wakeup-source",
key->is_wakeup_source);
if (key->wake)
if (key->wake) {
acpigen_write_PRW(key->wake, 3);
acpi_dp_add_integer(dsd, "wakeup-event-action",
key->wakeup_event_action);
}

if (key->can_be_disabled)
acpi_dp_add_integer(dsd, "linux,can-disable",
key->can_be_disabled);
Expand Down Expand Up @@ -116,8 +120,8 @@ static struct device_operations gpio_keys_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &gpio_keys_acpi_name,
.acpi_fill_ssdt_generator = &gpio_keys_fill_ssdt_generator,
.acpi_name = gpio_keys_acpi_name,
.acpi_fill_ssdt_generator = gpio_keys_fill_ssdt_generator,
};

static void gpio_keys_enable(struct device *dev)
Expand All @@ -127,5 +131,5 @@ static void gpio_keys_enable(struct device *dev)

struct chip_operations drivers_generic_gpio_keys_ops = {
CHIP_NAME("GPIO Keys")
.enable_dev = &gpio_keys_enable
.enable_dev = gpio_keys_enable
};
6 changes: 3 additions & 3 deletions src/drivers/generic/gpio_regulator/gpio_regulator.c
Expand Up @@ -75,8 +75,8 @@ static struct device_operations gpio_regulator_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &gpio_regulator_acpi_name,
.acpi_fill_ssdt_generator = &gpio_regulator_fill_ssdt_generator,
.acpi_name = gpio_regulator_acpi_name,
.acpi_fill_ssdt_generator = gpio_regulator_fill_ssdt_generator,
};

static void gpio_regulator_enable(struct device *dev)
Expand All @@ -86,5 +86,5 @@ static void gpio_regulator_enable(struct device *dev)

struct chip_operations drivers_generic_gpio_regulator_ops = {
CHIP_NAME("GPIO Regulator")
.enable_dev = &gpio_regulator_enable
.enable_dev = gpio_regulator_enable
};
6 changes: 3 additions & 3 deletions src/drivers/generic/max98357a/max98357a.c
Expand Up @@ -77,8 +77,8 @@ static struct device_operations max98357a_ops = {
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &max98357a_acpi_name,
.acpi_fill_ssdt_generator = &max98357a_fill_ssdt,
.acpi_name = max98357a_acpi_name,
.acpi_fill_ssdt_generator = max98357a_fill_ssdt,
#endif
};

Expand All @@ -105,5 +105,5 @@ static void max98357a_enable(struct device *dev)

struct chip_operations drivers_generic_max98357a_ops = {
CHIP_NAME("Maxim Integrated 98357A Amplifier")
.enable_dev = &max98357a_enable
.enable_dev = max98357a_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/da7219/da7219.c
Expand Up @@ -114,8 +114,8 @@ static struct device_operations da7219_ops = {
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &da7219_acpi_name,
.acpi_fill_ssdt_generator = &da7219_fill_ssdt,
.acpi_name = da7219_acpi_name,
.acpi_fill_ssdt_generator = da7219_fill_ssdt,
#endif
};

Expand All @@ -126,5 +126,5 @@ static void da7219_enable(struct device *dev)

struct chip_operations drivers_i2c_da7219_ops = {
CHIP_NAME("Dialog Semiconductor DA7219 Audio Codec")
.enable_dev = &da7219_enable
.enable_dev = da7219_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/generic/generic.c
Expand Up @@ -193,8 +193,8 @@ static struct device_operations i2c_generic_ops = {
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &i2c_generic_acpi_name,
.acpi_fill_ssdt_generator = &i2c_generic_fill_ssdt_generator,
.acpi_name = i2c_generic_acpi_name,
.acpi_fill_ssdt_generator = i2c_generic_fill_ssdt_generator,
#endif
};

Expand Down Expand Up @@ -228,5 +228,5 @@ static void i2c_generic_enable(struct device *dev)

struct chip_operations drivers_i2c_generic_ops = {
CHIP_NAME("I2C Device")
.enable_dev = &i2c_generic_enable
.enable_dev = i2c_generic_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/hid/hid.c
Expand Up @@ -51,8 +51,8 @@ static struct device_operations i2c_hid_ops = {
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &i2c_hid_acpi_name,
.acpi_fill_ssdt_generator = &i2c_hid_fill_ssdt_generator,
.acpi_name = i2c_hid_acpi_name,
.acpi_fill_ssdt_generator = i2c_hid_fill_ssdt_generator,
#endif
};

Expand All @@ -69,5 +69,5 @@ static void i2c_hid_enable(struct device *dev)

struct chip_operations drivers_i2c_hid_ops = {
CHIP_NAME("I2C HID Device")
.enable_dev = &i2c_hid_enable
.enable_dev = i2c_hid_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/max98373/max98373.c
Expand Up @@ -91,8 +91,8 @@ static struct device_operations max98373_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &max98373_acpi_name,
.acpi_fill_ssdt_generator = &max98373_fill_ssdt,
.acpi_name = max98373_acpi_name,
.acpi_fill_ssdt_generator = max98373_fill_ssdt,
};

static void max98373_enable(struct device *dev)
Expand All @@ -108,5 +108,5 @@ static void max98373_enable(struct device *dev)

struct chip_operations drivers_i2c_max98373_ops = {
CHIP_NAME("Maxim MAX98373 Codec")
.enable_dev = &max98373_enable
.enable_dev = max98373_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/max98927/max98927.c
Expand Up @@ -87,8 +87,8 @@ static struct device_operations max98927_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &max98927_acpi_name,
.acpi_fill_ssdt_generator = &max98927_fill_ssdt,
.acpi_name = max98927_acpi_name,
.acpi_fill_ssdt_generator = max98927_fill_ssdt,
};

static void max98927_enable(struct device *dev)
Expand All @@ -104,5 +104,5 @@ static void max98927_enable(struct device *dev)

struct chip_operations drivers_i2c_max98927_ops = {
CHIP_NAME("Maxim MAX98927 Codec")
.enable_dev = &max98927_enable
.enable_dev = max98927_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/nau8825/nau8825.c
Expand Up @@ -103,8 +103,8 @@ static struct device_operations nau8825_ops = {
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &nau8825_acpi_name,
.acpi_fill_ssdt_generator = &nau8825_fill_ssdt,
.acpi_name = nau8825_acpi_name,
.acpi_fill_ssdt_generator = nau8825_fill_ssdt,
#endif
};

Expand All @@ -115,5 +115,5 @@ static void nau8825_enable(struct device *dev)

struct chip_operations drivers_i2c_nau8825_ops = {
CHIP_NAME("Nuvoton NAU8825 Codec")
.enable_dev = &nau8825_enable
.enable_dev = nau8825_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/rt5663/rt5663.c
Expand Up @@ -91,8 +91,8 @@ static struct device_operations rt5663_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &rt5663_acpi_name,
.acpi_fill_ssdt_generator = &rt5663_fill_ssdt,
.acpi_name = rt5663_acpi_name,
.acpi_fill_ssdt_generator = rt5663_fill_ssdt,
};

static void rt5663_enable(struct device *dev)
Expand All @@ -102,5 +102,5 @@ static void rt5663_enable(struct device *dev)

struct chip_operations drivers_i2c_rt5663_ops = {
CHIP_NAME("Realtek RT5663 Codec")
.enable_dev = &rt5663_enable
.enable_dev = rt5663_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/sx9310/sx9310.c
Expand Up @@ -85,8 +85,8 @@ static struct device_operations i2c_sx9310_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &i2c_sx9310_acpi_name,
.acpi_fill_ssdt_generator = &i2c_sx9310_fill_ssdt,
.acpi_name = i2c_sx9310_acpi_name,
.acpi_fill_ssdt_generator = i2c_sx9310_fill_ssdt,
};

static void i2c_sx9310_enable(struct device *dev)
Expand All @@ -106,5 +106,5 @@ static void i2c_sx9310_enable(struct device *dev)

struct chip_operations drivers_i2c_sx9310_ops = {
CHIP_NAME(I2C_SX9310_ACPI_NAME)
.enable_dev = &i2c_sx9310_enable
.enable_dev = i2c_sx9310_enable
};
6 changes: 3 additions & 3 deletions src/drivers/i2c/tpm/chip.c
Expand Up @@ -78,8 +78,8 @@ static struct device_operations i2c_tpm_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &i2c_tpm_acpi_name,
.acpi_fill_ssdt_generator = &i2c_tpm_fill_ssdt,
.acpi_name = i2c_tpm_acpi_name,
.acpi_fill_ssdt_generator = i2c_tpm_fill_ssdt,
};

static void i2c_tpm_enable(struct device *dev)
Expand All @@ -95,5 +95,5 @@ static void i2c_tpm_enable(struct device *dev)

struct chip_operations drivers_i2c_tpm_ops = {
CHIP_NAME("I2C TPM")
.enable_dev = &i2c_tpm_enable
.enable_dev = i2c_tpm_enable
};
50 changes: 39 additions & 11 deletions src/drivers/i2c/tpm/cr50.c
Expand Up @@ -456,10 +456,44 @@ int tpm_vendor_probe(unsigned int bus, uint32_t addr)
return 0;
}

static int cr50_i2c_probe(struct tpm_chip *chip, uint32_t *did_vid)
{
int retries;

/*
* 150 ms should be enough to synchronize with the TPM even under the
* worst nested reset request conditions. In vast majority of cases
* there would be no wait at all.
*/
printk(BIOS_INFO, "Probing TPM I2C: ");

for (retries = 15; retries > 0; retries--) {
int rc;

rc = cr50_i2c_read(chip, TPM_DID_VID(0), (uint8_t *)did_vid, 4);

/* Exit once DID and VID verified */
if (!rc && (*did_vid == CR50_DID_VID)) {
printk(BIOS_INFO, "done! DID_VID 0x%08x\n", *did_vid);
return 0;
}

/* TPM might be resetting, let's retry in a bit. */
mdelay(10);
printk(BIOS_INFO, ".");
}

/*
* I2C reads failed, or the DID and VID didn't match
*/
printk(BIOS_ERR, "DID_VID 0x%08x not recognized\n", *did_vid);
return -1;
}

int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
{
struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev);
uint32_t vendor;
uint32_t did_vid = 0;

if (dev_addr == 0) {
printk(BIOS_ERR, "%s: missing device address\n", __func__);
Expand All @@ -471,24 +505,18 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)

cr50_vendor_init(chip);

if (cr50_i2c_probe(chip, &did_vid))
return -1;

if (ENV_VERSTAGE || ENV_BOOTBLOCK)
if (process_reset(chip))
return -1;

if (claim_locality(chip))
return -1;

/* Read four bytes from DID_VID register */
if (cr50_i2c_read(chip, TPM_DID_VID(0), (uint8_t *)&vendor, 4) < 0)
return -1;

if (vendor != CR50_DID_VID) {
printk(BIOS_DEBUG, "Vendor ID 0x%08x not recognized\n", vendor);
return -1;
}

printk(BIOS_DEBUG, "cr50 TPM 2.0 (i2c %u:0x%02x id 0x%x)\n",
bus, dev_addr, vendor >> 16);
bus, dev_addr, did_vid >> 16);

chip->is_open = 1;
return 0;
Expand Down
21 changes: 21 additions & 0 deletions src/drivers/intel/fsp1_0/Kconfig
Expand Up @@ -34,6 +34,27 @@ config DCACHE_RAM_SIZE
hex
default 0x4000

config FSP_1_0_DEBUG_LEVEL
int "FSP debug level (0-3)"
default 0
range 0 3
help
Select the debug level, where:
0: DISABLED
1: MINIMUM
2: NORMAL
3: MAXIMUM

config FSP_HEADER_PATH
string "Location of FSP headers"
help
The path to headers files that are released with the FSP binary.

config FSP_SRC_PATH
string "Additional FSP source file"
help
Additional source files that are released with the FSP binary.

if HAVE_FSP_BIN

config FSP_FILE
Expand Down
8 changes: 8 additions & 0 deletions src/drivers/intel/fsp1_0/Makefile.inc
Expand Up @@ -47,4 +47,12 @@ mrc.cache-type := mrc_cache
endif
endif

ifneq ($(call strip_quotes,$(CONFIG_FSP_SRC_PATH)),)
ramstage-y += $(call strip_quotes,$(CONFIG_FSP_SRC_PATH))
endif

ifneq ($(call strip_quotes,$(CONFIG_FSP_HEADER_PATH)),)
CPPFLAGS_common += -I$(CONFIG_FSP_HEADER_PATH)
endif

endif
4 changes: 0 additions & 4 deletions src/drivers/intel/fsp1_1/Kconfig
Expand Up @@ -86,10 +86,6 @@ config USE_GENERIC_FSP_CAR_INC
The chipset can select this to use a generic cache_as_ram.inc file
that should be good for all FSP based platforms.

config CHECKLIST_DATA_FILE_LOCATION
string
default "src/vendorcode/intel/fsp/fsp1_1/checklist"

config RESET_ON_INVALID_RAMSTAGE_CACHE
bool "Reset the system on S3 wake when ramstage cache invalid."
default n
Expand Down
1 change: 0 additions & 1 deletion src/drivers/intel/fsp1_1/cache_as_ram.inc
Expand Up @@ -24,7 +24,6 @@
* performs the final stage of initialization.
*/

#include <rules.h>

#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */

Expand Down
29 changes: 28 additions & 1 deletion src/drivers/intel/fsp1_1/car.c
Expand Up @@ -35,6 +35,22 @@ static inline void set_fih_car(FSP_INFO_HEADER *fih)

asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
{
int i;
const int num_guards = 4;
const u32 stack_guard = 0xdeadbeef;
u32 *stack_base;
void *ram_stack;
u32 size;

/* Size of unallocated CAR. */
size = _car_region_end - _car_relocatable_data_end;
size = ALIGN_DOWN(size, 16);

stack_base = (u32 *) (_car_region_end - size);

for (i = 0; i < num_guards; i++)
stack_base[i] = stack_guard;

/* Initialize timestamp book keeping only once. */
timestamp_init(car_params->tsc);

Expand All @@ -48,6 +64,8 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
printk(BIOS_SPEW, "bist: 0x%08x\n", car_params->bist);
printk(BIOS_SPEW, "tsc: 0x%016llx\n", car_params->tsc);

display_mtrrs();

if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE ||
car_params->bootloader_car_end !=
(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)) {
Expand All @@ -64,7 +82,16 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
set_fih_car(car_params->fih);

/* Return new stack value in RAM back to assembly stub. */
return cache_as_ram_stage_main(car_params->fih);
ram_stack = cache_as_ram_stage_main(car_params->fih);

/* Check the stack. */
for (i = 0; i < num_guards; i++) {
if (stack_base[i] == stack_guard)
continue;
printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n");
}

return ram_stack;
}

/* Entry point taken when romstage is called after a separate verstage. */
Expand Down
1 change: 0 additions & 1 deletion src/drivers/intel/fsp1_1/include/fsp/util.h
Expand Up @@ -17,7 +17,6 @@
#ifndef FSP1_1_UTIL_H
#define FSP1_1_UTIL_H

#include <rules.h>
#include <fsp/api.h>
/* Current users expect to get the SoC's FSP definitions by including util.h. */
#include <fsp/soc_binding.h>
Expand Down
4 changes: 0 additions & 4 deletions src/drivers/intel/fsp2_0/Kconfig
Expand Up @@ -146,10 +146,6 @@ config VERIFY_HOBS
Verify that the HOBs required by coreboot are returned by FSP and
that the resource HOBs are in the correct order and position.

config CHECKLIST_DATA_FILE_LOCATION
string
default "src/vendorcode/intel/fsp/fsp2_0/checklist"

config RESET_ON_INVALID_RAMSTAGE_CACHE
bool "Reset the system on S3 wake when ramstage cache invalid."
default n
Expand Down
1 change: 0 additions & 1 deletion src/drivers/intel/fsp2_0/include/fsp/info_header.h
Expand Up @@ -13,7 +13,6 @@
#ifndef _FSP2_0_INFO_HEADER_H_
#define _FSP2_0_INFO_HEADER_H_

#include <rules.h>
#include <stdint.h>
#include <stdlib.h>
#include <types.h>
Expand Down
6 changes: 3 additions & 3 deletions src/drivers/intel/mipi_camera/camera.c
Expand Up @@ -84,8 +84,8 @@ static struct device_operations camera_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &camera_acpi_name,
.acpi_fill_ssdt_generator = &camera_fill_ssdt,
.acpi_name = camera_acpi_name,
.acpi_fill_ssdt_generator = camera_fill_ssdt,
};

static void camera_enable(struct device *dev)
Expand All @@ -95,5 +95,5 @@ static void camera_enable(struct device *dev)

struct chip_operations drivers_intel_mipi_camera_ops = {
CHIP_NAME("Intel MIPI Camera Device")
.enable_dev = &camera_enable
.enable_dev = camera_enable
};
31 changes: 28 additions & 3 deletions src/drivers/intel/wifi/wifi.c
Expand Up @@ -255,9 +255,34 @@ static const char *intel_wifi_acpi_name(const struct device *dev)
}
#endif

static void pci_dev_apply_quirks(struct device *dev)
{
unsigned int cap;
uint16_t val;
struct device *root = dev->bus->dev;

switch (dev->device) {
case PCI_DEVICE_ID_TP_9260_SERIES_WIFI:
cap = pci_find_capability(root, PCI_CAP_ID_PCIE);
/* Check the LTR for root port and enable it */
if (cap) {
val = pci_read_config16(root, cap +
PCI_EXP_DEV_CAP2_OFFSET);
if (val & LTR_MECHANISM_SUPPORT) {
val = pci_read_config16(root, cap +
PCI_EXP_DEV_CTL_STS2_CAP_OFFSET);
val |= LTR_MECHANISM_EN;
pci_write_config16(root, cap +
PCI_EXP_DEV_CTL_STS2_CAP_OFFSET, val);
}
}
}
}

static void wifi_pci_dev_init(struct device *dev)
{
pci_dev_init(dev);
pci_dev_apply_quirks(dev);

if (IS_ENABLED(CONFIG_ELOG)) {
uint32_t val;
Expand All @@ -281,8 +306,8 @@ struct device_operations device_ops = {
#endif
.ops_pci = &pci_ops,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &intel_wifi_acpi_name,
.acpi_fill_ssdt_generator = &intel_wifi_fill_ssdt,
.acpi_name = intel_wifi_acpi_name,
.acpi_fill_ssdt_generator = intel_wifi_fill_ssdt,
#endif
};

Expand Down Expand Up @@ -341,5 +366,5 @@ static void intel_wifi_enable(struct device *dev)

struct chip_operations drivers_intel_wifi_ops = {
CHIP_NAME("Intel WiFi")
.enable_dev = &intel_wifi_enable
.enable_dev = intel_wifi_enable
};
2 changes: 1 addition & 1 deletion src/drivers/lenovo/hybrid_graphics/hybrid_graphics.c
Expand Up @@ -68,5 +68,5 @@ static void lenovo_hybrid_graphics_enable(struct device *dev)

struct chip_operations drivers_lenovo_hybrid_graphics_ops = {
CHIP_NAME("Lenovo hybrid graphics driver")
.enable_dev = &lenovo_hybrid_graphics_enable
.enable_dev = lenovo_hybrid_graphics_enable
};
4 changes: 3 additions & 1 deletion src/drivers/mrc_cache/mrc_cache.c
Expand Up @@ -456,13 +456,15 @@ static int nvm_is_write_protected(void)
/* Apply protection to a range of flash */
static int nvm_protect(const struct region *r)
{
const struct spi_flash *flash = boot_device_spi_flash();

if (!IS_ENABLED(CONFIG_MRC_SETTINGS_PROTECT))
return 0;

if (!IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH))
return 0;

return spi_flash_ctrlr_protect_region(boot_device_spi_flash(), r);
return spi_flash_ctrlr_protect_region(flash, r, WRITE_PROTECT);
}

/* Protect mrc region with a Protected Range Register */
Expand Down
1 change: 0 additions & 1 deletion src/drivers/net/ne2k.c
Expand Up @@ -34,7 +34,6 @@ SMC8416 PIO support added by Andrew Bettison (andrewb@zip.com.au) on 4/3/02
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <rules.h>
#include <stdlib.h>
#include <string.h>
#include <ip_checksum.h>
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/net/r8168.c
Expand Up @@ -347,8 +347,8 @@ static struct device_operations r8168_ops = {
.init = r8168_init,
.scan_bus = 0,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &r8168_net_acpi_name,
.acpi_fill_ssdt_generator = &r8168_net_fill_ssdt,
.acpi_name = r8168_net_acpi_name,
.acpi_fill_ssdt_generator = r8168_net_fill_ssdt,
#endif
};

Expand Down
8 changes: 4 additions & 4 deletions src/drivers/pc80/tpm/tis.c
Expand Up @@ -979,11 +979,11 @@ static const char *lpc_tpm_acpi_name(const struct device *dev)
#endif

static struct device_operations lpc_tpm_ops = {
.read_resources = &lpc_tpm_read_resources,
.set_resources = &lpc_tpm_set_resources,
.read_resources = lpc_tpm_read_resources,
.set_resources = lpc_tpm_set_resources,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.acpi_name = &lpc_tpm_acpi_name,
.acpi_fill_ssdt_generator = &lpc_tpm_fill_ssdt,
.acpi_name = lpc_tpm_acpi_name,
.acpi_fill_ssdt_generator = lpc_tpm_fill_ssdt,
#endif
};

Expand Down
2 changes: 1 addition & 1 deletion src/drivers/ricoh/rce822/rce822.c
Expand Up @@ -51,7 +51,7 @@ static void rce822_set_subsystem(struct device *dev, unsigned int vendor,
}

static struct pci_operations lops_pci = {
.set_subsystem = &rce822_set_subsystem,
.set_subsystem = rce822_set_subsystem,
};

static struct device_operations rce822_ops = {
Expand Down
6 changes: 3 additions & 3 deletions src/drivers/spi/acpi/acpi.c
Expand Up @@ -205,8 +205,8 @@ static struct device_operations spi_acpi_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.acpi_name = &spi_acpi_name,
.acpi_fill_ssdt_generator = &spi_acpi_fill_ssdt_generator,
.acpi_name = spi_acpi_name,
.acpi_fill_ssdt_generator = spi_acpi_fill_ssdt_generator,
};

static void spi_acpi_enable(struct device *dev)
Expand All @@ -216,5 +216,5 @@ static void spi_acpi_enable(struct device *dev)

struct chip_operations drivers_spi_acpi_ops = {
CHIP_NAME("SPI Device")
.enable_dev = &spi_acpi_enable
.enable_dev = spi_acpi_enable
};
74 changes: 73 additions & 1 deletion src/drivers/spi/adesto.c
Expand Up @@ -43,22 +43,62 @@ struct adesto_spi_flash_params {
};

static const struct adesto_spi_flash_params adesto_spi_flash_table[] = {
{
.id = 0x4218,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "AT25SL128A",
},
{
.id = 0x4501,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "AT25DF081A", /* Yes, 81A id < 81 */
},
{
.id = 0x4502,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "AT25DF081",
},
{
.id = 0x4701,
.id = 0x4602,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "AT25DF161",
},
{
.id = 0x4603,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "AT25DL161",
},
{
.id = 0x4700,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "AT25DF321",
},
{
.id = 0x4701,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "AT25DF321A",
},
{
.id = 0x4800,
.l2_page_size = 8,
Expand All @@ -67,6 +107,38 @@ static const struct adesto_spi_flash_params adesto_spi_flash_table[] = {
.nr_blocks = 128,
.name = "AT25DF641",
},
{
.id = 0x8501,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "AT25SF081",
},
{
.id = 0x8600,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "AT25DQ161",
},
{
.id = 0x8601,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "AT25SF161",
},
{
.id = 0x8700,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "AT25DQ321",
},
};

static int adesto_write(const struct spi_flash *flash, u32 offset, size_t len,
Expand Down
64 changes: 64 additions & 0 deletions src/drivers/spi/amic.c
Expand Up @@ -41,6 +41,38 @@ struct amic_spi_flash_params {
};

static const struct amic_spi_flash_params amic_spi_flash_table[] = {
{
.id = 0x2015,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "A25L16PU",
},
{
.id = 0x2025,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "A25L16PT",
},
{
.id = 0x3014,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "A25L080",
},
{
.id = 0x3015,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "A25L016",
},
{
.id = 0x3016,
.l2_page_size = 8,
Expand All @@ -49,6 +81,38 @@ static const struct amic_spi_flash_params amic_spi_flash_table[] = {
.nr_blocks = 64,
.name = "A25L032",
},
{
.id = 0x4014,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "A25LQ080",
},
{
.id = 0x4015,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "A25LQ16",
},
{
.id = 0x4016,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "A25LQ032",
},
{
.id = 0x4017,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 128,
.name = "A25LQ64",
},
};

static int amic_write(const struct spi_flash *flash, u32 offset, size_t len,
Expand Down
43 changes: 43 additions & 0 deletions src/drivers/spi/boot_device_rw_nommap.c
Expand Up @@ -108,3 +108,46 @@ const struct spi_flash *boot_device_spi_flash(void)

return car_get_var_ptr(&sfg);
}

int boot_device_wp_region(struct region_device *rd,
const enum bootdev_prot_type type)
{
uint32_t ctrlr_pr;

/* Ensure boot device has been initialized at least once. */
boot_device_init();

const struct spi_flash *boot_dev = boot_device_spi_flash();

if (boot_dev == NULL)
return -1;

if (type == MEDIA_WP) {
if (spi_flash_is_write_protected(boot_dev,
region_device_region(rd)) != 1) {
return spi_flash_set_write_protected(boot_dev,
region_device_region(rd), true,
SPI_WRITE_PROTECTION_REBOOT);
}

/* Already write protected */
return 0;
}

switch (type) {
case CTRLR_WP:
ctrlr_pr = WRITE_PROTECT;
break;
case CTRLR_RP:
ctrlr_pr = READ_PROTECT;
break;
case CTRLR_RWP:
ctrlr_pr = READ_WRITE_PROTECT;
break;
default:
return -1;
}

return spi_flash_ctrlr_protect_region(boot_dev,
region_device_region(rd), ctrlr_pr);
}
171 changes: 162 additions & 9 deletions src/drivers/spi/eon.c
Expand Up @@ -27,10 +27,27 @@
#define CMD_EN25_DP 0xb9 /* Deep Power-down */
#define CMD_EN25_RES 0xab /* Release from DP, and Read Signature */

#define EON_ID_EN25Q128 0x3018
#define EON_ID_EN25B80 0x2014
#define EON_ID_EN25B16 0x2015
#define EON_ID_EN25B32 0x2016
#define EON_ID_EN25B64 0x2017
#define EON_ID_EN25F80 0x3114
#define EON_ID_EN25F16 0x3115
#define EON_ID_EN25F32 0x3116
#define EON_ID_EN25F64 0x3117
#define EON_ID_EN25Q80 0x3014
#define EON_ID_EN25Q16 0x3015 /* Same as EN25D16 */
#define EON_ID_EN25Q32 0x3016 /* Same as EN25Q32A and EN25Q32B */
#define EON_ID_EN25Q64 0x3017
#define EON_ID_EN25Q128 0x3018
#define EON_ID_EN25QH16 0x7015
#define EON_ID_EN25QH32 0x7016
#define EON_ID_EN25QH64 0x7017
#define EON_ID_EN25QH128 0x7018
#define EON_ID_EN25S80 0x3814
#define EON_ID_EN25S16 0x3815
#define EON_ID_EN25S32 0x3816
#define EON_ID_EN25S64 0x3817
#define EON_ID_EN25F80 0x3114

struct eon_spi_flash_params {
u16 id;
Expand All @@ -43,12 +60,92 @@ struct eon_spi_flash_params {

static const struct eon_spi_flash_params eon_spi_flash_table[] = {
{
.id = EON_ID_EN25Q128,
.id = EON_ID_EN25B80,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 4096,
.name = "EN25Q128",
.nr_sectors = 256,
.name = "EN25B80",
},
{
.id = EON_ID_EN25B16,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 512,
.name = "EN25B16",
},
{
.id = EON_ID_EN25B32,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 1024,
.name = "EN25B32",
},
{
.id = EON_ID_EN25B64,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 2048,
.name = "EN25B64",
},
{
.id = EON_ID_EN25F80,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 256,
.name = "EN25F80",
},
{
.id = EON_ID_EN25F16,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 512,
.name = "EN25F16",
},
{
.id = EON_ID_EN25F32,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 1024,
.name = "EN25F32",
},
{
.id = EON_ID_EN25F64,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 2048,
.name = "EN25F64",
},
{
.id = EON_ID_EN25Q80,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 256,
.name = "EN25Q80(A)",
},
{
.id = EON_ID_EN25Q16,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 512,
.name = "EN25Q16(D16)",
},
{
.id = EON_ID_EN25Q32,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 1024,
.name = "EN25Q32(A/B)",
},
{
.id = EON_ID_EN25Q64,
Expand All @@ -59,20 +156,76 @@ static const struct eon_spi_flash_params eon_spi_flash_table[] = {
.name = "EN25Q64",
},
{
.id = EON_ID_EN25S64,
.id = EON_ID_EN25Q128,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 4096,
.name = "EN25Q128",
},
{
.id = EON_ID_EN25QH16,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 512,
.name = "EN25QH16",
},
{
.id = EON_ID_EN25QH32,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 1024,
.name = "EN25QH32",
},
{
.id = EON_ID_EN25QH64,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 2048,
.name = "EN25S64",
.name = "EN25QH64",
},
{
.id = EON_ID_EN25F80,
.id = EON_ID_EN25QH128,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 4096,
.name = "EN25QH128",
},
{
.id = EON_ID_EN25S80,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 256,
.name = "EN25F80",
.name = "EN25S80",
},
{
.id = EON_ID_EN25S16,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 512,
.name = "EN25S16",
},
{
.id = EON_ID_EN25S32,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 1024,
.name = "EN25S32",
},
{
.id = EON_ID_EN25S64,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_sectors = 2048,
.name = "EN25S64",
},
};

Expand Down
66 changes: 57 additions & 9 deletions src/drivers/spi/gigadevice.c
Expand Up @@ -50,13 +50,21 @@ struct gigadevice_spi_flash_params {
};

static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = {
{
.id = 0x3114,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "GD25T80",
},
{
.id = 0x4014,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "GD25Q80",
.name = "GD25Q80(B)",
},
{
.id = 0x4015,
Expand All @@ -75,20 +83,60 @@ static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = {
.name = "GD25Q32(B)",
},
{
.id = 0x6016,
.id = 0x4017,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "GD25LQ32",
.nr_blocks = 128,
.name = "GD25Q64(B)/GD25B64C",
},
{
.id = 0x4017,
.id = 0x4018,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 128,
.name = "GD25Q64B/GD25B64C",
.nr_blocks = 256,
.name = "GD25Q128(B)",
},
{
.id = 0x4214,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "GD25VQ80C",
},
{
.id = 0x4215,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "GD25VQ16C",
},
{
.id = 0x6014,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "GD25LQ80",
},
{
.id = 0x6015,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "GD25LQ16",
},
{
.id = 0x6016,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "GD25LQ32",
},
{
.id = 0x6017,
Expand All @@ -99,12 +147,12 @@ static const struct gigadevice_spi_flash_params gigadevice_spi_flash_table[] = {
.name = "GD25LQ64C/GD25LB64C",
},
{
.id = 0x4018,
.id = 0x6018,
.l2_page_size = 8,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "GD25Q128(B)",
.name = "GD25LQ128",
},
};

Expand Down
94 changes: 79 additions & 15 deletions src/drivers/spi/macronix.c
Expand Up @@ -80,44 +80,76 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
.name = "MX25L3205D",
},
{
.idcode = 0x5e16,
.idcode = 0x2017,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "MX25L3235D", /* MX25L3225D/MX25L3235D/MX25L3236D/MX25L3237D */
.nr_blocks = 128,
.name = "MX25L6405D",
},
{
.idcode = 0x2536,
.idcode = 0x2018,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "MX25L3239E",
.nr_blocks = 256,
.name = "MX25L12805D",
},
{
.idcode = 0x2017,
.idcode = 0x2019,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 128,
.name = "MX25L6405D",
.nr_blocks = 512,
.name = "MX25L25635F",
},
{
.idcode = 0x2018,
.idcode = 0x201a,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "MX25L12805D",
.nr_blocks = 1024,
.name = "MX66L51235F",
},
{
.idcode = 0x2618,
.idcode = 0x2415,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "MX25L12855E",
.nr_blocks = 32,
.name = "MX25L1635D",
},
{
.idcode = 0x2515,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "MX25L1635E",
},
{
.idcode = 0x2534,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 16,
.name = "MX25U8032E",
},
{
.idcode = 0x2535,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 32,
.name = "MX25U1635E",
},
{
.idcode = 0x2536,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "MX25U3235E",
},
{
.idcode = 0x2537,
Expand All @@ -135,6 +167,38 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
.nr_blocks = 256,
.name = "MX25U12835F",
},
{
.idcode = 0x2539,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 512,
.name = "MX25U25635F",
},
{
.idcode = 0x253a,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 1024,
.name = "MX25U51245G",
},
{
.idcode = 0x2618,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 256,
.name = "MX25L12855E",
},
{
.idcode = 0x5e16,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
.nr_blocks = 64,
.name = "MX25L3235D", /* MX25L3225D/MX25L3236D/MX25L3237D */
},
{
.idcode = 0x9517,
.page_size = 256,
Expand Down
39 changes: 36 additions & 3 deletions src/drivers/spi/spansion.c
Expand Up @@ -39,14 +39,17 @@
#define CMD_S25FLXX_DP 0xb9 /* Deep Power-down */
#define CMD_S25FLXX_RES 0xab /* Release from DP, and Read Signature */

#define SPSN_MANUFACTURER_ID_S25FL116K 0x01
#define SPSN_MANUFACTURER_ID_S25FL_K 0x01
#define SPSN_ID_S25FL008A 0x0213
#define SPSN_ID_S25FL016A 0x0214
#define SPSN_ID_S25FL032A 0x0215
#define SPSN_ID_S25FL064A 0x0216
#define SPSN_ID_S25FL128S 0x0219
#define SPSN_ID_S25FL128P 0x2018
#define SPSN_ID_S25FL208K 0x4014
#define SPSN_ID_S25FL116K 0x4015
#define SPSN_ID_S25FL132K 0x4016
#define SPSN_ID_S25FL164K 0x4017
#define SPSN_EXT_ID_S25FL128P_256KB 0x0300
#define SPSN_EXT_ID_S25FL128P_64KB 0x0301
#define SPSN_EXT_ID_S25FL032P 0x4d00
Expand Down Expand Up @@ -176,10 +179,20 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 256,
.name = "25FS128S",
.name = "S25FS128S",
},
{
.idcode0 = SPSN_MANUFACTURER_ID_S25FL116K,
.idcode0 = SPSN_MANUFACTURER_ID_S25FL_K,
.idcode1 = SPSN_ID_S25FL208K,
.idcode2 = 0,
.identify = identify_123,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 16,
.name = "S25FL208K",
},
{
.idcode0 = SPSN_MANUFACTURER_ID_S25FL_K,
.idcode1 = SPSN_ID_S25FL116K,
.idcode2 = 0,
.identify = identify_123,
Expand All @@ -188,6 +201,26 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
.nr_sectors = 32,
.name = "S25FL116K_16M",
},
{
.idcode0 = SPSN_MANUFACTURER_ID_S25FL_K,
.idcode1 = SPSN_ID_S25FL132K,
.idcode2 = 0,
.identify = identify_123,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 64,
.name = "S25FL132K",
},
{
.idcode0 = SPSN_MANUFACTURER_ID_S25FL_K,
.idcode1 = SPSN_ID_S25FL164K,
.idcode2 = 0,
.identify = identify_123,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 128,
.name = "S25FL164K",
},
};

static int spansion_write(const struct spi_flash *flash, u32 offset, size_t len,
Expand Down
6 changes: 3 additions & 3 deletions src/drivers/spi/spi_flash.c
Expand Up @@ -12,7 +12,6 @@
#include <boot_device.h>
#include <cpu/x86/smm.h>
#include <delay.h>
#include <rules.h>
#include <stdlib.h>
#include <string.h>
#include <spi-generic.h>
Expand Down Expand Up @@ -579,7 +578,8 @@ void lb_spi_flash(struct lb_header *header)


int spi_flash_ctrlr_protect_region(const struct spi_flash *flash,
const struct region *region)
const struct region *region,
const enum ctrlr_prot_type type)
{
const struct spi_ctrlr *ctrlr;
struct region flash_region = { 0 };
Expand All @@ -598,7 +598,7 @@ int spi_flash_ctrlr_protect_region(const struct spi_flash *flash,
return -1;

if (ctrlr->flash_protect)
return ctrlr->flash_protect(flash, region);
return ctrlr->flash_protect(flash, region, type);

return -1;
}
Expand Down
8 changes: 4 additions & 4 deletions src/drivers/spi/spi_flash_internal.h
Expand Up @@ -11,10 +11,10 @@
* is a problem (and well your system already is broken), so err on the side
* of caution in case we're dealing with slower SPI buses and/or processors.
*/
#define CONFIG_SYS_HZ 100
#define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ)
#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ)
#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ)
#define CONF_SYS_HZ 100
#define SPI_FLASH_PROG_TIMEOUT (2 * CONF_SYS_HZ)
#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONF_SYS_HZ)
#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONF_SYS_HZ)

/* Common commands */
#define CMD_READ_ID 0x9f
Expand Down
15 changes: 15 additions & 0 deletions src/drivers/spi/sst.c
Expand Up @@ -77,6 +77,11 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
.nr_sectors = 256,
.name = "SST25VF080B",
.ops = &spi_flash_ops_write_ai,
},{
.idcode1 = 0x80,
.nr_sectors = 256,
.name = "SST25VF080",
.ops = &spi_flash_ops_write_ai,
},{
.idcode1 = 0x41,
.nr_sectors = 512,
Expand Down Expand Up @@ -112,6 +117,16 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
.nr_sectors = 128,
.name = "SST25WF040",
.ops = &spi_flash_ops_write_ai,
},{
.idcode1 = 0x05,
.nr_sectors = 256,
.name = "SST25WF080",
.ops = &spi_flash_ops_write_ai,
},{
.idcode1 = 0x14,
.nr_sectors = 256,
.name = "SST25WF080B",
.ops = &spi_flash_ops_write_ai,
},
};

Expand Down
141 changes: 129 additions & 12 deletions src/drivers/spi/stmicro.c
Expand Up @@ -52,11 +52,24 @@
#define STM_ID_M25P32 0x2016
#define STM_ID_M25P64 0x2017
#define STM_ID_M25P128 0x2018
#define STM_ID_M25PX80 0x7114
#define STM_ID_M25PX16 0x7115
#define STM_ID_M25PX32 0x7116
#define STM_ID_M25PX64 0x7117
#define STM_ID_M25PE80 0x8014
#define STM_ID_M25PE16 0x8015
#define STM_ID_M25PE32 0x8016
#define STM_ID_M25PE64 0x8017
#define STM_ID_N25Q016__3E 0xba15
#define STM_ID_N25Q032__3E 0xba16
#define STM_ID_N25Q128A 0xba18
#define STM_ID_N25Q256 0xba19
#define STM_ID_N25Q064 0xbb17
#define STM_ID_N25Q128 0xbb18
#define STM_ID_N25Q064__3E 0xba17
#define STM_ID_N25Q128__3E 0xba18
#define STM_ID_N25Q256__3E 0xba19
#define STM_ID_N25Q016__1E 0xbb15
#define STM_ID_N25Q032__1E 0xbb16
#define STM_ID_N25Q064__1E 0xbb17
#define STM_ID_N25Q128__1E 0xbb18
#define STM_ID_N25Q256__1E 0xbb19

struct stmicro_spi_flash_params {
u16 device_id;
Expand Down Expand Up @@ -132,6 +145,78 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
.nr_sectors = 64,
.name = "M25P128",
},
{
.device_id = STM_ID_M25PX80,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 16,
.name = "M25PX80",
},
{
.device_id = STM_ID_M25PX16,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 32,
.name = "M25PX16",
},
{
.device_id = STM_ID_M25PX32,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 64,
.name = "M25PX32",
},
{
.device_id = STM_ID_M25PX64,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 128,
.name = "M25PX64",
},
{
.device_id = STM_ID_M25PE80,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 16,
.name = "M25PE80",
},
{
.device_id = STM_ID_M25PE16,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 32,
.name = "M25PE16",
},
{
.device_id = STM_ID_M25PE32,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 64,
.name = "M25PE32",
},
{
.device_id = STM_ID_M25PE64,
.op_erase = CMD_M25PXX_SE,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 128,
.name = "M25PE64",
},
{
.device_id = STM_ID_N25Q016__3E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 512,
.name = "N25Q016..3E",
},
{
.device_id = STM_ID_N25Q032__3E,
.op_erase = CMD_M25PXX_SSE,
Expand All @@ -141,36 +226,68 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
.name = "N25Q032..3E",
},
{
.device_id = STM_ID_N25Q064,
.device_id = STM_ID_N25Q064__3E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 2048,
.name = "N25Q064",
.name = "N25Q064..3E",
},
{
.device_id = STM_ID_N25Q128,
.device_id = STM_ID_N25Q128__3E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 4096,
.name = "N25Q128",
.name = "N25Q128..3E",
},
{
.device_id = STM_ID_N25Q256__3E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 8192,
.name = "N25Q256..3E",
},
{
.device_id = STM_ID_N25Q016__1E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 512,
.name = "N25Q016..1E",
},
{
.device_id = STM_ID_N25Q032__1E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 1024,
.name = "N25Q032..1E",
},
{
.device_id = STM_ID_N25Q064__1E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 2048,
.name = "N25Q064..1E",
},
{
.device_id = STM_ID_N25Q128A,
.device_id = STM_ID_N25Q128__1E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 4096,
.name = "N25Q128A",
.name = "N25Q128..1E",
},
{
.device_id = STM_ID_N25Q256,
.device_id = STM_ID_N25Q256__1E,
.op_erase = CMD_M25PXX_SSE,
.page_size = 256,
.pages_per_sector = 16,
.nr_sectors = 8192,
.name = "N25Q256",
.name = "N25Q256..1E",
},
};

Expand Down
64 changes: 58 additions & 6 deletions src/drivers/spi/winbond.c
Expand Up @@ -108,6 +108,38 @@ struct status_regs {
};

static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
{
.id = 0x2014,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 4,
.name = "W25P80",
},
{
.id = 0x2015,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 5,
.name = "W25P16",
},
{
.id = 0x2016,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 6,
.name = "W25P32",
},
{
.id = 0x3014,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 4,
.name = "W25X80",
},
{
.id = 0x3015,
.l2_page_size_shift = 8,
Expand Down Expand Up @@ -138,15 +170,25 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 4,
.name = "W25Q80",
.name = "W25Q80_V",
},
{
.id = 0x4015,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 5,
.name = "W25Q16",
.name = "W25Q16_V",
.protection_granularity_shift = 16,
.bp_bits = 3,
},
{
.id = 0x6015,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 5,
.name = "W25Q16DW",
.protection_granularity_shift = 16,
.bp_bits = 3,
},
Expand All @@ -156,7 +198,7 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 6,
.name = "W25Q32",
.name = "W25Q32_V",
.protection_granularity_shift = 16,
.bp_bits = 3,
},
Expand All @@ -176,7 +218,7 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 7,
.name = "W25Q64",
.name = "W25Q64_V",
.protection_granularity_shift = 17,
.bp_bits = 3,
},
Expand All @@ -196,7 +238,7 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 8,
.name = "W25Q128",
.name = "W25Q128_V",
.protection_granularity_shift = 18,
.bp_bits = 3,
},
Expand Down Expand Up @@ -226,7 +268,17 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 9,
.name = "W25Q256",
.name = "W25Q256_V",
.protection_granularity_shift = 16,
.bp_bits = 4,
},
{
.id = 0x7019,
.l2_page_size_shift = 8,
.pages_per_sector_shift = 4,
.sectors_per_block_shift = 4,
.nr_blocks_shift = 9,
.name = "W25Q256J",
.protection_granularity_shift = 16,
.bp_bits = 4,
},
Expand Down
1 change: 0 additions & 1 deletion src/drivers/uart/uart8250io.c
Expand Up @@ -14,7 +14,6 @@
* GNU General Public License for more details.
*/

#include <rules.h>
#include <stdlib.h>
#include <arch/early_variables.h>
#include <arch/io.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/uart/uart8250mem.c
Expand Up @@ -19,7 +19,6 @@
#include <console/uart.h>
#include <device/device.h>
#include <delay.h>
#include <rules.h>
#include <stdint.h>
#include "uart8250reg.h"

Expand Down
6 changes: 3 additions & 3 deletions src/drivers/usb/acpi/usb_acpi.c
Expand Up @@ -86,8 +86,8 @@ static struct device_operations usb_acpi_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.scan_bus = &scan_usb_bus,
.acpi_fill_ssdt_generator = &usb_acpi_fill_ssdt_generator,
.scan_bus = scan_usb_bus,
.acpi_fill_ssdt_generator = usb_acpi_fill_ssdt_generator,
};

static void usb_acpi_enable(struct device *dev)
Expand All @@ -97,5 +97,5 @@ static void usb_acpi_enable(struct device *dev)

struct chip_operations drivers_usb_acpi_ops = {
CHIP_NAME("USB ACPI Device")
.enable_dev = &usb_acpi_enable
.enable_dev = usb_acpi_enable
};
79 changes: 49 additions & 30 deletions src/drivers/usb/ehci_debug.c
Expand Up @@ -28,19 +28,20 @@
#include "ehci.h"

struct ehci_debug_info {
void *ehci_base;
void *ehci_debug;
u64 ehci_base;
u64 ehci_debug;

struct dbgp_pipe ep_pipe[DBGP_MAX_ENDPOINTS];
};
} __packed;

#if IS_ENABLED(CONFIG_DEBUG_USBDEBUG)
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug);
static int dbgp_enabled(void);
#if IS_ENABLED(CONFIG_DEBUG_CONSOLE_INIT)
/* When selected, you can debug the connection of usbdebug dongle.
* EHCI port register bits and USB packets are dumped on console,
* assuming some other console already works.
*/
# define dprintk(LEVEL, args...) \
do { if (!dbgp_enabled()) printk(LEVEL, ##args); } while (0)
#else
# define dbgp_print_data(x) do {} while (0)
# define dprintk(LEVEL, args...) do {} while (0)
#endif

Expand All @@ -57,18 +58,26 @@ static int dbgp_enabled(void);
#define DBGP_MICROFRAME_RETRIES 10
#define DBGP_MAX_PACKET 8

static int dbgp_enabled(void);
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug);

static struct ehci_debug_info glob_dbg_info CAR_GLOBAL;
static struct ehci_debug_info * glob_dbg_info_p CAR_GLOBAL;

static inline struct ehci_debug_info *dbgp_ehci_info(void)
{
if (IS_ENABLED(CONFIG_USBDEBUG_IN_PRE_RAM)
&& (ENV_ROMSTAGE || ENV_BOOTBLOCK || ENV_VERSTAGE))
glob_dbg_info_p =
(struct ehci_debug_info *)_car_ehci_dbg_info_start;
if (car_get_var(glob_dbg_info_p) == NULL)
car_set_var(glob_dbg_info_p, &glob_dbg_info);

if (car_get_var(glob_dbg_info_p) == NULL) {
struct ehci_debug_info *info;
if (ENV_BOOTBLOCK || ENV_VERSTAGE || ENV_ROMSTAGE) {
/* The message likely does not show if we hit this. */
if (sizeof(*info) > _car_ehci_dbg_info_size)
die("BUG: Increase ehci_dbg_info reserve in CAR");
info = (void *)_car_ehci_dbg_info_start;
} else {
info = &glob_dbg_info;
}
car_set_var(glob_dbg_info_p, info);
}
return car_get_var(glob_dbg_info_p);
}

Expand Down Expand Up @@ -202,13 +211,19 @@ static void dbgp_get_data(struct ehci_dbg_port *ehci_debug, void *buf, int size)
bytes[i] = (hi >> (8*(i - 4))) & 0xff;
}

#if IS_ENABLED(CONFIG_DEBUG_USBDEBUG)
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug)
{
u32 ctrl = read32(&ehci_debug->control);
u32 lo = read32(&ehci_debug->data03);
u32 hi = read32(&ehci_debug->data47);
int len = DBGP_LEN(ctrl);
int len;
u32 ctrl, lo, hi;

if (!IS_ENABLED(CONFIG_DEBUG_CONSOLE_INIT) || dbgp_enabled())
return;

ctrl = read32(&ehci_debug->control);
lo = read32(&ehci_debug->data03);
hi = read32(&ehci_debug->data47);

len = DBGP_LEN(ctrl);
if (len) {
int i;
dprintk(BIOS_SPEW, "dbgp: buf:");
Expand All @@ -219,7 +234,6 @@ static void dbgp_print_data(struct ehci_dbg_port *ehci_debug)
dprintk(BIOS_SPEW, "\n");
}
}
#endif

static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
const char *bytes, int size)
Expand Down Expand Up @@ -249,7 +263,9 @@ static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *p
int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size)
{
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
return dbgp_bulk_write(dbg_info->ehci_debug, pipe, bytes, size);
struct ehci_dbg_port *port;
port = (void *)(uintptr_t)dbg_info->ehci_debug;
return dbgp_bulk_write(port, pipe, bytes, size);
}

static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
Expand Down Expand Up @@ -283,7 +299,9 @@ static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pi
int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size)
{
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
return dbgp_bulk_read(dbg_info->ehci_debug, pipe, data, size);
struct ehci_dbg_port *port;
port = (void *)(uintptr_t)dbg_info->ehci_debug;
return dbgp_bulk_read(port, pipe, data, size);
}

void dbgp_mdelay(int ms)
Expand Down Expand Up @@ -433,8 +451,8 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_

/* Keep all endpoints disabled before any printk() call. */
memset(info, 0, sizeof (*info));
info->ehci_base = (void *)ehci_bar;
info->ehci_debug = (void *)(ehci_bar + offset);
info->ehci_base = ehci_bar;
info->ehci_debug = ehci_bar + offset;
info->ep_pipe[0].status |= DBGP_EP_NOT_PRESENT;

dprintk(BIOS_INFO, "ehci_bar: 0x%x debug_offset 0x%x\n", ehci_bar, offset);
Expand All @@ -443,7 +461,7 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_
ehci_regs = (struct ehci_regs *)(ehci_bar +
HC_LENGTH(read32(&ehci_caps->hc_capbase)));

struct ehci_dbg_port *ehci_debug = info->ehci_debug;
struct ehci_dbg_port *ehci_debug = (void *)(uintptr_t)info->ehci_debug;

if (CONFIG_USBDEBUG_DEFAULT_PORT > 0)
ehci_debug_select_port(CONFIG_USBDEBUG_DEFAULT_PORT);
Expand Down Expand Up @@ -568,7 +586,8 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_

dbgp_mdelay(100);

ret = dbgp_probe_gadget(info->ehci_debug, &info->ep_pipe[0]);
struct ehci_dbg_port *port = (void *)(uintptr_t)info->ehci_debug;
ret = dbgp_probe_gadget(port, &info->ep_pipe[0]);
if (ret < 0) {
dprintk(BIOS_INFO, "Could not probe gadget on debug port.\n");
ret = -6;
Expand Down Expand Up @@ -640,12 +659,12 @@ void dbgp_put(struct dbgp_pipe *pipe)
void usbdebug_re_enable(unsigned ehci_base)
{
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
unsigned diff;
u64 diff;
int i;

diff = (unsigned)dbg_info->ehci_base - ehci_base;
diff = dbg_info->ehci_base - ehci_base;
dbg_info->ehci_debug -= diff;
dbg_info->ehci_base = (void *)ehci_base;
dbg_info->ehci_base = ehci_base;

for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
if (dbg_info->ep_pipe[i].status & DBGP_EP_VALID)
Expand All @@ -665,7 +684,7 @@ void usbdebug_disable(void)
int usbdebug_hw_init(bool force)
{
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
unsigned int ehci_base, dbg_offset;
u32 ehci_base, dbg_offset;

if (dbgp_enabled() && !force)
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/drivers/usb/ehci_debug.h
Expand Up @@ -47,12 +47,12 @@ struct dbgp_pipe
u8 endpoint;
u8 pid;
u8 status;
int timeout;
u16 timeout;

u8 bufidx;
u8 buflen;
char buf[8];
};
} __packed;

void dbgp_put(struct dbgp_pipe *pipe);
int dbgp_try_get(struct dbgp_pipe *pipe);
Expand Down
1 change: 1 addition & 0 deletions src/ec/google/chromeec/Makefile.inc
@@ -1,6 +1,7 @@
ifeq ($(CONFIG_EC_GOOGLE_CHROMEEC),y)

bootblock-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
verstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
romstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
smm-$(CONFIG_EC_GOOGLE_CHROMEEC_BOARDID) += ec_boardid.c
Expand Down
9 changes: 9 additions & 0 deletions src/ec/google/wilco/commands.c
Expand Up @@ -158,3 +158,12 @@ int wilco_ec_radio_control(enum ec_radio radio, uint8_t state)
radio_control, ARRAY_SIZE(radio_control),
NULL, 0);
}

int wilco_ec_change_wake(uint8_t source, enum ec_wake_change change)
{
uint8_t wake_source[3] = { change, source };

return wilco_ec_mailbox(WILCO_EC_MSG_DEFAULT, KB_ACPI_WAKEUP_CHANGE,
wake_source, ARRAY_SIZE(wake_source),
NULL, 0);
}
23 changes: 23 additions & 0 deletions src/ec/google/wilco/commands.h
Expand Up @@ -38,6 +38,8 @@ enum {
KB_EC_INFO = 0x38,
/* Set ACPI mode on or off */
KB_ACPI = 0x3a,
/* Change ACPI wake up source */
KB_ACPI_WAKEUP_CHANGE = 0x4a,
/* Manage the EC power button passthru to the host */
KB_POWER_BUTTON_TO_HOST = 0x3e,
/* Manage the EC control of speaker mute */
Expand Down Expand Up @@ -257,4 +259,25 @@ int wilco_ec_get_pm(struct ec_pm_event_state *pm, bool clear);
*/
int wilco_ec_get_lid_state(void);

enum ec_wake_change {
WAKE_OFF = 0,
WAKE_ON
};
/**
* wilco_ec_change_wake_source
*
* Change acpi wake up source.
* @source: Wake up source that can be enabled/disabled.
* @ec_wake_change: On/off switch.
*
* Returns -1 if the EC command failed
*/
int wilco_ec_change_wake(uint8_t source, enum ec_wake_change change);

enum ec_acpi_wake_events {
EC_ACPI_WAKE_PWRB = BIT(0), /* Wake up by power button */
EC_ACPI_WAKE_LID = BIT(1), /* Wake up by lid switch */
EC_ACPI_WAKE_RTC = BIT(5), /* Wake up by RTC */
};

#endif /* EC_GOOGLE_WILCO_COMMANDS_H */
2 changes: 2 additions & 0 deletions src/ec/google/wilco/smihandler.c
Expand Up @@ -26,6 +26,8 @@ void wilco_ec_smi_sleep(int slp_type)
switch (slp_type) {
case ACPI_S3:
wilco_ec_send_noargs(KB_SAVE);
wilco_ec_change_wake((EC_ACPI_WAKE_PWRB|EC_ACPI_WAKE_LID),
WAKE_ON);
wilco_ec_slp_en();
break;
case ACPI_S5:
Expand Down
5 changes: 5 additions & 0 deletions src/ec/kontron/kempld/Kconfig
@@ -0,0 +1,5 @@
config EC_KONTRON_KEMPLD
bool
help
Driver for Kontron's express module programmable logic device used
on their COMexpress modules.
4 changes: 4 additions & 0 deletions src/ec/kontron/kempld/Makefile.inc
@@ -0,0 +1,4 @@
bootblock-$(CONFIG_EC_KONTRON_KEMPLD) += early_kempld.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += early_kempld.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += kempld.c
ramstage-$(CONFIG_EC_KONTRON_KEMPLD) += kempld_i2c.c
38 changes: 38 additions & 0 deletions src/ec/kontron/kempld/chip.h
@@ -0,0 +1,38 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 secunet Security Networks AG
*
* 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.
*/

#ifndef EC_KONTRON_KEMPLD_CHIP_H
#define EC_KONTRON_KEMPLD_CHIP_H

#define KEMPLD_NUM_UARTS 2

enum kempld_uart_io {
KEMPLD_UART_3F8 = 0,
KEMPLD_UART_2F8 = 1,
KEMPLD_UART_3E8 = 2,
KEMPLD_UART_2E8 = 3,
};

struct kempld_uart {
enum kempld_uart_io io;
unsigned int irq;
};

struct ec_kontron_kempld_config {
struct kempld_uart uart[KEMPLD_NUM_UARTS];
};

#endif /* EC_KONTRON_KEMPLD_CHIP_H */
72 changes: 72 additions & 0 deletions src/ec/kontron/kempld/early_kempld.c
@@ -0,0 +1,72 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 secunet Security Networks AG
*
* 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.
*/

#include <stdint.h>
#include <arch/io.h>
#include <delay.h>

#include "chip.h"
#include "kempld.h"
#include "kempld_internal.h"

void kempld_write8(const uint8_t addr, const uint8_t data)
{
outb(addr, KEMPLD_IDX);
outb(data, KEMPLD_DAT);
}

uint8_t kempld_read8(const uint8_t addr)
{
outb(addr, KEMPLD_IDX);
return inb(KEMPLD_DAT);
}

int kempld_get_mutex(int timeout_ms)
{
while (inb(KEMPLD_IDX) & KEMPLD_MUTEX_KEY && timeout_ms--)
mdelay(1);
return timeout_ms;
}

void kempld_release_mutex(void)
{
outb(KEMPLD_MUTEX_KEY, KEMPLD_IDX);
}

void kempld_enable_uart_for_console(void)
{
if (!IS_ENABLED(CONFIG_CONSOLE_SERIAL))
return;

if (kempld_get_mutex(100) < 0)
return;

switch (CONFIG_UART_FOR_CONSOLE) {
case 0:
kempld_write8(KEMPLD_UART_0,
KEMPLD_UART_ENABLE |
KEMPLD_UART_3F8 << KEMPLD_UART_IO_SHIFT);
break;
case 1:
kempld_write8(KEMPLD_UART_1,
KEMPLD_UART_ENABLE |
KEMPLD_UART_2F8 << KEMPLD_UART_IO_SHIFT);
break;
default:
break;
}

kempld_release_mutex();
}
115 changes: 115 additions & 0 deletions src/ec/kontron/kempld/kempld.c
@@ -0,0 +1,115 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 secunet Security Networks AG
*
* 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.
*/

#include <console/console.h>
#include <device/device.h>

#include "chip.h"
#include "kempld.h"
#include "kempld_internal.h"

static void kempld_uart_read_resources(struct device *dev)
{
static const unsigned int io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };

const struct ec_kontron_kempld_config *const config = dev->chip_info;

struct resource *const res_io = new_resource(dev, 0);
struct resource *const res_irq = new_resource(dev, 1);
const unsigned int uart = dev->path.generic.subid;
if (!config || !res_io || !res_irq || uart >= KEMPLD_NUM_UARTS)
return;

const enum kempld_uart_io io = config->uart[uart].io;
if (io >= ARRAY_SIZE(io_addr)) {
printk(BIOS_ERR, "KEMPLD: Bad io value '%d' for UART#%u\n.",
io, uart);
dev->enabled = false;
return;
}

const int irq = config->uart[uart].irq;
if (irq >= 16) {
printk(BIOS_ERR, "KEMPLD: Bad irq value '%d' for UART#%u\n.",
irq, uart);
dev->enabled = false;
return;
}

res_io->base = io_addr[io];
res_io->size = 8;
res_io->flags = IORESOURCE_IO | IORESOURCE_FIXED |
IORESOURCE_STORED | IORESOURCE_ASSIGNED;
res_irq->base = irq;
res_irq->size = 1;
res_irq->flags = IORESOURCE_IO | IORESOURCE_FIXED |
IORESOURCE_STORED | IORESOURCE_ASSIGNED;

if (kempld_get_mutex(100) < 0)
return;

const uint8_t reg = uart ? KEMPLD_UART_1 : KEMPLD_UART_0;
const uint8_t val = kempld_read8(reg);
kempld_write8(reg, (val & ~(KEMPLD_UART_IO_MASK | KEMPLD_UART_IRQ_MASK))
| io << KEMPLD_UART_IO_SHIFT
| irq << KEMPLD_UART_IRQ_SHIFT);

kempld_release_mutex();
}

static void kempld_uart_enable_resources(struct device *dev)
{
if (kempld_get_mutex(100) < 0)
return;

const unsigned int uart = dev->path.generic.subid;
const uint8_t reg = uart ? KEMPLD_UART_1 : KEMPLD_UART_0;
kempld_write8(reg, kempld_read8(reg) | KEMPLD_UART_ENABLE);

kempld_release_mutex();
}

static struct device_operations kempld_uart_ops = {
.read_resources = kempld_uart_read_resources,
.enable_resources = kempld_uart_enable_resources,
};

static void kempld_enable_dev(struct device *const dev)
{
if (dev->path.type == DEVICE_PATH_GENERIC) {
switch (dev->path.generic.id) {
case 0:
if (dev->path.generic.subid < KEMPLD_NUM_UARTS) {
dev->ops = &kempld_uart_ops;
break;
}
case 1:
if (dev->path.generic.subid == 0) {
kempld_i2c_device_init(dev);
break;
}
default:
printk(BIOS_WARNING,
"KEMPLD: Spurious device %s.\n",
dev_path(dev));
break;
}
}
}

struct chip_operations ec_kontron_kempld_ops = {
CHIP_NAME("Kontron KEMPLD")
.enable_dev = kempld_enable_dev,
};
29 changes: 29 additions & 0 deletions src/ec/kontron/kempld/kempld.h
@@ -0,0 +1,29 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 secunet Security Networks AG
*
* 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.
*/

#ifndef EC_KONTRON_KEMPLD_H
#define EC_KONTRON_KEMPLD_H

#include <stdint.h>

void kempld_write8(uint8_t addr, uint8_t data);
uint8_t kempld_read8(uint8_t addr);

int kempld_get_mutex(int timeout_ms);
void kempld_release_mutex(void);

void kempld_enable_uart_for_console(void);

#endif /* EC_KONTRON_KEMPLD_H */
296 changes: 296 additions & 0 deletions src/ec/kontron/kempld/kempld_i2c.c
@@ -0,0 +1,296 @@
/*
* I2C bus driver for Kontron COM modules
*
* Copyright (C) 2017 secunet Security Networks AG
*
* Based on the similar driver in Linux:
*
* Copyright (c) 2010-2013 Kontron Europe GmbH
* Author: Michael Brunner <michael.brunner@kontron.com>
*
* The driver is based on the i2c-ocores driver by Peter Korsgaard.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License 2 as published
* by the Free Software Foundation.
*
* 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.
*/

#include <stdint.h>
#include <console/console.h>
#include <device/device.h>
#include <device/i2c_bus.h>
#include <timer.h>
#include <delay.h>

#include "kempld.h"
#include "kempld_internal.h"

#define KEMPLD_I2C_PRELOW 0x0b
#define KEMPLD_I2C_PREHIGH 0x0c
#define KEMPLD_I2C_DATA 0x0e

#define KEMPLD_I2C_CTRL 0x0d
#define I2C_CTRL_IEN 0x40
#define I2C_CTRL_EN 0x80

#define KEMPLD_I2C_STAT 0x0f
#define I2C_STAT_IF 0x01
#define I2C_STAT_TIP 0x02
#define I2C_STAT_ARBLOST 0x20
#define I2C_STAT_BUSY 0x40
#define I2C_STAT_NACK 0x80

#define KEMPLD_I2C_CMD 0x0f
#define I2C_CMD_START 0x91
#define I2C_CMD_STOP 0x41
#define I2C_CMD_READ 0x21
#define I2C_CMD_WRITE 0x11
#define I2C_CMD_READ_ACK 0x21
#define I2C_CMD_READ_NACK 0x29
#define I2C_CMD_IACK 0x01

#define KEMPLD_I2C_FREQ_MAX 2700 /* 2.7 mHz */
#define KEMPLD_I2C_FREQ_STD 100 /* 100 kHz */

#define EIO 5
#define ENXIO 6
#define EAGAIN 11
#define EBUSY 16
#define ETIMEDOUT 110

enum kempld_i2c_state {
STATE_DONE = 0,
STATE_INIT,
STATE_ADDR,
STATE_ADDR10,
STATE_START,
STATE_WRITE,
STATE_READ,
STATE_ERROR,
};

struct kempld_i2c_data {
const struct i2c_msg *msg;
size_t pos;
size_t nmsgs;
enum kempld_i2c_state state;
};

/*
* kempld_get_mutex must be called prior to calling this function.
*/
static int kempld_i2c_process(struct kempld_i2c_data *const i2c)
{
u8 stat = kempld_read8(KEMPLD_I2C_STAT);
const struct i2c_msg *msg = i2c->msg;
u8 addr;

/* Ready? */
if (stat & I2C_STAT_TIP)
return -EBUSY;

if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) {
/* Stop has been sent */
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_IACK);
if (i2c->state == STATE_ERROR)
return -EIO;
return 0;
}

/* Error? */
if (stat & I2C_STAT_ARBLOST) {
i2c->state = STATE_ERROR;
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_STOP);
return -EAGAIN;
}

if (i2c->state == STATE_INIT) {
if (stat & I2C_STAT_BUSY)
return -EBUSY;

i2c->state = STATE_ADDR;
}

if (i2c->state == STATE_ADDR) {
/* 10 bit address? */
if (i2c->msg->flags & I2C_M_TEN) {
addr = 0xf0 | ((i2c->msg->slave >> 7) & 0x6);
i2c->state = STATE_ADDR10;
} else {
addr = (i2c->msg->slave << 1);
i2c->state = STATE_START;
}

/* Set read bit if necessary */
addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;

kempld_write8(KEMPLD_I2C_DATA, addr);
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_START);

return 0;
}

/* Second part of 10 bit addressing */
if (i2c->state == STATE_ADDR10) {
kempld_write8(KEMPLD_I2C_DATA, i2c->msg->slave & 0xff);
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_WRITE);

i2c->state = STATE_START;
return 0;
}

if (i2c->state == STATE_START || i2c->state == STATE_WRITE) {
i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;

if (stat & I2C_STAT_NACK) {
i2c->state = STATE_ERROR;
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_STOP);
return -ENXIO;
}
} else {
msg->buf[i2c->pos++] = kempld_read8(KEMPLD_I2C_DATA);
}

if (i2c->pos >= msg->len) {
i2c->nmsgs--;
i2c->msg++;
i2c->pos = 0;
msg = i2c->msg;

if (i2c->nmsgs) {
if (!(msg->flags & I2C_M_NOSTART)) {
i2c->state = STATE_ADDR;
return 0;
} else {
i2c->state = (msg->flags & I2C_M_RD)
? STATE_READ : STATE_WRITE;
}
} else {
i2c->state = STATE_DONE;
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_STOP);
return 0;
}
}

if (i2c->state == STATE_READ) {
kempld_write8(KEMPLD_I2C_CMD, i2c->pos == (msg->len - 1) ?
I2C_CMD_READ_NACK : I2C_CMD_READ_ACK);
} else {
kempld_write8(KEMPLD_I2C_DATA, msg->buf[i2c->pos++]);
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_WRITE);
}

return 0;
}

static int kempld_i2c_xfer(struct device *const dev,
const struct i2c_msg *const msgs,
const size_t num)
{
struct kempld_i2c_data i2c;
struct stopwatch sw;
int ret;

if (kempld_get_mutex(100) < 0)
return -ENXIO;

i2c.msg = msgs;
i2c.pos = 0;
i2c.nmsgs = num;
i2c.state = STATE_INIT;

/* Handle the transfer */
stopwatch_init_msecs_expire(&sw, 1000);
while (!stopwatch_expired(&sw)) {
ret = kempld_i2c_process(&i2c);

if (i2c.state == STATE_DONE || i2c.state == STATE_ERROR) {
if (i2c.state == STATE_DONE) {
printk(BIOS_SPEW, "kempld_i2c: Processed %zu segments.\n", num);
ret = 0;
} else {
printk(BIOS_INFO, "kempld_i2c: Transfer failed.\n");
}
goto _release;
}

if (ret == 0)
stopwatch_init_msecs_expire(&sw, 1000);

udelay(10);
}

i2c.state = STATE_ERROR;
ret = -ETIMEDOUT;
printk(BIOS_INFO, "kempld_i2c: Transfer failed.\n");

_release:
kempld_release_mutex();
return ret;
}

static const struct i2c_bus_operations kempld_i2c_bus_ops = {
.transfer = kempld_i2c_xfer,
};

static struct device_operations kempld_i2c_dev_ops = {
.scan_bus = &scan_smbus,
.ops_i2c_bus = &kempld_i2c_bus_ops,
};

void kempld_i2c_device_init(struct device *const dev)
{
u16 prescale_corr;
long prescale;
u8 ctrl;
u8 stat;
u8 cfg;

if (kempld_get_mutex(100) < 0)
return;

/* Make sure the device is disabled */
ctrl = kempld_read8(KEMPLD_I2C_CTRL);
ctrl &= ~(I2C_CTRL_EN | I2C_CTRL_IEN);
kempld_write8(KEMPLD_I2C_CTRL, ctrl);

const u8 spec_major = KEMPLD_SPEC_GET_MAJOR(kempld_read8(KEMPLD_SPEC));
if (spec_major == 1)
prescale = KEMPLD_CLK / (KEMPLD_I2C_FREQ_STD * 5) - 1000;
else
prescale = KEMPLD_CLK / (KEMPLD_I2C_FREQ_STD * 4) - 3000;

if (prescale < 0)
prescale = 0;

/* Round to the best matching value */
prescale_corr = prescale / 1000;
if (prescale % 1000 >= 500)
prescale_corr++;

kempld_write8(KEMPLD_I2C_PRELOW, prescale_corr & 0xff);
kempld_write8(KEMPLD_I2C_PREHIGH, prescale_corr >> 8);

/* Disable I2C bus output on GPIO pins */
cfg = kempld_read8(KEMPLD_CFG);
cfg &= ~KEMPLD_CFG_GPIO_I2C_MUX;
kempld_write8(KEMPLD_CFG, cfg);

/* Enable the device */
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_IACK);
ctrl |= I2C_CTRL_EN;
kempld_write8(KEMPLD_I2C_CTRL, ctrl);

stat = kempld_read8(KEMPLD_I2C_STAT);
if (stat & I2C_STAT_BUSY)
kempld_write8(KEMPLD_I2C_CMD, I2C_CMD_STOP);

dev->ops = &kempld_i2c_dev_ops;

kempld_release_mutex();
}
46 changes: 46 additions & 0 deletions src/ec/kontron/kempld/kempld_internal.h
@@ -0,0 +1,46 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 secunet Security Networks AG
*
* 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.
*/

#ifndef EC_KONTRON_KEMPLD_INTERNAL_H
#define EC_KONTRON_KEMPLD_INTERNAL_H

#include <device/device.h>

/* i/o ports */
#define KEMPLD_IDX 0xa80
#define KEMPLD_MUTEX_KEY 0x80
#define KEMPLD_DAT 0xa81

/* indexed registers */
#define KEMPLD_SPEC 0x06
#define KEMPLD_SPEC_GET_MINOR(x) (x & 0x0f)
#define KEMPLD_SPEC_GET_MAJOR(x) (x >> 4 & 0x0f)

#define KEMPLD_CFG 0x37
#define KEMPLD_CFG_GPIO_I2C_MUX (1 << 0)

#define KEMPLD_UART_0 0x30
#define KEMPLD_UART_1 0x31
#define KEMPLD_UART_IRQ_SHIFT 0
#define KEMPLD_UART_IRQ_MASK (0xf << KEMPLD_UART_IRQ_SHIFT)
#define KEMPLD_UART_IO_SHIFT 4
#define KEMPLD_UART_IO_MASK (0x3 << KEMPLD_UART_IO_SHIFT)
#define KEMPLD_UART_ENABLE 0x80

#define KEMPLD_CLK 33333333 /* 33MHz */

void kempld_i2c_device_init(struct device *const dev);

#endif /* EC_KONTRON_KEMPLD_INTERNAL_H */
24 changes: 24 additions & 0 deletions src/include/boot_device.h
Expand Up @@ -18,6 +18,22 @@

#include <commonlib/region.h>

/*
* Boot device region can be protected by 2 sources, media and controller.
* The following modes are identified. It depends on the flash chip and the
* controller if mode is actually supported.
*
* MEDIA_WP : Flash/Boot device enforces write protect
* CTRLR_WP : Controller device enforces write protect
* CTRLR_RP : Controller device enforces read protect
* CTRLR_RWP : Controller device enforces read-write protect
*/
enum bootdev_prot_type {
CTRLR_WP = 1,
CTRLR_RP = 2,
CTRLR_RWP = 3,
MEDIA_WP = 4,
};
/*
* Please note that the read-only boot device may not be coherent with
* the read-write boot device. Thus, mixing mmap() and writeat() is
Expand All @@ -44,6 +60,14 @@ int boot_device_ro_subregion(const struct region *sub,
int boot_device_rw_subregion(const struct region *sub,
struct region_device *subrd);

/*
* Write protect a sub-region of the boot device represented
* by the region device.
* Returns 0 on success, < 0 on error.
*/
int boot_device_wp_region(struct region_device *rd,
const enum bootdev_prot_type type);

/*
* Initialize the boot device. This may be called multiple times within
* a stage so boot device implementations should account for this behavior.
Expand Down
7 changes: 5 additions & 2 deletions src/include/bootmem.h
Expand Up @@ -94,8 +94,11 @@ bool bootmem_walk_os_mem(range_action_t action, void *arg);
*/
bool bootmem_walk(range_action_t action, void *arg);

/* Return 1 if region targets usable RAM, 0 otherwise. */
int bootmem_region_targets_usable_ram(uint64_t start, uint64_t size);
/* Returns 1 if the requested memory range is all tagged as type dest_type.
* Otherwise returns 0.
*/
int bootmem_region_targets_type(uint64_t start, uint64_t size,
enum bootmem_type dest_type);

/* Allocate a temporary buffer from the unused RAM areas. */
void *bootmem_allocate_buffer(size_t size);
Expand Down
1 change: 0 additions & 1 deletion src/include/bootstate.h
Expand Up @@ -15,7 +15,6 @@
#ifndef BOOTSTATE_H
#define BOOTSTATE_H

#include <rules.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
Expand Down
4 changes: 2 additions & 2 deletions src/include/cbmem.h
Expand Up @@ -18,7 +18,6 @@
#define _CBMEM_H_

#include <commonlib/cbmem_id.h>
#include <rules.h>
#include <stddef.h>
#include <stdint.h>
#include <boot/coreboot_tables.h>
Expand Down Expand Up @@ -71,7 +70,8 @@ void cbmem_top_init(void);

/* Return the top address for dynamic cbmem. The address returned needs to
* be consistent across romstage and ramstage, and it is required to be
* below 4GiB.
* below 4GiB for 32bit coreboot builds. On 64bit coreboot builds there's no
* upper limit.
* x86 boards or chipsets must return NULL before the cbmem backing store has
* been initialized. */
void *cbmem_top(void);
Expand Down
1 change: 0 additions & 1 deletion src/include/console/cbmem_console.h
Expand Up @@ -15,7 +15,6 @@
#ifndef _CONSOLE_CBMEM_CONSOLE_H_
#define _CONSOLE_CBMEM_CONSOLE_H_

#include <rules.h>
#include <stdint.h>

void cbmemc_init(void);
Expand Down
1 change: 0 additions & 1 deletion src/include/console/console.h
Expand Up @@ -17,7 +17,6 @@
#define CONSOLE_CONSOLE_H_

#include <stdint.h>
#include <rules.h>
#include <arch/cpu.h>
#include <console/post_codes.h>
#include <commonlib/loglevel.h>
Expand Down
1 change: 0 additions & 1 deletion src/include/console/flash.h
Expand Up @@ -16,7 +16,6 @@
#ifndef CONSOLE_FLASH_H
#define CONSOLE_FLASH_H 1

#include <rules.h>
#include <stdint.h>

void flashconsole_init(void);
Expand Down
1 change: 0 additions & 1 deletion src/include/console/ne2k.h
Expand Up @@ -16,7 +16,6 @@
#ifndef _NE2K_H__
#define _NE2K_H__

#include <rules.h>
#include <stdint.h>

void ne2k_append_data(unsigned char *d, int len, unsigned int base);
Expand Down