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 /src/soc/amd/cezanne/fch.c | |
parent | 0e099eaf83c732599b47f2d5301871d6076857a8 (diff) |
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>
Diffstat (limited to 'src/soc/amd/cezanne/fch.c')
-rw-r--r-- | src/soc/amd/cezanne/fch.c | 45 |
1 files changed, 45 insertions, 0 deletions
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) |