diff options
-rw-r--r-- | src/soc/amd/cezanne/chip.h | 9 | ||||
-rw-r--r-- | src/soc/amd/cezanne/fch.c | 45 | ||||
-rw-r--r-- | src/soc/amd/cezanne/include/soc/southbridge.h | 15 |
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 |