summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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