blob: c74e88fd128e1c7da0c24a22816428c4a4ee60d2 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#include "psp_verstage.h"
#include <amdblocks/acpimmio.h>
#include <amdblocks/espi.h>
#include <amdblocks/i2c.h>
#include <amdblocks/spi.h>
#include <arch/exception.h>
#include <arch/hlt.h>
#include <arch/io.h>
#include <bl_uapp/bl_errorcodes_public.h>
#include <bl_uapp/bl_syscall_public.h>
#include <console/console.h>
#include <soc/i2c.h>
#include <soc/southbridge.h>
#include <stdint.h>
static void i2c3_set_bar(void *bar)
{
i2c_set_bar(3, (uintptr_t)bar);
}
static void i2c2_set_bar(void *bar)
{
i2c_set_bar(2, (uintptr_t)bar);
}
static void espi_set_bar(void *bar)
{
espi_update_static_bar((uintptr_t)bar);
}
static void iomux_set_bar(void *bar)
{
acpimmio_iomux = bar;
}
static void misc_set_bar(void *bar)
{
acpimmio_misc = bar;
}
static void gpio_set_bar(void *bar)
{
acpimmio_gpio0 = bar;
}
static uintptr_t io_bar;
static void io_set_bar(void *bar)
{
io_bar = (uintptr_t)bar;
}
u8 io_read8(u16 reg)
{
return read8((void *)(io_bar + reg));
}
void io_write8(u16 reg, u8 value)
{
write8((void *)(io_bar + reg), value);
}
static void aoac_set_bar(void *bar)
{
acpimmio_aoac = bar;
}
static struct {
const char *name;
struct {
enum fch_io_device device;
uint32_t arg0;
} args;
void (*set_bar)(void *bar);
void *_bar;
} bar_map[] = {
{"IOMUX", {FCH_IO_DEVICE_IOMUX}, iomux_set_bar},
{"MISC", {FCH_IO_DEVICE_MISC}, misc_set_bar},
{"GPIO", {FCH_IO_DEVICE_GPIO}, gpio_set_bar},
{"IO", {FCH_IO_DEVICE_IOPORT}, io_set_bar},
{"eSPI", {FCH_IO_DEVICE_ESPI}, espi_set_bar},
{"I2C2", {FCH_IO_DEVICE_I2C, 2}, i2c2_set_bar},
{"I2C3", {FCH_IO_DEVICE_I2C, 3}, i2c3_set_bar},
{"SPI", {FCH_IO_DEVICE_SPI}, spi_set_base},
{"AOAC", {FCH_IO_DEVICE_AOAC}, aoac_set_bar},
};
uintptr_t *map_spi_rom(void)
{
uintptr_t *addr = NULL;
struct spirom_info spi = {0};
if (svc_get_spi_rom_info(&spi))
printk(BIOS_DEBUG, "Error getting SPI ROM info.\n");
if (spi.SpiBiosSmnBase != 0)
if (svc_map_spi_rom(spi.SpiBiosSmnBase, CONFIG_ROM_SIZE, (void **)&addr))
printk(BIOS_DEBUG, "Error mapping SPI ROM to address.\n");
return addr;
}
static uint32_t map_fch_devices(void)
{
void *bar;
uint32_t err;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(bar_map); ++i) {
err = svc_map_fch_dev(bar_map[i].args.device, bar_map[i].args.arg0, 0, &bar);
if (err) {
printk(BIOS_ERR, "Failed to map %s: %u\n", bar_map[i].name, err);
return err;
}
bar_map[i]._bar = bar;
bar_map[i].set_bar(bar);
}
return BL_OK;
}
uint32_t unmap_fch_devices(void)
{
void *bar;
uint32_t err, rtn = BL_OK;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(bar_map); ++i) {
bar = bar_map[i]._bar;
if (!bar)
continue;
err = svc_unmap_fch_dev(bar_map[i].args.device, bar);
if (err) {
printk(BIOS_ERR, "Failed to unmap %s: %u\n", bar_map[i].name, err);
rtn = err;
} else {
bar_map[i]._bar = NULL;
bar_map[i].set_bar(NULL);
}
}
return rtn;
}
uint32_t verstage_soc_early_init(void)
{
return map_fch_devices();
}
void verstage_soc_init(void)
{
if (CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI))
espi_setup();
enable_aoac_devices();
printk(BIOS_DEBUG, "Setting up i2c\n");
i2c_soc_early_init();
printk(BIOS_DEBUG, "i2c setup\n");
}