ec/google/chromeec: Add indexed IO support

Add support for indexed IO for ec communication, Indexed I/O allows
memory access using a single I/O port base address usually called an
index register and another port address called a data register.

BUG=b:379224648
TEST= able to build nissa/trulo.

Change-Id: I6c1aab3fc914eb5af2736a8ea3adf447040905e0
Signed-off-by: Jayvik Desai <jayvik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85449
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Caveh Jalali <caveh@chromium.org>
Reviewed-by: Subrata Banik <subratabanik@google.com>
This commit is contained in:
Jayvik Desai 2024-12-03 14:19:52 +05:30 committed by Subrata Banik
commit 1e90bbadfa
2 changed files with 41 additions and 0 deletions

View file

@ -60,6 +60,30 @@ config EC_GOOGLE_CHROMEEC_ESPI
this option simply enables the LPC EC code. The eSPI device
still needs to correctly configure the bus transactions.
config EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO
depends on EC_GOOGLE_CHROMEEC && ARCH_X86
def_bool n
help
Google Chrome EC enable support for indexed I/O access.
Indexed I/O allows devices with multiple memory locations to be
accessed using a single I/O port base address and an index register.
A separate data register, typically located at the address
immediately following the index register, is used for sending and
receiving data to the device.
Ensure port address and gen3_dec values are correct when selecting
this configuration.
config EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO_PORT
depends on EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO
hex
default 0x380
help
Google Chrome EC indexed I/O access address.
Index register port address for memory mapped indexed IO access
config EC_GOOGLE_CHROMEEC_LPC
depends on ARCH_X86 # Needs Plug-and-play.
def_bool n

View file

@ -52,6 +52,15 @@ static inline u8 read_byte(u16 port)
return byte;
}
#if CONFIG(EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO)
/* Read singe byte and return byte read using indexed IO*/
static inline u8 read_byte_indexed_io(u8 offset)
{
outb(offset, CONFIG_EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO_PORT);
return inb(CONFIG_EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO_PORT + 1);
}
#endif
/*
* Write bytes to a given LPC-mapped address.
*
@ -156,6 +165,10 @@ static int google_chromeec_command_version(void)
printk(BIOS_ERR, "Error reading memmap data.\n");
return -1;
}
#elif CONFIG(EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO)
id1 = read_byte_indexed_io(EC_MEMMAP_ID);
id2 = read_byte_indexed_io(EC_MEMMAP_ID + 1);
flags = read_byte_indexed_io(EC_MEMMAP_HOST_CMD_FLAGS);
#else
id1 = read_byte(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID);
id2 = read_byte(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1);
@ -358,7 +371,11 @@ static int google_chromeec_command_v1(struct chromeec_command *cec_command)
/* Return the byte of EC switch states */
uint8_t google_chromeec_get_switches(void)
{
#if CONFIG(EC_GOOGLE_CHROMEEC_MEMMAP_INDEXED_IO)
return read_byte_indexed_io(EC_MEMMAP_SWITCHES);
#else
return read_byte(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES);
#endif
}
void google_chromeec_ioport_range(uint16_t *out_base, size_t *out_size)