summaryrefslogtreecommitdiff
path: root/src/soc/amd/cezanne/fch.c
diff options
context:
space:
mode:
authorFelix Held <felix-coreboot@felixheld.de>2021-05-18 01:25:51 +0200
committerFelix Held <felix-coreboot@felixheld.de>2021-05-19 15:37:39 +0000
commit224b578420a5d42e16ec6a8285971d34d8cdafac (patch)
treeeb7a334ae4d2f9599815aaa886d8c2c3cd396327 /src/soc/amd/cezanne/fch.c
parent0e099eaf83c732599b47f2d5301871d6076857a8 (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.c45
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)