diff options
author | Subrata Banik <subratabanik@google.com> | 2022-06-01 07:56:40 +0000 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-06-07 12:50:29 +0000 |
commit | 801dbf4f09db70801ece813dad7fec3129759ef1 (patch) | |
tree | 44dbbf6852ddd6dd5bd2d29877f256d87c4f94f9 /src/soc/intel/common/block/cse/cse.c | |
parent | 644502311571cf315fd2cdeb080a14f87d0b9e7c (diff) |
soc/intel/cmn/cse: Implement heci_init() to initialize HECI devices
This patch implements heci_init() API that perform initialization of
all HECI devices as per MAX_HECI_DEVICES config.
BUG=none
TEST=Able to build and boot google/taeko with this change. No CSE
error observed with `heci_init()` called from romstage.
Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Ia25e18a20cc749fc7eee39b0b591d41540fc14c9
Reviewed-on: https://review.coreboot.org/c/coreboot/+/64855
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Diffstat (limited to 'src/soc/intel/common/block/cse/cse.c')
-rw-r--r-- | src/soc/intel/common/block/cse/cse.c | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 1c7e218273..8af3d9e00e 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -23,6 +23,8 @@ #include <timer.h> #include <types.h> +#define HECI_BASE_SIZE (4 * KiB) + #define MAX_HECI_MESSAGE_RETRY_COUNT 5 /* Wait up to 15 sec for HECI to get ready */ @@ -84,6 +86,24 @@ static uintptr_t get_cse_bar(pci_devfn_t dev) return bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; } +static void heci_assign_resource(pci_devfn_t dev, uintptr_t tempbar) +{ + u16 pcireg; + + /* Assign Resources */ + /* Clear BIT 1-2 of Command Register */ + pcireg = pci_read_config16(dev, PCI_COMMAND); + pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + pci_write_config16(dev, PCI_COMMAND, pcireg); + + /* Program Temporary BAR for HECI device */ + pci_write_config32(dev, PCI_BASE_ADDRESS_0, tempbar); + pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0x0); + + /* Enable Bus Master and MMIO Space */ + pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); +} + /* * Initialize the CSE device with provided temporary BAR. If BAR is 0 use a * default. This is intended for pre-mem usage only where BARs haven't been @@ -93,8 +113,6 @@ void cse_init(uintptr_t tempbar) { pci_devfn_t dev = PCH_DEV_CSE; - u16 pcireg; - /* Check if device enabled */ if (!is_cse_enabled()) return; @@ -107,18 +125,8 @@ void cse_init(uintptr_t tempbar) if (!tempbar) tempbar = HECI1_BASE_ADDRESS; - /* Assign Resources to HECI1 */ - /* Clear BIT 1-2 of Command Register */ - pcireg = pci_read_config16(dev, PCI_COMMAND); - pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - pci_write_config16(dev, PCI_COMMAND, pcireg); - - /* Program Temporary BAR for HECI1 */ - pci_write_config32(dev, PCI_BASE_ADDRESS_0, tempbar); - pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0x0); - - /* Enable Bus Master and MMIO Space */ - pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + /* Assign HECI resource and enable the resource */ + heci_assign_resource(dev, tempbar); /* Trigger HECI Reset and make Host ready for communication with CSE */ heci_reset(); @@ -1020,6 +1028,28 @@ void heci_set_to_d0i3(void) } } +/* Initialize the HECI devices. */ +void heci_init(void) +{ + for (int i = 0; i < CONFIG_MAX_HECI_DEVICES; i++) { + unsigned int devfn = PCI_DEVFN(PCH_DEV_SLOT_CSE, i); + pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + if (!is_cse_devfn_visible(devfn)) + continue; + + /* Assume it is already initialized, nothing else to do */ + if (get_cse_bar(dev)) + return; + + heci_assign_resource(dev, HECI1_BASE_ADDRESS + (i * HECI_BASE_SIZE)); + + ensure_cse_active(dev); + } + /* Trigger HECI Reset and make Host ready for communication with CSE */ + heci_reset(); +} + void cse_control_global_reset_lock(void) { /* |