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 <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51025
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Zheng Bao 2021-03-16 15:28:49 +08:00 committed by Martin Roth
parent 7a0b9c5e73
commit b0f00ed426
8 changed files with 172 additions and 0 deletions

View file

@ -39,6 +39,7 @@ config SOC_SPECIFIC_OPTIONS
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC select SOC_AMD_COMMON_BLOCK_DATA_FABRIC
select SOC_AMD_COMMON_BLOCK_GRAPHICS select SOC_AMD_COMMON_BLOCK_GRAPHICS
select SOC_AMD_COMMON_BLOCK_HAS_ESPI select SOC_AMD_COMMON_BLOCK_HAS_ESPI
select SOC_AMD_COMMON_BLOCK_I2C
select SOC_AMD_COMMON_BLOCK_LPC select SOC_AMD_COMMON_BLOCK_LPC
select SOC_AMD_COMMON_BLOCK_NONCAR select SOC_AMD_COMMON_BLOCK_NONCAR
select SOC_AMD_COMMON_BLOCK_PCI select SOC_AMD_COMMON_BLOCK_PCI

View file

@ -11,19 +11,23 @@ all-y += aoac.c
bootblock-y += bootblock.c bootblock-y += bootblock.c
bootblock-y += early_fch.c bootblock-y += early_fch.c
bootblock-y += i2c.c
bootblock-y += gpio.c bootblock-y += gpio.c
bootblock-y += reset.c bootblock-y += reset.c
bootblock-y += uart.c bootblock-y += uart.c
verstage-y += i2c.c
verstage_x86-y += gpio.c verstage_x86-y += gpio.c
verstage_x86-y += reset.c verstage_x86-y += reset.c
verstage_x86-y += uart.c verstage_x86-y += uart.c
romstage-y += i2c.c
romstage-y += gpio.c romstage-y += gpio.c
romstage-y += reset.c romstage-y += reset.c
romstage-y += romstage.c romstage-y += romstage.c
romstage-y += uart.c romstage-y += uart.c
ramstage-y += i2c.c
ramstage-y += acpi.c ramstage-y += acpi.c
ramstage-y += chip.c ramstage-y += chip.c
ramstage-y += cpu.c ramstage-y += cpu.c

View file

@ -4,9 +4,13 @@
#define CEZANNE_CHIP_H #define CEZANNE_CHIP_H
#include <amdblocks/chip.h> #include <amdblocks/chip.h>
#include <soc/i2c.h>
#include <drivers/i2c/designware/dw_i2c.h>
struct soc_amd_cezanne_config { struct soc_amd_cezanne_config {
struct soc_amd_common_config common_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 */ #endif /* CEZANNE_CHIP_H */

View file

@ -4,10 +4,33 @@
#include <amdblocks/espi.h> #include <amdblocks/espi.h>
#include <amdblocks/lpc.h> #include <amdblocks/lpc.h>
#include <amdblocks/smbus.h> #include <amdblocks/smbus.h>
#include <amdblocks/i2c.h>
#include <console/console.h> #include <console/console.h>
#include <soc/i2c.h>
#include <soc/southbridge.h> #include <soc/southbridge.h>
#include <soc/uart.h> #include <soc/uart.h>
#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 */ /* Before console init */
void fch_pre_init(void) void fch_pre_init(void)
{ {
@ -19,6 +42,7 @@ void fch_pre_init(void)
fch_enable_legacy_io(); fch_enable_legacy_io();
fch_disable_legacy_dma_io(); fch_disable_legacy_dma_io();
enable_aoac_devices(); enable_aoac_devices();
reset_i2c_peripherals();
/* /*
* On reset Range_0 defaults to enabled. We want to start with a clean * On reset Range_0 defaults to enabled. We want to start with a clean

72
src/soc/amd/cezanne/i2c.c Normal file
View file

@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/acpimmio.h>
#include <amdblocks/i2c.h>
#include <soc/i2c.h>
#include <soc/southbridge.h>
#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;
}

View file

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <soc/gpio.h>
#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 */

View file

@ -16,11 +16,22 @@
/* FCH AL2AHB Registers */ /* FCH AL2AHB Registers */
#define ALINK_AHB_ADDRESS 0xfedc0000 #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_I2C0_BASE 0xfedc2000
#define APU_I2C1_BASE 0xfedc3000 #define APU_I2C1_BASE 0xfedc3000
#define APU_I2C2_BASE 0xfedc4000 #define APU_I2C2_BASE 0xfedc4000
#define APU_I2C3_BASE 0xfedc5000 #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_DMAC0_BASE 0xfedc7000
#define APU_DMAC1_BASE 0xfedc8000 #define APU_DMAC1_BASE 0xfedc8000
#define APU_UART0_BASE 0xfedc9000 #define APU_UART0_BASE 0xfedc9000

View file

@ -65,6 +65,33 @@
#define FCH_LEGACY_UART_DECODE (ALINK_AHB_ADDRESS + 0x20) /* 0xfedc0020 */ #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 */ /* FCH AOAC device offsets for AOAC_DEV_D3_CTL/AOAC_DEV_D3_STATE */
#define FCH_AOAC_DEV_CLK_GEN 0 #define FCH_AOAC_DEV_CLK_GEN 0
#define FCH_AOAC_DEV_I2C0 5 #define FCH_AOAC_DEV_I2C0 5
@ -89,4 +116,7 @@ void fch_final(void *chip_info);
void enable_aoac_devices(void); void enable_aoac_devices(void);
void wait_for_aoac_enabled(unsigned int dev); 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 */ #endif /* AMD_CEZANNE_SOUTHBRIDGE_H */