From b0f00ed4268573269c5f2085da1c92566768ece3 Mon Sep 17 00:00:00 2001 From: Zheng Bao Date: Tue, 16 Mar 2021 15:28:49 +0800 Subject: soc/amd/cezanne: Get I2C specific code for cezanne Add macros, settings and callbacks to support I2C for cezanne. Change-Id: Ic480681d4b7c6fb8591e729090e4faeb5fccf800 Signed-off-by: Zheng Bao Reviewed-on: https://review.coreboot.org/c/coreboot/+/51025 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/amd/cezanne/Kconfig | 1 + src/soc/amd/cezanne/Makefile.inc | 4 ++ src/soc/amd/cezanne/chip.h | 4 ++ src/soc/amd/cezanne/early_fch.c | 24 +++++++++ src/soc/amd/cezanne/i2c.c | 72 +++++++++++++++++++++++++++ src/soc/amd/cezanne/include/soc/i2c.h | 26 ++++++++++ src/soc/amd/cezanne/include/soc/iomap.h | 11 ++++ src/soc/amd/cezanne/include/soc/southbridge.h | 30 +++++++++++ 8 files changed, 172 insertions(+) create mode 100644 src/soc/amd/cezanne/i2c.c create mode 100644 src/soc/amd/cezanne/include/soc/i2c.h (limited to 'src/soc') diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig index ab305a7506..119889db36 100644 --- a/src/soc/amd/cezanne/Kconfig +++ b/src/soc/amd/cezanne/Kconfig @@ -39,6 +39,7 @@ config SOC_SPECIFIC_OPTIONS select SOC_AMD_COMMON_BLOCK_DATA_FABRIC select SOC_AMD_COMMON_BLOCK_GRAPHICS select SOC_AMD_COMMON_BLOCK_HAS_ESPI + select SOC_AMD_COMMON_BLOCK_I2C select SOC_AMD_COMMON_BLOCK_LPC select SOC_AMD_COMMON_BLOCK_NONCAR select SOC_AMD_COMMON_BLOCK_PCI diff --git a/src/soc/amd/cezanne/Makefile.inc b/src/soc/amd/cezanne/Makefile.inc index f099ad81d8..91a16d89ba 100644 --- a/src/soc/amd/cezanne/Makefile.inc +++ b/src/soc/amd/cezanne/Makefile.inc @@ -11,19 +11,23 @@ all-y += aoac.c bootblock-y += bootblock.c bootblock-y += early_fch.c +bootblock-y += i2c.c bootblock-y += gpio.c bootblock-y += reset.c bootblock-y += uart.c +verstage-y += i2c.c verstage_x86-y += gpio.c verstage_x86-y += reset.c verstage_x86-y += uart.c +romstage-y += i2c.c romstage-y += gpio.c romstage-y += reset.c romstage-y += romstage.c romstage-y += uart.c +ramstage-y += i2c.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c diff --git a/src/soc/amd/cezanne/chip.h b/src/soc/amd/cezanne/chip.h index b4e94a4478..76ecbfa057 100644 --- a/src/soc/amd/cezanne/chip.h +++ b/src/soc/amd/cezanne/chip.h @@ -4,9 +4,13 @@ #define CEZANNE_CHIP_H #include +#include +#include struct soc_amd_cezanne_config { struct soc_amd_common_config common_config; + u8 i2c_scl_reset; + struct dw_i2c_bus_config i2c[I2C_CTRLR_COUNT]; }; #endif /* CEZANNE_CHIP_H */ diff --git a/src/soc/amd/cezanne/early_fch.c b/src/soc/amd/cezanne/early_fch.c index cdb1f12aad..0bab87ff8a 100644 --- a/src/soc/amd/cezanne/early_fch.c +++ b/src/soc/amd/cezanne/early_fch.c @@ -4,10 +4,33 @@ #include #include #include +#include #include +#include #include #include +#include "chip.h" + +/* This table is for the initial conversion of all SCL pins to input with no pull. */ +static const struct soc_i2c_scl_pin i2c_scl_pins[] = { + { PAD_GPI(I2C0_SCL_PIN, PULL_NONE), GPIO_I2C0_SCL }, + { PAD_GPI(I2C1_SCL_PIN, PULL_NONE), GPIO_I2C1_SCL }, + { PAD_GPI(I2C2_SCL_PIN, PULL_NONE), GPIO_I2C2_SCL }, + { PAD_GPI(I2C3_SCL_PIN, PULL_NONE), GPIO_I2C3_SCL }, +}; + +static void reset_i2c_peripherals(void) +{ + const struct soc_amd_cezanne_config *cfg = config_of_soc(); + struct soc_i2c_peripheral_reset_info reset_info; + + reset_info.i2c_scl_reset_mask = cfg->i2c_scl_reset & GPIO_I2C_MASK; + reset_info.i2c_scl = i2c_scl_pins; + reset_info.num_pins = ARRAY_SIZE(i2c_scl_pins); + sb_reset_i2c_peripherals(&reset_info); +} + /* Before console init */ void fch_pre_init(void) { @@ -19,6 +42,7 @@ void fch_pre_init(void) fch_enable_legacy_io(); fch_disable_legacy_dma_io(); enable_aoac_devices(); + reset_i2c_peripherals(); /* * On reset Range_0 defaults to enabled. We want to start with a clean diff --git a/src/soc/amd/cezanne/i2c.c b/src/soc/amd/cezanne/i2c.c new file mode 100644 index 0000000000..ec6cb0382d --- /dev/null +++ b/src/soc/amd/cezanne/i2c.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include "chip.h" + +#if ENV_X86 +static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = { + { I2C_MASTER_MODE, APU_I2C0_BASE, "I2C0" }, + { I2C_MASTER_MODE, APU_I2C1_BASE, "I2C1" }, + { I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" }, + { I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" } +}; +#else +static struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_CNT] = { + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, 0, "" }, + { I2C_MASTER_MODE, 0, "" } +}; + +void i2c_set_bar(unsigned int bus, uintptr_t bar) +{ + if (bus >= ARRAY_SIZE(i2c_ctrlr)) { + printk(BIOS_ERR, "Error: i2c index out of bounds: %u.", bus); + return; + } + + i2c_ctrlr[bus].bar = bar; +} +#endif + +__weak void mainboard_i2c_override(int bus, uint32_t *pad_settings) { } + +void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg) +{ + uint32_t pad_ctrl; + int misc_reg; + + misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * bus; + 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(bus, &pad_ctrl); + misc_write32(misc_reg, pad_ctrl); +} + +const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs) +{ + *num_ctrlrs = ARRAY_SIZE(i2c_ctrlr); + return i2c_ctrlr; +} + +const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses) +{ + const struct soc_amd_cezanne_config *config = config_of_soc(); + + *num_buses = ARRAY_SIZE(config->i2c); + return config->i2c; +} diff --git a/src/soc/amd/cezanne/include/soc/i2c.h b/src/soc/amd/cezanne/include/soc/i2c.h new file mode 100644 index 0000000000..d69925dfc3 --- /dev/null +++ b/src/soc/amd/cezanne/include/soc/i2c.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#ifndef AMD_CEZANNE_I2C_H +#define AMD_CEZANNE_I2C_H + +#define GPIO_I2C0_SCL BIT(0) +#define GPIO_I2C1_SCL BIT(1) +#define GPIO_I2C2_SCL BIT(2) +#define GPIO_I2C3_SCL BIT(3) +#define GPIO_I2C_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + + +#define I2C0_SCL_PIN GPIO_145 +#define I2C1_SCL_PIN GPIO_147 +#define I2C2_SCL_PIN GPIO_113 +#define I2C3_SCL_PIN GPIO_19 + +#define I2C0_SCL_PIN_IOMUX_GPIOxx GPIO_145_IOMUX_GPIOxx +#define I2C1_SCL_PIN_IOMUX_GPIOxx GPIO_147_IOMUX_GPIOxx +#define I2C2_SCL_PIN_IOMUX_GPIOxx GPIO_113_IOMUX_GPIOxx +#define I2C3_SCL_PIN_IOMUX_GPIOxx GPIO_19_IOMUX_GPIOxx + + +#endif /* AMD_CEZANNE_I2C_H */ diff --git a/src/soc/amd/cezanne/include/soc/iomap.h b/src/soc/amd/cezanne/include/soc/iomap.h index 3a84fae4c7..8f33794acf 100644 --- a/src/soc/amd/cezanne/include/soc/iomap.h +++ b/src/soc/amd/cezanne/include/soc/iomap.h @@ -16,11 +16,22 @@ /* FCH AL2AHB Registers */ #define ALINK_AHB_ADDRESS 0xfedc0000 +#define I2C_MASTER_DEV_COUNT 4 +#define I2C_MASTER_START_INDEX 0 +#define I2C_PERIPHERAL_DEV_COUNT 0 /* TODO: Only master for now. */ +#define I2C_CTRLR_COUNT (I2C_MASTER_DEV_COUNT + I2C_PERIPHERAL_DEV_COUNT) + #define APU_I2C0_BASE 0xfedc2000 #define APU_I2C1_BASE 0xfedc3000 #define APU_I2C2_BASE 0xfedc4000 #define APU_I2C3_BASE 0xfedc5000 +/* I2C parameters for lpc_read_resources */ +#define I2C_BASE_ADDRESS APU_I2C2_BASE +#define I2C_DEVICE_SIZE 0x00001000 +#define I2C_DEVICE_COUNT (I2C_MASTER_DEV_COUNT \ + - I2C_MASTER_START_INDEX) + #define APU_DMAC0_BASE 0xfedc7000 #define APU_DMAC1_BASE 0xfedc8000 #define APU_UART0_BASE 0xfedc9000 diff --git a/src/soc/amd/cezanne/include/soc/southbridge.h b/src/soc/amd/cezanne/include/soc/southbridge.h index 0b5882eb6c..05dd9b36e3 100644 --- a/src/soc/amd/cezanne/include/soc/southbridge.h +++ b/src/soc/amd/cezanne/include/soc/southbridge.h @@ -65,6 +65,33 @@ #define FCH_LEGACY_UART_DECODE (ALINK_AHB_ADDRESS + 0x20) /* 0xfedc0020 */ +#define MISC_I2C0_PAD_CTRL 0xd8 +#define MISC_I2C1_PAD_CTRL 0xdc +#define MISC_I2C2_PAD_CTRL 0xe0 +#define MISC_I2C3_PAD_CTRL 0xe4 +#define I2C_PAD_CTRL_NG_MASK (BIT(0) + BIT(1) + BIT(2) + BIT(3)) +#define I2C_PAD_CTRL_NG_NORMAL 0xc +#define I2C_PAD_CTRL_RX_SEL_MASK (BIT(4) + BIT(5)) +#define I2C_PAD_CTRL_RX_SHIFT 4 +#define I2C_PAD_CTRL_RX_SEL_OFF (0 << I2C_PAD_CTRL_RX_SHIFT) +#define I2C_PAD_CTRL_RX_SEL_3_3V (1 << I2C_PAD_CTRL_RX_SHIFT) +#define I2C_PAD_CTRL_RX_SEL_1_8V (3 << I2C_PAD_CTRL_RX_SHIFT) +#define I2C_PAD_CTRL_PULLDOWN_EN BIT(6) +#define I2C_PAD_CTRL_FALLSLEW_MASK (BIT(7) + BIT(8)) +#define I2C_PAD_CTRL_FALLSLEW_SHIFT 7 +#define I2C_PAD_CTRL_FALLSLEW_STD (0 << I2C_PAD_CTRL_FALLSLEW_SHIFT) +#define I2C_PAD_CTRL_FALLSLEW_LOW (1 << I2C_PAD_CTRL_FALLSLEW_SHIFT) +#define I2C_PAD_CTRL_FALLSLEW_EN BIT(9) +#define I2C_PAD_CTRL_SPIKE_RC_EN BIT(10) +#define I2C_PAD_CTRL_SPIKE_RC_SEL BIT(11) /* 0 = 50ns, 1 = 20ns */ +#define I2C_PAD_CTRL_CAP_DOWN BIT(12) +#define I2C_PAD_CTRL_CAP_UP BIT(13) +#define I2C_PAD_CTRL_RES_DOWN BIT(14) +#define I2C_PAD_CTRL_RES_UP BIT(15) +#define I2C_PAD_CTRL_BIOS_CRT_EN BIT(16) +#define I2C_PAD_CTRL_SPARE0 BIT(17) +#define I2C_PAD_CTRL_SPARE1 BIT(18) + /* FCH AOAC device offsets for AOAC_DEV_D3_CTL/AOAC_DEV_D3_STATE */ #define FCH_AOAC_DEV_CLK_GEN 0 #define FCH_AOAC_DEV_I2C0 5 @@ -89,4 +116,7 @@ void fch_final(void *chip_info); void enable_aoac_devices(void); void wait_for_aoac_enabled(unsigned int dev); +/* Allow the board to change the default I2C pad configuration */ +void mainboard_i2c_override(int bus, uint32_t *pad_settings); + #endif /* AMD_CEZANNE_SOUTHBRIDGE_H */ -- cgit v1.2.3