soc/amd/common/block/i2c/i23c_pad_ctr: add & use I23C pad configuration

I2C bus 0..2 on Sabrina uses a different pad type which supports 1.1V
and 1.8V levels, but doesn't support 3.3V I2C levels. Compared to the
existing I2C pad control registers the bit definitions are different, so
add a separate function to configure those pads which however still has
the same function signature and is compatible with same data structs
used for the devicetree settings. PPR #57243 Rev 1.50 was used as a
reference.

TEST=None

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: Ie210c3437f2608d1e9fb99dcb151fc4190721375
Reviewed-on: https://review.coreboot.org/c/coreboot/+/61570
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
This commit is contained in:
Felix Held
2022-02-02 22:55:34 +01:00
parent 6d1db72958
commit 3bdbdb77a2
8 changed files with 140 additions and 1 deletions

View File

@@ -8,3 +8,9 @@ config SOC_AMD_COMMON_BLOCK_I2C_PAD_CTRL
help help
Select this option to add FCH I2C pad configuration functions to the Select this option to add FCH I2C pad configuration functions to the
build. build.
config SOC_AMD_COMMON_BLOCK_I23C_PAD_CTRL
bool
help
Select this option to add FCH I2C/I3C pad configuration functions to
the build.

View File

@@ -1,2 +1,3 @@
all-$(CONFIG_SOC_AMD_COMMON_BLOCK_I2C) += i2c.c all-$(CONFIG_SOC_AMD_COMMON_BLOCK_I2C) += i2c.c
all-$(CONFIG_SOC_AMD_COMMON_BLOCK_I2C_PAD_CTRL) += i2c_pad_ctrl.c all-$(CONFIG_SOC_AMD_COMMON_BLOCK_I2C_PAD_CTRL) += i2c_pad_ctrl.c
all-$(CONFIG_SOC_AMD_COMMON_BLOCK_I23C_PAD_CTRL) += i23c_pad_ctrl.c

View File

@@ -0,0 +1,55 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/acpimmio.h>
#include <amdblocks/i2c.h>
#include <console/console.h>
#include <types.h>
#include "i23c_pad_def.h"
void fch_i23c_pad_init(unsigned int bus,
enum i2c_speed speed,
const struct i2c_pad_control *ctrl)
{
uint32_t pad_ctrl;
pad_ctrl = misc_read32(MISC_I23C_PAD_CTRL(bus));
pad_ctrl &= ~I23C_PAD_CTRL_MODE_I3C_I2C_MASK;
pad_ctrl |= I23C_PAD_CTRL_MODE_I2C;
switch (ctrl->rx_level) {
case I2C_PAD_RX_NO_CHANGE:
/* Default is enabled and thresholds for 1.8V operation */
break;
case I2C_PAD_RX_OFF:
pad_ctrl &= ~I23C_PAD_CTRL_RX_SEL_MASK;
pad_ctrl |= I23C_PAD_CTRL_RX_SEL_OFF;
pad_ctrl &= ~I23C_PAD_CTRL_MODE_1_8V_1_1V_MASK;
pad_ctrl |= I23C_PAD_CTRL_MODE_1_8V;
break;
case I2C_PAD_RX_1_8V:
pad_ctrl &= ~I23C_PAD_CTRL_RX_SEL_MASK;
pad_ctrl |= I23C_PAD_CTRL_RX_SEL_ON;
pad_ctrl &= ~I23C_PAD_CTRL_MODE_1_8V_1_1V_MASK;
pad_ctrl |= I23C_PAD_CTRL_MODE_1_8V;
break;
case I2C_PAD_RX_1_1V:
pad_ctrl &= ~I23C_PAD_CTRL_RX_SEL_MASK;
pad_ctrl |= I23C_PAD_CTRL_RX_SEL_ON;
pad_ctrl &= ~I23C_PAD_CTRL_MODE_1_8V_1_1V_MASK;
pad_ctrl |= I23C_PAD_CTRL_MODE_1_1V;
break;
default:
printk(BIOS_WARNING, "Invalid I2C/I3C pad RX level for bus %u\n", bus);
break;
}
pad_ctrl &= ~I23C_PAD_CTRL_FALLSLEW_SEL_MASK;
pad_ctrl |= speed == I2C_SPEED_STANDARD ?
I23C_PAD_CTRL_FALLSLEW_SEL_STD : I23C_PAD_CTRL_FALLSLEW_SEL_LOW;
pad_ctrl &= I23C_PAD_CTRL_SLEW_N_MASK;
pad_ctrl |= I23C_PAD_CTRL_SLEW_N_FAST;
misc_write32(MISC_I23C_PAD_CTRL(bus), pad_ctrl);
}

View File

@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef AMD_BLOCK_I23C_PAD_DEF_H
#define AMD_BLOCK_I23C_PAD_DEF_H
#include <types.h>
/* MISC_I2Cx_PAD_CTRL and MISC_I23Cx_PAD_CTRL are in the same place, but have different bit
definitions. Which one is present depends on the SoC. */
#define MISC_I23C0_PAD_CTRL 0xd8
#define MISC_I23C_PAD_CTRL(bus) (MISC_I23C0_PAD_CTRL + 4 * (bus))
#define I23C_PAD_CTRL_OD_RP_SW_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
#define I23C_PAD_CTRL_OD_RP_SW_SHIFT 0
#define I23C_PAD_CTRL_RX_SEL_MASK (BIT(4) | BIT(5))
#define I23C_PAD_CTRL_RX_SHIFT 4
#define I23C_PAD_CTRL_RX_SEL_OFF (0 << I23C_PAD_CTRL_RX_SHIFT)
#define I23C_PAD_CTRL_RX_SEL_ON (3 << I23C_PAD_CTRL_RX_SHIFT)
#define I23C_PAD_CTRL_SLEW_N_MASK (BIT(6) | BIT(7))
#define I23C_PAD_CTRL_SLEW_N_SHIFT 7
#define I23C_PAD_CTRL_SLEW_N_DIS (0 << I23C_PAD_CTRL_SLEW_N_SHIFT)
#define I23C_PAD_CTRL_SLEW_N_FAST (3 << I23C_PAD_CTRL_SLEW_N_SHIFT)
#define I23C_PAD_CTRL_FALLSLEW_SEL_MASK (BIT(8) | BIT(9))
#define I23C_PAD_CTRL_FALLSLEW_SEL_SHIFT 8
#define I23C_PAD_CTRL_FALLSLEW_SEL_STD (0 << I23C_PAD_CTRL_FALLSLEW_SEL_SHIFT)
#define I23C_PAD_CTRL_FALLSLEW_SEL_LOW (3 << I23C_PAD_CTRL_FALLSLEW_SEL_SHIFT)
#define I23C_PAD_CTRL_SPIKE_RC_EN_MASK (BIT(10) | BIT(11))
#define I23C_PAD_CTRL_SPIKE_RC_EN_SHIFT 10
#define I23C_PAD_CTRL_SPIKE_RC_DIS (0 << I23C_PAD_CTRL_SPIKE_RC_EN_SHIFT)
#define I23C_PAD_CTRL_SPIKE_RC_EN (3 << I23C_PAD_CTRL_SPIKE_RC_EN_SHIFT)
#define I23C_PAD_CTRL_CAP_DOWN BIT(12)
#define I23C_PAD_CTRL_CAP_UP BIT(13)
#define I23C_PAD_CTRL_RES_DOWN BIT(14)
#define I23C_PAD_CTRL_RES_UP BIT(15)
#define I23C_PAD_CTRL_BIAS_CRT_EN_MASK (BIT(16) | BIT(17))
#define I23C_PAD_CTRL_BIAS_CRT_EN_SHIFT 16
#define I23C_PAD_CTRL_BIAS_CRT_DIS (0 << I23C_PAD_CTRL_BIAS_CRT_EN_SHIFT)
#define I23C_PAD_CTRL_BIAS_CRT_EN (3 << I23C_PAD_CTRL_BIAS_CRT_EN_SHIFT)
#define I23C_PAD_CTRL_SPARE0 BIT(18)
#define I23C_PAD_CTRL_SPARE1 BIT(19)
#define I23C_PAD_CTRL_COMP_SEL0 BIT(20) /* unused */
#define I23C_PAD_CTRL_COMP_SEL1 BIT(21) /* unused */
#define I23C_PAD_CTRL_RES_BIAS_EN_MASK (BIT(22) | BIT(23))
#define I23C_PAD_CTRL_RES_BIAS_EN_SHIFT 22
#define I23C_PAD_CTRL_RES_BIAS_T_COMP (0 << I23C_PAD_CTRL_RES_BIAS_EN_SHIFT)
#define I23C_PAD_CTRL_RES_BIAS_CONST_GM (3 << I23C_PAD_CTRL_RES_BIAS_EN_SHIFT)
#define I23C_PAD_CTRL_SLEW_P_MASK (BIT(24) | BIT(25))
#define I23C_PAD_CTRL_SLEW_P_SHIFT 24
#define I23C_PAD_CTRL_SLEW_P_DIS (0 << I23C_PAD_CTRL_SLEW_P_SHIFT)
#define I23C_PAD_CTRL_SLEW_P_EN (3 << I23C_PAD_CTRL_SLEW_P_SHIFT)
#define I23C_PAD_CTRL_MODE_I3C_I2C_MASK (BIT(26) | BIT(27))
#define I23C_PAD_CTRL_MODE_I3C_I2C_SHIFT 26
#define I23C_PAD_CTRL_MODE_I2C (0 << I23C_PAD_CTRL_MODE_I3C_I2C_SHIFT)
#define I23C_PAD_CTRL_MODE_I3C (3 << I23C_PAD_CTRL_MODE_I3C_I2C_SHIFT)
#define I23C_PAD_CTRL_MODE_1_8V_1_1V_MASK (BIT(28) | BIT(29))
#define I23C_PAD_CTRL_MODE_1_8V_1_1V_SHIFT 28
#define I23C_PAD_CTRL_MODE_1_1V (0 << I23C_PAD_CTRL_MODE_1_8V_1_1V_SHIFT)
#define I23C_PAD_CTRL_MODE_1_8V (3 << I23C_PAD_CTRL_MODE_1_8V_1_1V_SHIFT)
#define I23C_PAD_CTRL_SPIKE_C_SEL_MASK (BIT(30) | BIT(31))
#define I23C_PAD_CTRL_SPIKE_C_SEL_SHIFT 30
#define I23C_PAD_CTRL_SPIKE_C_SEL_DIS (0 << I23C_PAD_CTRL_SPIKE_C_SEL_SHIFT)
#define I23C_PAD_CTRL_SPIKE_C_SEL_EN (3 << I23C_PAD_CTRL_SPIKE_C_SEL_SHIFT)
#endif /* AMD_BLOCK_I23C_PAD_DEF_H */

View File

@@ -5,6 +5,8 @@
#include <types.h> #include <types.h>
/* MISC_I2Cx_PAD_CTRL and MISC_I23Cx_PAD_CTRL are in the same place, but have different bit
definitions. Which one is present depends on the SoC. */
#define MISC_I2C0_PAD_CTRL 0xd8 #define MISC_I2C0_PAD_CTRL 0xd8
#define MISC_I2C_PAD_CTRL(bus) (MISC_I2C0_PAD_CTRL + 4 * (bus)) #define MISC_I2C_PAD_CTRL(bus) (MISC_I2C0_PAD_CTRL + 4 * (bus))

View File

@@ -61,6 +61,7 @@ enum i2c_pad_rx_level {
I2C_PAD_RX_OFF, I2C_PAD_RX_OFF,
I2C_PAD_RX_3_3V, I2C_PAD_RX_3_3V,
I2C_PAD_RX_1_8V, I2C_PAD_RX_1_8V,
I2C_PAD_RX_1_1V,
}; };
struct i2c_pad_control { struct i2c_pad_control {
@@ -71,6 +72,10 @@ void fch_i2c_pad_init(unsigned int bus,
enum i2c_speed speed, enum i2c_speed speed,
const struct i2c_pad_control *ctrl); const struct i2c_pad_control *ctrl);
void fch_i23c_pad_init(unsigned int bus,
enum i2c_speed speed,
const struct i2c_pad_control *ctrl);
/* Helper function to perform misc I2C configuration specific to SoC. */ /* Helper function to perform misc I2C configuration specific to SoC. */
void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg); void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg);

View File

@@ -53,6 +53,7 @@ config SOC_SPECIFIC_OPTIONS
select SOC_AMD_COMMON_BLOCK_HAS_ESPI # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_HAS_ESPI # TODO: Check if this is still correct
select SOC_AMD_COMMON_BLOCK_I2C # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_I2C # TODO: Check if this is still correct
select SOC_AMD_COMMON_BLOCK_I2C_PAD_CTRL select SOC_AMD_COMMON_BLOCK_I2C_PAD_CTRL
select SOC_AMD_COMMON_BLOCK_I23C_PAD_CTRL
select SOC_AMD_COMMON_BLOCK_IOMMU # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_IOMMU # TODO: Check if this is still correct
select SOC_AMD_COMMON_BLOCK_LPC # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_LPC # TODO: Check if this is still correct
select SOC_AMD_COMMON_BLOCK_MCAX # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_MCAX # TODO: Check if this is still correct

View File

@@ -41,7 +41,12 @@ void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
if (bus >= ARRAY_SIZE(config->i2c_pad)) if (bus >= ARRAY_SIZE(config->i2c_pad))
return; return;
fch_i2c_pad_init(bus, cfg->speed, &config->i2c_pad[bus]); /* The I/O pads of I2C0..2 are the new I23C pads and the I/O pads of I2C3 still are the
same I2C pads as in Picasso and Cezanne. */
if (bus <= 2)
fch_i23c_pad_init(bus, cfg->speed, &config->i2c_pad[bus]);
else
fch_i2c_pad_init(bus, cfg->speed, &config->i2c_pad[bus]);
} }
const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs) const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs)