From b3c41329fdca84a251c183bbc2b0767978e9d96f Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Wed, 20 May 2020 14:07:41 -0600 Subject: mb/google/zork: Add Picasso based Zork mainboard and variants This is a copy of the mb/google/zork directory from the chromiumos coreboot-zork branch. This was from commit 29308ac8606. See https://chromium.googlesource.com/chromiumos/third_party/coreboot/+/29308ac8606/src/mainboard/google/zork Changes: * Minor changes to make the board build. * Add bootblock.c. * Modify romstage.c * Removed the FSP_X configs from zork/Kconfig since they should be set in picasso/Kconfig. picasso/Kconfig doesn't currently define the binaries since they haven't been published. To get a working build a custom config that sets FSP_X_FILE is required. BUG=b:157140753 TEST=Build trembyle and boot to OS Signed-off-by: Raul E Rangel Change-Id: I3933fa54e3f603985a0818852a1c77d8e248484f Reviewed-on: https://review.coreboot.org/c/coreboot/+/41581 Reviewed-by: Furquan Shaikh Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- src/mainboard/google/zork/mainboard.c | 255 ++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 src/mainboard/google/zork/mainboard.c (limited to 'src/mainboard/google/zork/mainboard.c') diff --git a/src/mainboard/google/zork/mainboard.c b/src/mainboard/google/zork/mainboard.c new file mode 100644 index 0000000000..73ece65930 --- /dev/null +++ b/src/mainboard/google/zork/mainboard.c @@ -0,0 +1,255 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*********************************************************** + * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. + * This table is responsible for physically routing the PIC and + * IOAPIC IRQs to the different PCI devices on the system. It + * is read and written via registers 0xC00/0xC01 as an + * Index/Data pair. These values are chipset and mainboard + * dependent and should be updated accordingly. + */ +static uint8_t fch_pic_routing[0x80]; +static uint8_t fch_apic_routing[0x80]; + +_Static_assert(sizeof(fch_pic_routing) == sizeof(fch_apic_routing), + "PIC and APIC FCH interrupt tables must be the same size"); + +/* + * This table doesn't actually perform any routing. It only populates the + * PCI_INTERRUPT_LINE register on the PCI device with the PIC value specified + * in fch_apic_routing. The linux kernel only looks at this field as a backup + * if ACPI routing fails to describe the PCI routing correctly. The linux kernel + * also uses the APIC by default, so the value coded into the registers will be + * wrong. + * + * This table is also confusing because PCI Interrupt routing happens at the + * device/slot level, not the function level. + */ +static const struct pirq_struct mainboard_pirq_data[] = { + { PCIE_GPP_0_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, + { PCIE_GPP_1_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, // Bridge 1 - Wifi + { PCIE_GPP_2_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, // Bridge 2 - SD + { PCIE_GPP_3_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, + { PCIE_GPP_4_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, + { PCIE_GPP_5_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, + { PCIE_GPP_6_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, // Bridge 6 - NVME + { PCIE_GPP_A_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, + { PCIE_GPP_B_DEVFN, { PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D } }, + { SMBUS_DEVFN, { PIRQ_SMBUS, PIRQ_NC, PIRQ_NC, PIRQ_NC } }, +}; + +/* + * This controls the device -> IRQ routing. + * The PIC values are limited to 0,1, 3 - 12, 14, 15. + */ +static const struct fch_apic_routing { + uint8_t intr_index; + uint8_t pic_irq_num; + uint8_t apic_irq_num; +} fch_pirq[] = { + { PIRQ_A, 6, 16 }, + { PIRQ_B, 6, 17 }, + { PIRQ_C, 14, 18 }, + { PIRQ_D, 15, 19 }, + { PIRQ_E, PIRQ_NC, PIRQ_NC }, + { PIRQ_F, PIRQ_NC, PIRQ_NC }, + { PIRQ_G, PIRQ_NC, PIRQ_NC }, + { PIRQ_H, PIRQ_NC, PIRQ_NC }, + { PIRQ_SIRQA, PIRQ_NC, PIRQ_NC }, + { PIRQ_SIRQB, PIRQ_NC, PIRQ_NC }, + { PIRQ_SIRQC, PIRQ_NC, PIRQ_NC }, + { PIRQ_SIRQD, PIRQ_NC, PIRQ_NC }, + { PIRQ_SCI, 9, 9 }, + { PIRQ_SMBUS, PIRQ_NC, PIRQ_NC }, + { PIRQ_ASF, PIRQ_NC, PIRQ_NC }, + { PIRQ_PMON, PIRQ_NC, PIRQ_NC }, + { PIRQ_SD, PIRQ_NC, PIRQ_NC }, + { PIRQ_SDIO, PIRQ_NC, PIRQ_NC }, + { PIRQ_CIR, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPIOA, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPIOB, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPIOC, PIRQ_NC, PIRQ_NC }, + { PIRQ_SATA, PIRQ_NC, PIRQ_NC }, + { PIRQ_EMMC, 5, 5 }, + { PIRQ_GPP0, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPP1, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPP2, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPP3, PIRQ_NC, PIRQ_NC }, + { PIRQ_GPIO, 7, 7 }, + { PIRQ_I2C0, PIRQ_NC, PIRQ_NC }, + { PIRQ_I2C1, PIRQ_NC, PIRQ_NC }, + { PIRQ_I2C2, 10, 10 }, + { PIRQ_I2C3, 11, 11 }, + { PIRQ_UART0, 4, 4 }, + { PIRQ_UART1, 3, 3 }, + { PIRQ_I2C4, PIRQ_NC, PIRQ_NC }, + { PIRQ_I2C5, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART2, PIRQ_NC, PIRQ_NC }, + { PIRQ_UART3, PIRQ_NC, PIRQ_NC }, + + /* The MISC registers are not interrupt numbers */ + { PIRQ_MISC, 0xfa, 0x00 }, + { PIRQ_MISC0, 0xf1, 0x00 }, + { PIRQ_MISC1, 0x00, 0x00 }, + { PIRQ_MISC2, 0x00, 0x00 }, +}; + +static void init_tables(void) +{ + const struct fch_apic_routing *entry; + int i; + + memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing)); + memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing)); + + for (i = 0; i < ARRAY_SIZE(fch_pirq); i++) { + entry = fch_pirq + i; + fch_pic_routing[entry->intr_index] = entry->pic_irq_num; + fch_apic_routing[entry->intr_index] = entry->apic_irq_num; + } +} + +/* PIRQ Setup */ +static void pirq_setup(void) +{ + init_tables(); + + pirq_data_ptr = mainboard_pirq_data; + pirq_data_size = ARRAY_SIZE(mainboard_pirq_data); + intr_data_ptr = fch_apic_routing; + picr_data_ptr = fch_pic_routing; +} + +static void mainboard_configure_gpios(void) +{ + size_t base_num_gpios, override_num_gpios; + const struct soc_amd_gpio *base_gpios, *override_gpios; + + base_gpios = variant_base_gpio_table(&base_num_gpios); + override_gpios = variant_override_gpio_table(&override_num_gpios); + + gpio_configure_pads_with_override(base_gpios, base_num_gpios, override_gpios, + override_num_gpios); +} + +static void mainboard_init(void *chip_info) +{ + const struct sci_source *gpes; + size_t num; + int boardid; + + mainboard_ec_init(); + boardid = board_id(); + printk(BIOS_INFO, "Board ID: %d\n", boardid); + + mainboard_configure_gpios(); + + /* Update DUT configuration */ + variant_devtree_update(); + + /* + * Some platforms use SCI not generated by a GPIO pin (event above 23). + * For these boards, gpe_configure_sci() is still needed, but all GPIO + * generated events (23-0) must be removed from gpe_table[]. + * For boards that only have GPIO generated events, table gpe_table[] + * must be removed, and get_gpe_table() should return NULL. + */ + gpes = get_gpe_table(&num); + if (gpes != NULL) + gpe_configure_sci(gpes, num); +} + +void mainboard_get_pcie_ddi_descriptors(const picasso_fsp_pcie_descriptor **pcie_descs, + size_t *pcie_num, + const picasso_fsp_ddi_descriptor **ddi_descs, + size_t *ddi_num) +{ + variant_get_pcie_ddi_descriptors(pcie_descs, pcie_num, ddi_descs, ddi_num); +} + +/************************************************* + * Dedicated mainboard function + *************************************************/ +static void zork_enable(struct device *dev) +{ + printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER " Enable.\n"); + + /* Initialize the PIRQ data structures for consumption */ + pirq_setup(); + + dev->ops->acpi_inject_dsdt = chromeos_dsdt_generator; +} + +static const struct soc_amd_gpio gpio_set_bl[] = { + PAD_GPO(GPIO_85, LOW), +}; + +static void reset_backlight_gpio(void *unused) +{ + printk(BIOS_DEBUG, "Reset backlight GPIO\n"); + /* Re-Enable backlight - GPIO 85 active low */ + /* TODO: Remove this after AGESA stops enabling the fan - b/155667589 */ + program_gpios(gpio_set_bl, ARRAY_SIZE(gpio_set_bl)); /* APU_EDP_BL_DISABLE */ +} + +static void mainboard_final(void *chip_info) +{ + struct global_nvs_t *gnvs; + + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + + reset_backlight_gpio(NULL); + + if (gnvs) { + gnvs->tmps = CTL_TDP_SENSOR_ID; + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; + } +} + +struct chip_operations mainboard_ops = { + .init = mainboard_init, + .enable_dev = zork_enable, + .final = mainboard_final, +}; + +void __weak variant_devtree_update(void) +{ +} + +__weak const struct soc_amd_gpio *variant_override_gpio_table(size_t *size) +{ + /* Default weak implementation - No overrides. */ + *size = 0; + return NULL; +} + +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, reset_backlight_gpio, NULL); -- cgit v1.2.3