blob: 26b9243f9a2aa155558c8896fdd4625cdc472178 [file] [log] [blame]
/*
* Copyright 2018 Google LLC
*
* 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 <arch/io.h>
#include <cbfs.h>
#include <libpayload.h>
#include <pci.h>
#include <pci/pci.h>
#include <sysinfo.h>
#include "base/init_funcs.h"
#include "base/list.h"
#include "config.h"
#include "drivers/bus/i2c/designware.h"
#include "drivers/bus/i2c/i2c.h"
#include "drivers/ec/wilco/ec.h"
#include "drivers/ec/wilco/pd_ti.h"
#include "drivers/flash/fast_spi.h"
#include "drivers/flash/flash.h"
#include "drivers/gpio/cannonlake.h"
#include "drivers/gpio/gpio.h"
#include "drivers/gpio/sysinfo.h"
#include "drivers/power/pch.h"
#include "drivers/soc/cannonlake.h"
#include "drivers/sound/hda_codec.h"
#include "drivers/sound/sound.h"
#include "drivers/storage/ahci.h"
#include "drivers/storage/blockdev.h"
#include "drivers/storage/nvme.h"
#include "drivers/tpm/cr50_i2c.h"
#include "drivers/tpm/cr50_switches.h"
#include "drivers/tpm/tpm.h"
#include "vboot/util/flag.h"
enum {
EC_HOST_BASE = 0x940,
EC_PACKET_BASE = 0x950,
};
const char *pd_cbfs_firmware = "pdrw.bin";
const char *pd_cbfs_hash = "pdrw.hash";
FlashProtectionMapping flash_protection_list[] = {
{
/* Macronix MX25L256 */
.id = {
.vendor = 0xc2,
.model = 0x2019
},
.wp_status_value = 0x9c
},
{
/* Winbond W25Q256 */
.id = {
.vendor = 0xef,
.model = 0x4019
},
.wp_status_value = 0x9c
},
{
/* GigaDevice GD25L256 */
.id = {
.vendor = 0xc8,
.model = 0x4019
},
.wp_status_value = 0x9c
},
/* Empty entry for end of list */
{{ 0 }}
};
static int cr50_irq_status(void)
{
return cannonlake_get_gpe(GPE0_DW2_18);
}
static int board_setup(void)
{
Cr50I2c *tpm;
GpioOps *power_switch;
sysinfo_install_flags(new_cannonlake_gpio_input_from_coreboot);
GpioOps *rec_gpio = sysinfo_lookup_gpio("recovery", 1,
new_cannonlake_gpio_input_from_coreboot);
flag_replace(FLAG_RECSW, rec_gpio);
/* 32MB SPI Flash */
uintptr_t mmio_base = pci_read_config32(PCI_DEV(0, 0x1f, 5),
PCI_BASE_ADDRESS_0);
mmio_base &= PCI_BASE_ADDRESS_MEM_MASK;
FastSpiFlash *spi = new_fast_spi_flash(mmio_base);
flash_set_ops(&spi->ops);
/* Wilco EC */
WilcoEc *wilco_ec = new_wilco_ec(EC_HOST_BASE, EC_PACKET_BASE,
spi->region[FLASH_REGION_EC].offset,
spi->region[FLASH_REGION_EC].size);
register_vboot_ec(&wilco_ec->vboot, PRIMARY_VBOOT_EC);
flag_replace(FLAG_LIDSW, wilco_ec_lid_switch_flag(wilco_ec));
/* Update TI TCPC if available in CBFS */
if (cbfs_find_file(pd_cbfs_hash, CBFS_TYPE_RAW)) {
WilcoPd *ti_tcpc = new_wilco_pd_ti(wilco_ec, pd_cbfs_firmware,
pd_cbfs_hash);
register_vboot_aux_fw(&ti_tcpc->ops);
}
/* H1 TPM on I2C bus 4 @ 400KHz, controller core is 133MHz */
DesignwareI2c *i2c4 = new_pci_designware_i2c(
PCI_DEV(0, 0x19, 0), 400000, CANNONLAKE_DW_I2C_MHZ);
tpm = new_cr50_i2c(&i2c4->ops, 0x50, &cr50_irq_status);
tpm_set_ops(&tpm->base.ops);
power_switch = &new_cr50_power_switch(&tpm->base.ops)->ops;
flag_replace(FLAG_PWRSW, power_switch);
flag_install(FLAG_PHYS_PRESENCE, power_switch);
/* Cannonlake PCH */
power_set_ops(&cannonlake_power_ops);
/* SATA AHCI */
AhciCtrlr *ahci = new_ahci_ctrlr(PCI_DEV(0, 0x17, 0));
list_insert_after(&ahci->ctrlr.list_node, &fixed_block_dev_controllers);
/* M.2 2280 SSD x4 */
NvmeCtrlr *nvme = new_nvme_ctrlr(PCI_DEV(0, 0x1d, 4));
list_insert_after(&nvme->ctrlr.list_node, &fixed_block_dev_controllers);
/* M.2 2280 SSD x4 (if root ports are coalesced) */
NvmeCtrlr *nvme_b = new_nvme_ctrlr(PCI_DEV(0, 0x1d, 0));
list_insert_after(&nvme_b->ctrlr.list_node,
&fixed_block_dev_controllers);
/* Boot beep uses HDA codec */
HdaCodec *codec = new_hda_codec();
sound_set_ops(&codec->ops);
set_hda_beep_nid_override(codec, 1);
return 0;
}
INIT_FUNC(board_setup);