From 208587e0f688988eb20ec89d2422d27f0fe7ad27 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 19 May 2017 18:38:24 +0530 Subject: soc/intel/apollolake: Use common systemagent code This patch perform resource mapping for PCI, fixed MMIO, DRAM and IMR's based on inputs given by SoC. TEST=Ensure PCI root bridge 0:0:0 memory resource allocation remains same between previous implementation and current implementation. Change-Id: I15a3b2fc46ec9063b54379d41996b9a1d612cfd2 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/19795 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/intel/apollolake/Kconfig | 1 + src/soc/intel/apollolake/Makefile.inc | 2 +- src/soc/intel/apollolake/chip.c | 9 +- src/soc/intel/apollolake/include/soc/systemagent.h | 7 +- src/soc/intel/apollolake/northbridge.c | 174 --------------------- src/soc/intel/apollolake/romstage.c | 37 +++-- src/soc/intel/apollolake/systemagent.c | 40 +++++ 7 files changed, 66 insertions(+), 204 deletions(-) delete mode 100644 src/soc/intel/apollolake/northbridge.c create mode 100644 src/soc/intel/apollolake/systemagent.c (limited to 'src') diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 0a13a6659f..a923057d1b 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -50,6 +50,7 @@ config CPU_SPECIFIC_OPTIONS select RELOCATABLE_RAMSTAGE # Build fails if this is not selected select RTC select SMM_TSEG + select SA_ENABLE_IMR select SOC_INTEL_COMMON select SOC_INTEL_COMMON_ACPI select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index 9b1f44022d..b1f92f04d0 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -63,7 +63,7 @@ ramstage-y += mmap_boot.c ramstage-y += p2sb.c ramstage-y += uart.c ramstage-y += nhlt.c -ramstage-y += northbridge.c +ramstage-y += systemagent.c ramstage-y += spi.c ramstage-y += tsc_freq.c ramstage-y += pmutil.c diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index 91bae2d3a2..ef63d2055b 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -219,7 +219,6 @@ static void set_power_limits(void) uint32_t power_unit; uint32_t tdp, min_power, max_power; uint32_t pl2_val; - uint32_t *rapl_mmio_reg; if (!dev || !dev->chip_info) { printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n"); @@ -272,15 +271,11 @@ static void set_power_limits(void) printk(BIOS_INFO, "RAPL PL2 %d.%dW\n", pl2_val / power_unit, 100 * (pl2_val % power_unit) / power_unit); - /* Get the MMIO address */ - rapl_mmio_reg = (void *)(uintptr_t) (MCH_BASE_ADDRESS + - MCHBAR_RAPL_PPL); - /* Setting RAPL MMIO register for Power limits. * RAPL driver is using MSR instead of MMIO. * So, disabled LIMIT_EN bit for MMIO. */ - write32(rapl_mmio_reg, limit.lo & ~(PKG_POWER_LIMIT_EN)); - write32(rapl_mmio_reg + 1, limit.hi & ~(PKG_POWER_LIMIT_EN)); + MCHBAR32(MCHBAR_RAPL_PPL) = limit.lo & ~PKG_POWER_LIMIT_EN; + MCHBAR32(MCHBAR_RAPL_PPL + 4) = limit.hi & ~PKG_POWER_LIMIT_EN; } static void soc_init(void *data) diff --git a/src/soc/intel/apollolake/include/soc/systemagent.h b/src/soc/intel/apollolake/include/soc/systemagent.h index 6b423db840..fe9c15feaa 100644 --- a/src/soc/intel/apollolake/include/soc/systemagent.h +++ b/src/soc/intel/apollolake/include/soc/systemagent.h @@ -20,17 +20,12 @@ #include -/* IMR registers are found under MCHBAR. */ -#define MCHBAR_IMR0BASE 0x6870 -#define MCHBAR_IMR0MASK 0x6874 -#define MCH_IMR_PITCH 0x20 -#define MCH_NUM_IMRS 20 - /* RAPL Package Power Limit register under MCHBAR. */ #define PUNIT_THERMAL_DEVICE_IRQ 0x700C #define PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER 0x18 #define PUINT_THERMAL_DEVICE_IRQ_LOCK 0x80000000 #define BIOS_RESET_CPL 0x7078 +#define PCODE_INIT_DONE (1 << 8) #define MCHBAR_RAPL_PPL 0x70A8 #define CORE_DISABLE_MASK 0x7168 diff --git a/src/soc/intel/apollolake/northbridge.c b/src/soc/intel/apollolake/northbridge.c deleted file mode 100644 index 4997c6f9a4..0000000000 --- a/src/soc/intel/apollolake/northbridge.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Intel Corp. - * (Written by Andrey Petrov for Intel Corp.) - * (Written by Alexandru Gagniuc for Intel Corp.) - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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 -#include -#include -#include -#include - -static uint32_t get_bar(device_t dev, unsigned int index) -{ - uint32_t bar; - - bar = pci_read_config32(dev, index); - - /* If not enabled return 0 else strip enabled bit */ - return (bar & 1) ? (bar & ~1) : 0; -} - -static int mc_add_fixed_mmio_resources(device_t dev, int index) -{ - unsigned long addr; - - /* PCI extended config region */ - addr = ALIGN_DOWN(get_bar(dev, PCIEXBAR), 256*MiB) / KiB; - mmio_resource(dev, index++, addr, CONFIG_SA_PCIEX_LENGTH / KiB); - - /* Memory Controller Hub */ - addr = ALIGN_DOWN(get_bar(dev, MCHBAR), 32*KiB) / KiB; - mmio_resource(dev, index++, addr, MCH_BASE_SIZE / KiB); - - return index; -} - -static bool is_imr_enabled(uint32_t imr_base_reg) -{ - return !!(imr_base_reg & (1 << 31)); -} - -static void imr_resource(device_t dev, int idx, uint32_t base, uint32_t mask) -{ - uint32_t base_k, size_k; - /* Bits 28:0 encode the base address bits 38:10, hence the KiB unit. */ - base_k = (base & 0x0fffffff); - /* Bits 28:0 encode the AND mask used for comparison, in KiB. */ - size_k = ((~mask & 0x0fffffff) + 1); - /* - * IMRs sit in lower DRAM. Mark them cacheable, otherwise we run - * out of MTRRs. Memory reserved by IMRs is not usable for host - * so mark it reserved. - */ - reserved_ram_resource(dev, idx, base_k, size_k); -} - -static int mc_add_imr_resources(device_t dev, int index) -{ - uint8_t *mchbar; - size_t i, imr_offset; - uint32_t base, mask; - - mchbar = (void *)(ALIGN_DOWN(get_bar(dev, MCHBAR), 32*KiB)); - - for (i = 0; i < MCH_NUM_IMRS; i++) { - imr_offset = i * MCH_IMR_PITCH; - base = read32(mchbar + imr_offset + MCHBAR_IMR0BASE); - mask = read32(mchbar + imr_offset + MCHBAR_IMR0MASK); - - if (is_imr_enabled(base)) - imr_resource(dev, index++, base, mask); - } - - return index; -} - - -static int mc_add_dram_resources(device_t dev, int index) -{ - unsigned long base_k, size_k; - uint32_t bgsm, bdsm, tolud, tseg; - uint64_t touud; - - bgsm = ALIGN_DOWN(pci_read_config32(dev, BGSM), MiB); - bdsm = ALIGN_DOWN(pci_read_config32(dev, BDSM), MiB); - tolud = ALIGN_DOWN(pci_read_config32(dev, TOLUD), MiB); - tseg = ALIGN_DOWN(pci_read_config32(dev, TSEG), MiB); - - /* TOUUD is naturally a 64 bit integer */ - touud = pci_read_config32(dev, TOUUD + sizeof(uint32_t)); - touud <<= 32; - touud |= ALIGN_DOWN(pci_read_config32(dev, TOUUD), MiB); - - /* 0 -> 0xa0000: 640kb of DOS memory. Not enough for anybody nowadays */ - ram_resource(dev, index++, 0, 640); - - /* 0xa0000 - 0xbffff: legacy VGA */ - mmio_resource(dev, index++, 640, 128); - - /* 0xc0000 -> 0xfffff: leave without e820 entry, as it has special uses - * 0x100000 -> top_of_ram - */ - base_k = 1024; - size_k = (tseg / KiB) - base_k; - ram_resource(dev, index++, base_k, size_k); - - /* TSEG -> BGSM */ - reserved_ram_resource(dev, index++, tseg / KiB, (bgsm - tseg) / KiB); - - /* BGSM -> BDSM */ - mmio_resource(dev, index++, bgsm / KiB, (bdsm - bgsm) / KiB); - - /* BDSM -> TOLUD */ - mmio_resource(dev, index++, bdsm / KiB, (tolud - bdsm) / KiB); - - /* 4G -> TOUUD */ - base_k = 4ULL*GiB / KiB; - size_k = (touud / KiB) - base_k; - ram_resource(dev, index++, base_k, size_k); - - - return index; -} - -static void northbridge_read_resources(device_t dev) -{ - - int index = 0; - /* Read standard PCI resources. */ - pci_dev_read_resources(dev); - - /* Add all fixed MMIO resources. */ - index = mc_add_fixed_mmio_resources(dev, index); - - /* Calculate and add DRAM resources. */ - index = mc_add_dram_resources(dev, index); - - /* Add the isolated memory ranges (IMRs). */ - mc_add_imr_resources(dev, index); - -} - -static struct device_operations northbridge_ops = { - .read_resources = northbridge_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = DEVICE_NOOP, - .enable = DEVICE_NOOP -}; - -static const unsigned short pci_device_ids[] = { - PCI_DEVICE_ID_INTEL_APL_NB, - PCI_DEVICE_ID_INTEL_GLK_NB, - 0, -}; - -static const struct pci_driver northbridge_driver __pci_driver = { - .ops = &northbridge_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .devices = pci_device_ids, -}; diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c index 87ba26bd34..5a5913a150 100644 --- a/src/soc/intel/apollolake/romstage.c +++ b/src/soc/intel/apollolake/romstage.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -80,8 +81,13 @@ static uint32_t fsp_version CAR_GLOBAL; */ static void soc_early_romstage_init(void) { - /* Set MCH base address and enable bit */ - pci_write_config32(SA_DEV_ROOT, MCHBAR, MCH_BASE_ADDRESS | 1); + static const struct sa_mmio_descriptor soc_fixed_pci_resources[] = { + { MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" }, + }; + + /* Set Fixed MMIO addresss into PCI configuration space */ + sa_set_pci_bar(soc_fixed_pci_resources, + ARRAY_SIZE(soc_fixed_pci_resources)); /* Enable decoding for HPET. Needed for FSP global pointer storage */ pci_write_config8(PCH_DEV_P2SB, P2SB_HPTC, P2SB_HPTC_ADDRESS_SELECT_0 | @@ -140,12 +146,10 @@ static bool punit_init(void) * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR). * Enable all cores here. */ - write32((void *)(MCH_BASE_ADDRESS + CORE_DISABLE_MASK), 0x0); - - void *bios_rest_cpl = (void *)(MCH_BASE_ADDRESS + BIOS_RESET_CPL); + MCHBAR32(CORE_DISABLE_MASK) = 0x0; /* P-Unit bring up */ - reg = read32(bios_rest_cpl); + reg = MCHBAR32(BIOS_RESET_CPL); if (reg == 0xffffffff) { /* P-unit not found */ printk(BIOS_DEBUG, "Punit MMIO not available\n"); @@ -155,31 +159,32 @@ static bool punit_init(void) pci_write_config8(SA_DEV_PUNIT, PCI_INTERRUPT_PIN, 0x2); /* Set PUINT IRQ to 24 and INTPIN LOCK */ - write32((void *)(MCH_BASE_ADDRESS + PUNIT_THERMAL_DEVICE_IRQ), - PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER | - PUINT_THERMAL_DEVICE_IRQ_LOCK); + MCHBAR32(PUNIT_THERMAL_DEVICE_IRQ) = + PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER | + PUINT_THERMAL_DEVICE_IRQ_LOCK; - data = read32((void *)(MCH_BASE_ADDRESS + 0x7818)); + data = MCHBAR32(0x7818); data &= 0xFFFFE01F; data |= 0x20 | 0x200; - write32((void *)(MCH_BASE_ADDRESS + 0x7818), data); + MCHBAR32(0x7818) = data; /* Stage0 BIOS Reset Complete (RST_CPL) */ - write32(bios_rest_cpl, 0x1); + enable_bios_reset_cpl(); /* - * Poll for bit 8 in same reg (RST_CPL). + * Poll for bit 8 to check if PCODE has completed its action + * in reponse to BIOS Reset complete. * We wait here till 1 ms for the bit to get set. */ stopwatch_init_msecs_expire(&sw, 1); - while (!(read32(bios_rest_cpl) & 0x100)) { + while (!(MCHBAR32(BIOS_RESET_CPL) & PCODE_INIT_DONE)) { if (stopwatch_expired(&sw)) { - printk(BIOS_DEBUG, - "Failed to set RST_CPL bit\n"); + printk(BIOS_DEBUG, "PCODE Init Done Failure\n"); return false; } udelay(100); } + return true; } diff --git a/src/soc/intel/apollolake/systemagent.c b/src/soc/intel/apollolake/systemagent.c new file mode 100644 index 0000000000..22d801e018 --- /dev/null +++ b/src/soc/intel/apollolake/systemagent.c @@ -0,0 +1,40 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corp. + * (Written by Andrey Petrov for Intel Corp.) + * (Written by Alexandru Gagniuc for Intel Corp.) + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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 +#include +#include +#include + +/* + * SoC implementation + * + * Add all known fixed memory ranges for Host Controller/Mmeory + * controller. + */ +void soc_add_fixed_mmio_resources(struct device *dev, int *index) +{ + static const struct sa_mmio_descriptor soc_fixed_resources[] = { + { PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS, CONFIG_SA_PCIEX_LENGTH, + "PCIEXBAR" }, + { MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" }, + }; + + sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources, + ARRAY_SIZE(soc_fixed_resources)); +} -- cgit v1.2.3