diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2020-08-28 01:40:20 +0200 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2020-08-31 06:42:39 +0000 |
commit | 82a0a63f99a7c9e9afaf7fc6b85a93ef75e480cf (patch) | |
tree | 9a0e004c6ccd4e236440bb848fcb2bf78c605860 /src/soc/amd/picasso/southbridge.c | |
parent | 05ef94795f0303326084290690659f99c6c0e9a7 (diff) | |
download | coreboot-82a0a63f99a7c9e9afaf7fc6b85a93ef75e480cf.tar.xz |
soc/amd/picasso/southbridge: make GPP clock outputs configurable
Make the general purpose PCIe clock outputs configurable to be either
permanently enabled, permanently disabled or dynamically enabled via
their corresponding external #CLK_REQx pins in the board's devicetree.
BUG=b:149970243
BRANCH=zork
Change-Id: I3f5760c0b869e8a9416ba9b57d182a88a2eb5e44
Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/44889
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/amd/picasso/southbridge.c')
-rw-r--r-- | src/soc/amd/picasso/southbridge.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/soc/amd/picasso/southbridge.c b/src/soc/amd/picasso/southbridge.c index 2a5f822b8f..9772e9bc31 100644 --- a/src/soc/amd/picasso/southbridge.c +++ b/src/soc/amd/picasso/southbridge.c @@ -307,6 +307,48 @@ static void al2ahb_clock_gate(void) write8((void *)(al2ahb_base + AL2AHB_CONTROL_HCLK_OFFSET), al2ahb_val); } +/* configure the genral purpose PCIe clock outputs according to the devicetree settings */ +static void gpp_clk_setup(void) +{ + const struct soc_amd_picasso_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 southbridge_init(void *chip_info) { struct chipset_state *state; @@ -322,6 +364,8 @@ void southbridge_init(void *chip_info) acpi_clear_pm_gpe_status(); al2ahb_clock_gate(); + + gpp_clk_setup(); } void southbridge_final(void *chip_info) |