diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2021-05-18 01:25:51 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-05-19 15:37:39 +0000 |
commit | 224b578420a5d42e16ec6a8285971d34d8cdafac (patch) | |
tree | eb7a334ae4d2f9599815aaa886d8c2c3cd396327 | |
parent | 0e099eaf83c732599b47f2d5301871d6076857a8 (diff) | |
download | coreboot-224b578420a5d42e16ec6a8285971d34d8cdafac.tar.xz |
soc/amd/cezanne/fch: add PCIe GPP clock generator configuration settings
I'm not 100% sure if this should rather be duplicated from Picasso or
commonized. Checked with the docs and this won't be compatible with
Stoneyridge and one future product's PPR lacked the corresponding
register. Some other chip has a compatible register layout, but a
different number of PCIe GPP clock outputs, so the common code would
need to use some SoC-dependent defines and possibly a SoC-specific
lookup table for the mapping which is also not that great.
TEST=Checked Cezanne PPR
Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: I6b6d0cb8d7eb0288d8a18fcb975dc377b2c6846a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/54685
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r-- | src/soc/amd/cezanne/chip.h | 9 | ||||
-rw-r--r-- | src/soc/amd/cezanne/fch.c | 45 | ||||
-rw-r--r-- | src/soc/amd/cezanne/include/soc/southbridge.h | 15 |
3 files changed, 69 insertions, 0 deletions
diff --git a/src/soc/amd/cezanne/chip.h b/src/soc/amd/cezanne/chip.h index e770670e05..6731a71333 100644 --- a/src/soc/amd/cezanne/chip.h +++ b/src/soc/amd/cezanne/chip.h @@ -5,6 +5,7 @@ #include <amdblocks/chip.h> #include <soc/i2c.h> +#include <soc/southbridge.h> #include <drivers/i2c/designware/dw_i2c.h> #include <types.h> @@ -83,6 +84,14 @@ struct soc_amd_cezanne_config { uint32_t slow_ppt_limit_tablet_mode_mW; uint32_t sustained_power_limit_tablet_mode_mW; uint32_t thermctl_limit_tablet_mode_degreeC; + + /* The array index is the general purpose PCIe clock output number. Values in here + aren't the values written to the register to have the default to be always on. */ + enum { + GPP_CLK_ON, /* GPP clock always on; default */ + GPP_CLK_REQ, /* GPP clock controlled by corresponding #CLK_REQx pin */ + GPP_CLK_OFF, /* GPP clk off */ + } gpp_clk_config[GPP_CLK_OUTPUT_COUNT]; }; #endif /* CEZANNE_CHIP_H */ diff --git a/src/soc/amd/cezanne/fch.c b/src/soc/amd/cezanne/fch.c index f02d1acec5..81fb5d2f01 100644 --- a/src/soc/amd/cezanne/fch.c +++ b/src/soc/amd/cezanne/fch.c @@ -14,6 +14,7 @@ #include <soc/i2c.h> #include <soc/smi.h> #include <soc/southbridge.h> +#include "chip.h" /* * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME @@ -118,6 +119,48 @@ static void fch_init_resets(void) pm_write16(PWR_RESET_CFG, pm_read16(PWR_RESET_CFG) | TOGGLE_ALL_PWR_GOOD); } +/* configure the genral purpose PCIe clock outputs according to the devicetree settings */ +static void gpp_clk_setup(void) +{ + const struct soc_amd_cezanne_config *cfg = config_of_soc(); + + /* look-up table to be able to iterate over the PCIe clock output settings */ + const uint8_t gpp_clk_shift_lut[GPP_CLK_OUTPUT_COUNT] = { + GPP_CLK0_REQ_SHIFT, + GPP_CLK1_REQ_SHIFT, + GPP_CLK2_REQ_SHIFT, + GPP_CLK3_REQ_SHIFT, + GPP_CLK4_REQ_SHIFT, + GPP_CLK5_REQ_SHIFT, + GPP_CLK6_REQ_SHIFT, + }; + + uint32_t gpp_clk_ctl = misc_read32(GPP_CLK_CNTRL); + + for (int i = 0; i < GPP_CLK_OUTPUT_COUNT; i++) { + gpp_clk_ctl &= ~GPP_CLK_REQ_MASK(gpp_clk_shift_lut[i]); + /* + * The remapping of values is done so that the default of the enum used for the + * devicetree settings is the clock being enabled, so that a missing devicetree + * configuration for this will result in an always active clock and not an + * inactive PCIe clock output. + */ + switch (cfg->gpp_clk_config[i]) { + case GPP_CLK_REQ: + gpp_clk_ctl |= GPP_CLK_REQ_EXT(gpp_clk_shift_lut[i]); + break; + case GPP_CLK_OFF: + gpp_clk_ctl |= GPP_CLK_REQ_OFF(gpp_clk_shift_lut[i]); + break; + case GPP_CLK_ON: + default: + gpp_clk_ctl |= GPP_CLK_REQ_ON(gpp_clk_shift_lut[i]); + } + } + + misc_write32(GPP_CLK_CNTRL, gpp_clk_ctl); +} + void fch_init(void *chip_info) { fch_init_resets(); @@ -127,6 +170,8 @@ void fch_init(void *chip_info) acpi_pm_gpe_add_events_print_events(); gpio_add_events(); acpi_clear_pm_gpe_status(); + + gpp_clk_setup(); } void fch_final(void *chip_info) diff --git a/src/soc/amd/cezanne/include/soc/southbridge.h b/src/soc/amd/cezanne/include/soc/southbridge.h index 157ad4ec3c..e58a8cd2ca 100644 --- a/src/soc/amd/cezanne/include/soc/southbridge.h +++ b/src/soc/amd/cezanne/include/soc/southbridge.h @@ -63,6 +63,21 @@ #define FCH_LEGACY_UART_DECODE (ALINK_AHB_ADDRESS + 0x20) /* 0xfedc0020 */ +/* FCH MISC Registers 0xfed80e00 */ +#define GPP_CLK_CNTRL 0x00 +#define GPP_CLK0_REQ_SHIFT 0 +#define GPP_CLK1_REQ_SHIFT 2 +#define GPP_CLK4_REQ_SHIFT 4 +#define GPP_CLK2_REQ_SHIFT 6 +#define GPP_CLK3_REQ_SHIFT 8 +#define GPP_CLK5_REQ_SHIFT 10 +#define GPP_CLK6_REQ_SHIFT 12 +#define GPP_CLK_OUTPUT_COUNT 7 +#define GPP_CLK_REQ_MASK(clk_shift) (0x3 << (clk_shift)) +#define GPP_CLK_REQ_ON(clk_shift) (0x3 << (clk_shift)) +#define GPP_CLK_REQ_EXT(clk_shift) (0x1 << (clk_shift)) +#define GPP_CLK_REQ_OFF(clk_shift) (0x0 << (clk_shift)) + #define MISC_I2C0_PAD_CTRL 0xd8 #define MISC_I2C1_PAD_CTRL 0xdc #define MISC_I2C2_PAD_CTRL 0xe0 |