soc/amd/common/block/i2c: Move SoC agnostic parts into common

The logic behind I2C bus initialization, I2C MMIO base address getter
and setter, I2C bus ACPI name resolution are identical for all the AMD
SoCs. Hence moving all the SoC agnotic parts of the driver into the
common driver and just configure the SoC specific parts into individual
I2C drivers.

BUG=None
TEST=Build Dalboz and Grunt. Boot to OS in Dalboz. Ensure that the I2C
peripherals are detected as earlier in Dalboz. Verify some I2C
peripheral functionality like trackpad and touchscreen.

Change-Id: Ic9c99ec769d7d8ad7e1e566fdf42a5206657183d
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Suggested-by: Kyosti Malkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51509
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Karthikeyan Ramasubramanian
2021-03-18 23:16:29 -06:00
committed by Martin Roth
parent 0dbea48d46
commit 4f87ae1d4a
14 changed files with 231 additions and 226 deletions

View File

@@ -14,7 +14,7 @@
#include <fsp/api.h>
/* Supplied by i2c.c */
extern struct device_operations picasso_i2c_mmio_ops;
extern struct device_operations soc_amd_i2c_mmio_ops;
/* Supplied by uart.c */
extern struct device_operations picasso_uart_mmio_ops;
@@ -51,7 +51,7 @@ static void set_mmio_dev_ops(struct device *dev)
case APU_I2C2_BASE:
case APU_I2C3_BASE:
case APU_I2C4_BASE:
dev->ops = &picasso_i2c_mmio_ops;
dev->ops = &soc_amd_i2c_mmio_ops;
break;
case APU_UART0_BASE:
case APU_UART1_BASE:

View File

@@ -105,7 +105,7 @@ struct soc_amd_picasso_config {
* register i2c_scl_reset = (GPIO_I2C0_SCL | GPIO_I2C3_SCL)
*/
u8 i2c_scl_reset;
struct dw_i2c_bus_config i2c[I2C_MASTER_DEV_COUNT];
struct dw_i2c_bus_config i2c[I2C_CTRLR_COUNT];
enum {
I2S_PINS_MAX_HDA = 0, /* HDA w/reset 3xSDI, SW w/Data0 */
I2S_PINS_MAX_MHDA = 1, /* HDA no reset 3xSDI, SW w/Data0-1 */

View File

@@ -13,6 +13,7 @@
#include <amdblocks/reset.h>
#include <amdblocks/acpimmio.h>
#include <amdblocks/acpi.h>
#include <amdblocks/i2c.h>
#include <amdblocks/smi.h>
#include <soc/acpi.h>
#include <soc/cpu.h>

View File

@@ -1,11 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/mmio.h>
#include <acpi/acpi.h>
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <drivers/i2c/designware/dw_i2c.h>
#include <amdblocks/acpimmio.h>
#include <amdblocks/i2c.h>
#include <soc/i2c.h>
@@ -15,130 +10,69 @@
#include "chip.h"
#if ENV_X86
static const uintptr_t i2c_bus_address[I2C_MASTER_DEV_COUNT + I2C_SLAVE_DEV_COUNT] = {
0,
0,
APU_I2C2_BASE,
APU_I2C3_BASE,
APU_I2C4_BASE, /* Can only be used in slave mode */
/* Preferably keep all the I2C controllers operating in a specific mode together. */
static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
{ I2C_MASTER_MODE, 0, "" },
{ I2C_MASTER_MODE, 0, "" },
{ I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" },
{ I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" },
{ I2C_PERIPHERAL_MODE, APU_I2C4_BASE, "I2C4" } /* Can only be used in peripheral mode */
};
#else
static uintptr_t i2c_bus_address[I2C_MASTER_DEV_COUNT + I2C_SLAVE_DEV_COUNT];
#endif
static struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
{ I2C_MASTER_MODE, 0, ""},
{ I2C_MASTER_MODE, 0, "" },
{ I2C_MASTER_MODE, 0, "" },
{ I2C_MASTER_MODE, 0, "" },
{ I2C_PERIPHERAL_MODE, 0, "" },
};
uintptr_t dw_i2c_base_address(unsigned int bus)
{
if (bus >= ARRAY_SIZE(i2c_bus_address))
return 0;
return i2c_bus_address[bus];
}
#if !ENV_X86
void i2c_set_bar(unsigned int bus, uintptr_t bar)
{
if (bus >= ARRAY_SIZE(i2c_bus_address)) {
if (bus >= ARRAY_SIZE(i2c_ctrlr)) {
printk(BIOS_ERR, "Error: i2c index out of bounds: %u.", bus);
return;
}
i2c_bus_address[bus] = bar;
i2c_ctrlr[bus].bar = bar;
}
#endif
const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus)
{
const struct soc_amd_picasso_config *config;
if (bus >= ARRAY_SIZE(config->i2c))
return NULL;
/* config is not NULL; if it was, config_of_soc calls die() internally */
config = config_of_soc();
return &config->i2c[bus];
}
static const char *i2c_acpi_name(const struct device *dev)
{
if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[2])
return "I2C2";
else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[3])
return "I2C3";
else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[4])
return "I2C4";
return NULL;
}
int dw_i2c_soc_dev_to_bus(const struct device *dev)
{
if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[2])
return 2;
else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[3])
return 3;
else if ((uintptr_t)dev->path.mmio.addr == i2c_bus_address[4])
return 4;
return -1;
}
__weak void mainboard_i2c_override(int bus, uint32_t *pad_settings) { }
static void dw_i2c_soc_init(bool is_early_init)
void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
{
size_t i;
const struct soc_amd_picasso_config *config;
uint32_t pad_ctrl;
int misc_reg;
/* config is not NULL; if it was, config_of_soc calls die() internally */
config = config_of_soc();
misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * bus;
pad_ctrl = misc_read32(misc_reg);
for (i = I2C_MASTER_START_INDEX; i < ARRAY_SIZE(config->i2c); i++) {
const struct dw_i2c_bus_config *cfg = &config->i2c[i];
pad_ctrl &= ~I2C_PAD_CTRL_NG_MASK;
pad_ctrl |= I2C_PAD_CTRL_NG_NORMAL;
if (cfg->early_init != is_early_init)
continue;
pad_ctrl &= ~I2C_PAD_CTRL_RX_SEL_MASK;
pad_ctrl |= I2C_PAD_CTRL_RX_SEL_3_3V;
if (dw_i2c_init(i, cfg)) {
printk(BIOS_ERR, "Failed to init i2c bus %zd\n", i);
continue;
}
pad_ctrl &= ~I2C_PAD_CTRL_FALLSLEW_MASK;
pad_ctrl |= cfg->speed == I2C_SPEED_STANDARD ? I2C_PAD_CTRL_FALLSLEW_STD :
I2C_PAD_CTRL_FALLSLEW_LOW;
pad_ctrl |= I2C_PAD_CTRL_FALLSLEW_EN;
misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * i;
pad_ctrl = misc_read32(misc_reg);
pad_ctrl &= ~I2C_PAD_CTRL_NG_MASK;
pad_ctrl |= I2C_PAD_CTRL_NG_NORMAL;
pad_ctrl &= ~I2C_PAD_CTRL_RX_SEL_MASK;
pad_ctrl |= I2C_PAD_CTRL_RX_SEL_3_3V;
pad_ctrl &= ~I2C_PAD_CTRL_FALLSLEW_MASK;
pad_ctrl |= cfg->speed == I2C_SPEED_STANDARD
? I2C_PAD_CTRL_FALLSLEW_STD
: I2C_PAD_CTRL_FALLSLEW_LOW;
pad_ctrl |= I2C_PAD_CTRL_FALLSLEW_EN;
mainboard_i2c_override(i, &pad_ctrl);
misc_write32(misc_reg, pad_ctrl);
}
mainboard_i2c_override(bus, &pad_ctrl);
misc_write32(misc_reg, pad_ctrl);
}
void i2c_soc_early_init(void)
const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs)
{
dw_i2c_soc_init(true);
*num_ctrlrs = ARRAY_SIZE(i2c_ctrlr);
return i2c_ctrlr;
}
void i2c_soc_init(void)
const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses)
{
dw_i2c_soc_init(false);
}
const struct soc_amd_picasso_config *config = config_of_soc();
struct device_operations picasso_i2c_mmio_ops = {
/* TODO(teravest): Move I2C resource info here. */
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.scan_bus = scan_smbus,
.acpi_name = i2c_acpi_name,
.acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt,
};
*num_buses = ARRAY_SIZE(config->i2c);
return config->i2c;
}

View File

@@ -39,7 +39,8 @@
*/
#define I2C_MASTER_DEV_COUNT 4
#define I2C_MASTER_START_INDEX 2
#define I2C_SLAVE_DEV_COUNT 1
#define I2C_PERIPHERAL_DEV_COUNT 1
#define I2C_CTRLR_COUNT (I2C_MASTER_DEV_COUNT + I2C_PERIPHERAL_DEV_COUNT)
#if ENV_X86

View File

@@ -181,12 +181,6 @@ void enable_aoac_devices(void);
void wait_for_aoac_enabled(unsigned int dev);
void sb_clk_output_48Mhz(void);
/* Initialize all the i2c buses that are marked with early init. */
void i2c_soc_early_init(void);
/* Initialize all the i2c buses that are not marked with early init. */
void i2c_soc_init(void);
/* Allow the board to change the default I2C pad configuration */
void mainboard_i2c_override(int bus, uint32_t *pad_settings);