summaryrefslogtreecommitdiff
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
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>
-rw-r--r--src/soc/amd/cezanne/chip.h9
-rw-r--r--src/soc/amd/cezanne/fch.c45
-rw-r--r--src/soc/amd/cezanne/include/soc/southbridge.h15
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