Felix Held submitted this change.

View Change

Approvals: Matt DeVillier: Looks good to me, approved build bot (Jenkins): Verified Felix Held: Looks good to me, approved
soc/amd: Factor out gpp_clk_setup function

gpp_clk_setup code in most AMD SoC is similar and it can moved to common
code. The only thing which is SoC dependent in this function is the SoC
config, hence keep it in SoC code and move everything else in new
gpp_clk_setup_common function which is in soc/amd/common. Picasso and
Glinda don't have pcie_gpp_dxio_update_clk_req_config fixup function so
they are addressed in later patches.

Change-Id: I7d7da4bfe079f07e31212247dbf3acd14daa6447
Signed-off-by: Varshit Pandya <pandyavarshit@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/80285
Reviewed-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
---
M src/soc/amd/cezanne/Kconfig
M src/soc/amd/cezanne/fch.c
M src/soc/amd/cezanne/include/soc/southbridge.h
A src/soc/amd/common/block/gpp_clk/Kconfig
A src/soc/amd/common/block/gpp_clk/Makefile.mk
A src/soc/amd/common/block/gpp_clk/gpp_clk.c
M src/soc/amd/common/block/include/amdblocks/pci_clk_req.h
M src/soc/amd/mendocino/Kconfig
M src/soc/amd/mendocino/fch.c
M src/soc/amd/mendocino/include/soc/southbridge.h
M src/soc/amd/phoenix/Kconfig
M src/soc/amd/phoenix/fch.c
M src/soc/amd/phoenix/include/soc/southbridge.h
13 files changed, 80 insertions(+), 160 deletions(-)

diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig
index 4e22005..2ebf6bc 100644
--- a/src/soc/amd/cezanne/Kconfig
+++ b/src/soc/amd/cezanne/Kconfig
@@ -44,6 +44,7 @@
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
select SOC_AMD_COMMON_BLOCK_EMMC
+ select SOC_AMD_COMMON_BLOCK_GPP_CLK
select SOC_AMD_COMMON_BLOCK_GRAPHICS
select SOC_AMD_COMMON_BLOCK_HAS_ESPI
select SOC_AMD_COMMON_BLOCK_I2C
diff --git a/src/soc/amd/cezanne/fch.c b/src/soc/amd/cezanne/fch.c
index f065c8e..1abe00d 100644
--- a/src/soc/amd/cezanne/fch.c
+++ b/src/soc/amd/cezanne/fch.c
@@ -135,45 +135,7 @@
static void gpp_clk_setup(void)
{
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);
-
- pcie_gpp_dxio_update_clk_req_config(&cfg->gpp_clk_config[0],
- ARRAY_SIZE(cfg->gpp_clk_config));
- 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);
+ gpp_clk_setup_common(&cfg->gpp_clk_config[0], ARRAY_SIZE(cfg->gpp_clk_config));
}

static void cgpll_clock_gate_init(void)
diff --git a/src/soc/amd/cezanne/include/soc/southbridge.h b/src/soc/amd/cezanne/include/soc/southbridge.h
index 4cd53cb..bdd6644 100644
--- a/src/soc/amd/cezanne/include/soc/southbridge.h
+++ b/src/soc/amd/cezanne/include/soc/southbridge.h
@@ -85,21 +85,6 @@

#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_CLKGATEDCNTL 0x2c
#define ALINKCLK_GATEOFFEN BIT(16)
#define BLINKCLK_GATEOFFEN BIT(17)
diff --git a/src/soc/amd/common/block/gpp_clk/Kconfig b/src/soc/amd/common/block/gpp_clk/Kconfig
new file mode 100644
index 0000000..0838df4
--- /dev/null
+++ b/src/soc/amd/common/block/gpp_clk/Kconfig
@@ -0,0 +1,4 @@
+config SOC_AMD_COMMON_BLOCK_GPP_CLK
+ bool
+ help
+ Select this option to use AMD common PCIe clk generator configuration.
diff --git a/src/soc/amd/common/block/gpp_clk/Makefile.mk b/src/soc/amd/common/block/gpp_clk/Makefile.mk
new file mode 100644
index 0000000..4b943f4
--- /dev/null
+++ b/src/soc/amd/common/block/gpp_clk/Makefile.mk
@@ -0,0 +1,3 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_GPP_CLK) += gpp_clk.c
diff --git a/src/soc/amd/common/block/gpp_clk/gpp_clk.c b/src/soc/amd/common/block/gpp_clk/gpp_clk.c
new file mode 100644
index 0000000..20d768f
--- /dev/null
+++ b/src/soc/amd/common/block/gpp_clk/gpp_clk.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/acpimmio.h>
+#include <amdblocks/pci_clk_req.h>
+#include <types.h>
+
+/* configure the general purpose PCIe clock outputs according to the devicetree settings */
+void gpp_clk_setup_common(enum gpp_clk_req *gpp_clk_config, size_t gpp_clk_config_num)
+{
+ /* 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);
+
+ pcie_gpp_dxio_update_clk_req_config(gpp_clk_config, gpp_clk_config_num);
+ 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. Only the configuration for the clock outputs
+ * available on the package is provided via the devicetree; the rest is
+ * switched off unconditionally.
+ */
+ switch (i < gpp_clk_config_num ? gpp_clk_config[i] : GPP_CLK_OFF) {
+ 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);
+}
diff --git a/src/soc/amd/common/block/include/amdblocks/pci_clk_req.h b/src/soc/amd/common/block/include/amdblocks/pci_clk_req.h
index 7c10e5d..811fe68 100644
--- a/src/soc/amd/common/block/include/amdblocks/pci_clk_req.h
+++ b/src/soc/amd/common/block/include/amdblocks/pci_clk_req.h
@@ -5,6 +5,21 @@

#include <types.h>

+/* 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))
+
enum gpp_clk_req {
GPP_CLK_ON, /* GPP clock always on; default */
GPP_CLK_REQ, /* GPP clock controlled by corresponding #CLK_REQx pin */
@@ -14,4 +29,8 @@
void pcie_gpp_dxio_update_clk_req_config(enum gpp_clk_req *gpp_clk_config,
size_t gpp_clk_config_num);

+/* configure the general purpose PCIe clock outputs according to the devicetree settings */
+void gpp_clk_setup_common(enum gpp_clk_req *gpp_clk_config,
+ size_t gpp_clk_config_num);
+
#endif
diff --git a/src/soc/amd/mendocino/Kconfig b/src/soc/amd/mendocino/Kconfig
index 7f61338..f6305ee 100644
--- a/src/soc/amd/mendocino/Kconfig
+++ b/src/soc/amd/mendocino/Kconfig
@@ -48,6 +48,7 @@
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
select SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES
+ select SOC_AMD_COMMON_BLOCK_GPP_CLK
select SOC_AMD_COMMON_BLOCK_GRAPHICS
select SOC_AMD_COMMON_BLOCK_HAS_ESPI
select SOC_AMD_COMMON_BLOCK_HAS_ESPI_ALERT_ENABLE
diff --git a/src/soc/amd/mendocino/fch.c b/src/soc/amd/mendocino/fch.c
index 772cca0..8fb0190 100644
--- a/src/soc/amd/mendocino/fch.c
+++ b/src/soc/amd/mendocino/fch.c
@@ -130,46 +130,7 @@
static void gpp_clk_setup(void)
{
struct soc_amd_mendocino_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);
-
- pcie_gpp_dxio_update_clk_req_config(&cfg->gpp_clk_config[0],
- ARRAY_SIZE(cfg->gpp_clk_config));
- 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. Only the configuration for the clock outputs
- * available on the package is provided via the devicetree; the rest is
- * switched off unconditionally.
- */
- switch (i < GPP_CLK_OUTPUT_AVAILABLE ? cfg->gpp_clk_config[i] : GPP_CLK_OFF) {
- 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);
+ gpp_clk_setup_common(&cfg->gpp_clk_config[0], ARRAY_SIZE(cfg->gpp_clk_config));
}

static void cgpll_clock_gate_init(void)
diff --git a/src/soc/amd/mendocino/include/soc/southbridge.h b/src/soc/amd/mendocino/include/soc/southbridge.h
index 2e88c773..9b276d2 100644
--- a/src/soc/amd/mendocino/include/soc/southbridge.h
+++ b/src/soc/amd/mendocino/include/soc/southbridge.h
@@ -85,20 +85,7 @@
#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_OUTPUT_AVAILABLE 4
-#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_CLKGATEDCNTL 0x2c
#define ALINKCLK_GATEOFFEN BIT(16)
diff --git a/src/soc/amd/phoenix/Kconfig b/src/soc/amd/phoenix/Kconfig
index 0acf62b..9d45b76 100644
--- a/src/soc/amd/phoenix/Kconfig
+++ b/src/soc/amd/phoenix/Kconfig
@@ -43,6 +43,7 @@
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN
select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT
select SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES
+ select SOC_AMD_COMMON_BLOCK_GPP_CLK
select SOC_AMD_COMMON_BLOCK_GRAPHICS # TODO: Check if this is still correct
select SOC_AMD_COMMON_BLOCK_HAS_ESPI
select SOC_AMD_COMMON_BLOCK_HAS_ESPI_ALERT_ENABLE
diff --git a/src/soc/amd/phoenix/fch.c b/src/soc/amd/phoenix/fch.c
index 1e03cda..779d448 100644
--- a/src/soc/amd/phoenix/fch.c
+++ b/src/soc/amd/phoenix/fch.c
@@ -128,46 +128,7 @@
static void gpp_clk_setup(void)
{
struct soc_amd_phoenix_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);
-
- pcie_gpp_dxio_update_clk_req_config(&cfg->gpp_clk_config[0],
- ARRAY_SIZE(cfg->gpp_clk_config));
- 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. Only the configuration for the clock outputs
- * available on the package is provided via the devicetree; the rest is
- * switched off unconditionally.
- */
- switch (i < GPP_CLK_OUTPUT_AVAILABLE ? cfg->gpp_clk_config[i] : GPP_CLK_OFF) {
- 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);
+ gpp_clk_setup_common(&cfg->gpp_clk_config[0], ARRAY_SIZE(cfg->gpp_clk_config));
}

static void cgpll_clock_gate_init(void)
diff --git a/src/soc/amd/phoenix/include/soc/southbridge.h b/src/soc/amd/phoenix/include/soc/southbridge.h
index 9b84934..db0e304 100644
--- a/src/soc/amd/phoenix/include/soc/southbridge.h
+++ b/src/soc/amd/phoenix/include/soc/southbridge.h
@@ -84,20 +84,7 @@
#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_OUTPUT_AVAILABLE 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_CLKGATEDCNTL 0x2c
#define ALINKCLK_GATEOFFEN BIT(16)

To view, visit change 80285. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: main
Gerrit-Change-Id: I7d7da4bfe079f07e31212247dbf3acd14daa6447
Gerrit-Change-Number: 80285
Gerrit-PatchSet: 7
Gerrit-Owner: Varshit Pandya <pandyavarshit@gmail.com>
Gerrit-Reviewer: Felix Held <felix-coreboot@felixheld.de>
Gerrit-Reviewer: Fred Reitberger <reitbergerfred@gmail.com>
Gerrit-Reviewer: Jason Glenesk <jason.glenesk@gmail.com>
Gerrit-Reviewer: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-MessageType: merged