From 964079f77cced3aedc468a888b6b6f32cfbec7c9 Mon Sep 17 00:00:00 2001 From: Angel Pons Date: Tue, 21 Mar 2023 16:13:36 +0100 Subject: [PATCH] mb/prodrive/atlas: Add support to read from EC EMI Implement initial support for EMI (Embedded Memory Interface), which Microchip describes as "a standard run-time mechanism for the system host to communicate with the Embedded Controller (EC) and other logical components". EMI allows the host to access regions of EC memory without requiring any assistance from the EC. For now, Atlas only uses EMI 0. This change enables EMI 0, subsequent commits will read data from it. Change-Id: Ia899ae71e97f9fc259397dfb5fb84ca06545f5d8 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/73936 Tested-by: build bot (Jenkins) Reviewed-by: Lean Sheng Tan --- src/mainboard/prodrive/atlas/Makefile.inc | 2 + src/mainboard/prodrive/atlas/bootblock.c | 6 ++ src/mainboard/prodrive/atlas/devicetree.cb | 2 + src/mainboard/prodrive/atlas/ec.c | 68 ++++++++++++++++++++++ src/mainboard/prodrive/atlas/ec.h | 23 ++++++++ src/mainboard/prodrive/atlas/mainboard.h | 10 ++++ 6 files changed, 111 insertions(+) create mode 100644 src/mainboard/prodrive/atlas/ec.c create mode 100644 src/mainboard/prodrive/atlas/ec.h create mode 100644 src/mainboard/prodrive/atlas/mainboard.h diff --git a/src/mainboard/prodrive/atlas/Makefile.inc b/src/mainboard/prodrive/atlas/Makefile.inc index 1446e54c25..3826c8f654 100644 --- a/src/mainboard/prodrive/atlas/Makefile.inc +++ b/src/mainboard/prodrive/atlas/Makefile.inc @@ -1,5 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only +all-y += ec.c + bootblock-y += bootblock.c bootblock-y += early_gpio.c diff --git a/src/mainboard/prodrive/atlas/bootblock.c b/src/mainboard/prodrive/atlas/bootblock.c index 5b1643b742..07f3bb2bde 100644 --- a/src/mainboard/prodrive/atlas/bootblock.c +++ b/src/mainboard/prodrive/atlas/bootblock.c @@ -1,10 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include +#include "ec.h" #include "gpio.h" +#include "mainboard.h" void bootblock_mainboard_early_init(void) { configure_early_gpio_pads(); + + /* Enable EMI (Embedded Memory Interface) 0 on the EC */ + ec_espi_io_program_iobase(EC_IDX_PORT, EMI_0_IOBASE_INDEX, EMI_0_IO_BASE_ADDR); } diff --git a/src/mainboard/prodrive/atlas/devicetree.cb b/src/mainboard/prodrive/atlas/devicetree.cb index e9c818106f..1c4af586a9 100644 --- a/src/mainboard/prodrive/atlas/devicetree.cb +++ b/src/mainboard/prodrive/atlas/devicetree.cb @@ -13,6 +13,8 @@ chip soc/intel/alderlake register "gen2_dec" = "0x000c0201" # EC memory map range is 0x900-0x9ff register "gen3_dec" = "0x00fc0901" + # EC EMI 0 range is 0xc00 - 0xc0f + register "gen4_dec" = "0x000c0c01" # SaGv Configuration register "sagv" = "CONFIG(ATLAS_ENABLE_SAGV) ? SaGv_Enabled : SaGv_Disabled" diff --git a/src/mainboard/prodrive/atlas/ec.c b/src/mainboard/prodrive/atlas/ec.c new file mode 100644 index 0000000000..cb022dbc88 --- /dev/null +++ b/src/mainboard/prodrive/atlas/ec.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define __SIMPLE_DEVICE__ + +#include +#include +#include +#include + +#include "ec.h" + +/* 10.7.2 ENABLE CONFIG MODE */ +static void pnp_enter_conf_state(const pnp_devfn_t dev) +{ + const u16 port = dev >> 8; + outb(0x55, port); +} + +/* 10.7.3 DISABLE CONFIG MODE */ +static void pnp_exit_conf_state(const pnp_devfn_t dev) +{ + const u16 port = dev >> 8; + outb(0xaa, port); +} + +void ec_espi_io_program_iobase(const u16 port, const u8 iobase_index, const u16 base) +{ + const pnp_devfn_t dev = PNP_DEV(port, LDN_ESPI_IO_COMPONENT); + + pnp_enter_conf_state(dev); + pnp_set_logical_device(dev); + pnp_write_config(dev, iobase_index + 2, (base & 0x00ff) >> 0); /* Addr LSB */ + pnp_write_config(dev, iobase_index + 3, (base & 0xff00) >> 8); /* Addr MSB */ + pnp_write_config(dev, iobase_index + 0, base != 0x0000); /* Valid bit */ + pnp_exit_conf_state(dev); +} + +/* TABLE 14-5: RUNTIME REGISTER SUMMARY */ +#define HOST_EC_MBOX 0x00 +#define EC_HOST_MBOX 0x01 +#define EC_ADDRESS_LSB 0x02 +#define EC_ADDRESS_MSB 0x03 +#define EC_DATA_BYTE(n) (0x04 + (n) % sizeof(u32)) +#define INTERRUPT_SOURCE_LSB 0x08 +#define INTERRUPT_SOURCE_MSB 0x09 +#define INTERRUPT_MASK_LSB 0x0a +#define INTERRUPT_MASK_MSB 0x0b +#define APPLICATION_ID 0x0c + +/* 14.8.3 ACCESS TYPES */ +enum emi_access_type { + EMI_ACCESS_8_BIT = 0, + EMI_ACCESS_16_BIT = 1, + EMI_ACCESS_32_BIT = 2, + EMI_ACCESS_32_BIT_AUTO_INC = 3, +}; + +void ec_emi_read(u8 *dest, const u16 base, const u8 region, const u16 offset, const u16 length) +{ + const u16 addr = ((region & 1) << 15) | (offset & 0x7ffc) | EMI_ACCESS_32_BIT_AUTO_INC; + + outb((addr & 0x00ff) >> 0, base + EC_ADDRESS_LSB); + outb((addr & 0xff00) >> 8, base + EC_ADDRESS_MSB); + + /* EC_ADDRESS auto-increment happens when accessing EC_DATA_BYTE_3 */ + for (u16 i = 0; i < length; i++) + dest[i] = inb(base + EC_DATA_BYTE(offset + i)); +} diff --git a/src/mainboard/prodrive/atlas/ec.h b/src/mainboard/prodrive/atlas/ec.h new file mode 100644 index 0000000000..bad9904340 --- /dev/null +++ b/src/mainboard/prodrive/atlas/ec.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef MICROCHIP_MEC152X_EC_H +#define MICROCHIP_MEC152X_EC_H + +/* + * Used references: MEC152x datasheet (Microchip document DS00003427C) + */ + +#include + +/* TABLE 3-1: BASE ADDRESS */ +#define LDN_ESPI_IO_COMPONENT 0xd + +/* TABLE 9-6: ESPI I/O BASE ADDRESS REGISTER DEFAULT VALUES */ +#define EMI_0_IOBASE_INDEX 0x68 +#define EMI_1_IOBASE_INDEX 0x6c + +void ec_espi_io_program_iobase(const u16 port, const u8 iobase_index, const u16 base); + +void ec_emi_read(u8 *dest, const u16 base, const u8 region, const u16 offset, const u16 length); + +#endif /* MICROCHIP_MEC152X_EC_H */ diff --git a/src/mainboard/prodrive/atlas/mainboard.h b/src/mainboard/prodrive/atlas/mainboard.h new file mode 100644 index 0000000000..a03cff4f47 --- /dev/null +++ b/src/mainboard/prodrive/atlas/mainboard.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef ATLAS_MAINBOARD_H +#define ATLAS_MAINBOARD_H + +/* Embedded controller settings */ +#define EC_IDX_PORT 0x2e +#define EMI_0_IO_BASE_ADDR 0xc00 + +#endif /* ATLAS_MAINBOARD_H */