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 <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73936
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
This commit is contained in:
Angel Pons 2023-03-21 16:13:36 +01:00 committed by Lean Sheng Tan
parent 3ba1621dab
commit 964079f77c
6 changed files with 111 additions and 0 deletions

View File

@ -1,5 +1,7 @@
## SPDX-License-Identifier: GPL-2.0-only
all-y += ec.c
bootblock-y += bootblock.c
bootblock-y += early_gpio.c

View File

@ -1,10 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <bootblock_common.h>
#include <types.h>
#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);
}

View File

@ -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"

View File

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#define __SIMPLE_DEVICE__
#include <arch/io.h>
#include <device/pnp.h>
#include <device/pnp_ops.h>
#include <types.h>
#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));
}

View File

@ -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 <types.h>
/* 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 */

View File

@ -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 */