summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorKane Chen <kane.chen@intel.corp-partner.google.com>2023-07-06 16:05:42 +0800
committerSubrata Banik <subratabanik@google.com>2023-07-18 05:31:15 +0000
commitfa77ac93c5b63ab56135436cc34d97ab60b57470 (patch)
tree85ecdb7aa1328012963e5b14b02bad006d7e886b /src/soc
parentfadda4ae6b1614523e14326fbe98280ff0c19c64 (diff)
soc/intel/common/acpi: Support on/off PCIe CLK by P2SB
In the older platform such as Raptor Lake (RPL), Tiger Lake (TGL), it needs PMC IPC cmd to turn on/off the corresponding clock. Now on Meteor Lake (MTL), it control pcie clock registers on P2SB on IOE or SoC die. BUG=b:288976547, b:289461604 TEST=Test on google/screebo and found the pcie clock is on/off properly and sdcard pcie port doesn't block S0ix with RTD3 cold enabled. Change-Id: Ia729444b561daafc2dca0ed86c797eb98ce1f165 Signed-off-by: Kane Chen <kane.chen@intel.corp-partner.google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/76347 Reviewed-by: Kapil Porwal <kapilporwal@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/common/acpi/ioe_clk.asl37
-rw-r--r--src/soc/intel/common/acpi/pch_clk.asl37
-rw-r--r--src/soc/intel/common/acpi/pcie_clk.asl30
-rw-r--r--src/soc/intel/common/block/pcie/Kconfig16
-rw-r--r--src/soc/intel/common/block/pcie/rtd3/rtd3.c31
5 files changed, 146 insertions, 5 deletions
diff --git a/src/soc/intel/common/acpi/ioe_clk.asl b/src/soc/intel/common/acpi/ioe_clk.asl
new file mode 100644
index 0000000000..9aa1aba4f5
--- /dev/null
+++ b/src/soc/intel/common/acpi/ioe_clk.asl
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define PCR_BIOS_BUFFEN 0x8080
+
+Scope (\_SB)
+{
+ /* MTL IOE CLK */
+ Device (ECLK) {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, "IOECLK")
+
+ Method (_STA)
+ {
+ /*
+ * Device is present, enabled and decoding its resources
+ * and should not be shown in UI
+ */
+ Return (0x3)
+ }
+
+ /*
+ * PCIe(100MHz) clock disable
+ * Arg0 - clock index
+ */
+ Method (CLKD, 1) {
+ \_SB.PCI0.ICRA (PID_ISCLK, PCR_BIOS_BUFFEN, Not (ShiftLeft (1, Arg0)))
+ }
+
+ /*
+ * PCIe(100MHz) clock enable
+ * Arg0 - clock index
+ */
+ Method (CLKE, 1) {
+ \_SB.PCI0.ICRO (PID_ISCLK, PCR_BIOS_BUFFEN, (ShiftLeft (1, Arg0)))
+ }
+ }
+}
diff --git a/src/soc/intel/common/acpi/pch_clk.asl b/src/soc/intel/common/acpi/pch_clk.asl
new file mode 100644
index 0000000000..08863a3234
--- /dev/null
+++ b/src/soc/intel/common/acpi/pch_clk.asl
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define PCR_BIOS_BUFFEN 0x8080
+
+Scope (\_SB)
+{
+ /* MTL PCH CLK */
+ Device (ICLK) {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, "SOCCLK")
+
+ Method (_STA)
+ {
+ /*
+ * Device is present, enabled and decoding its resources
+ * and should not be shown in UI
+ */
+ Return (0x3)
+ }
+
+ /*
+ * PCIe(100MHz) clock disable
+ * Arg0 - clock index
+ */
+ Method (CLKD, 1) {
+ \_SB.PCI0.PCRA (PID_ISCLK, PCR_BIOS_BUFFEN, Not (ShiftLeft (1, Arg0)))
+ }
+
+ /*
+ * PCIe(100MHz) clock enable
+ * Arg0 - clock index
+ */
+ Method (CLKE, 1) {
+ \_SB.PCI0.PCRO (PID_ISCLK, PCR_BIOS_BUFFEN, (ShiftLeft (1, Arg0)))
+ }
+ }
+}
diff --git a/src/soc/intel/common/acpi/pcie_clk.asl b/src/soc/intel/common/acpi/pcie_clk.asl
new file mode 100644
index 0000000000..e7e311fe9c
--- /dev/null
+++ b/src/soc/intel/common/acpi/pcie_clk.asl
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* PCH clock by P2SB */
+#include <soc/intel/common/acpi/pch_clk.asl>
+
+/* IOE clock by P2SB */
+#if CONFIG(SOC_INTEL_COMMON_BLOCK_IOE_P2SB)
+ #include <soc/intel/common/acpi/ioe_clk.asl>
+#endif
+
+/*
+ * Configure PCIe ClkReq Override
+ * Arg0: Clock number
+ * Arg1: Enable(1)/Disable(0) Clock
+ */
+Method (SPCO, 2, Serialized) {
+ If (LEqual (Arg1,1)) {
+ If (LGreaterEqual (Arg0, CONFIG_IOE_DIE_CLOCK_START)) {
+ \_SB.ECLK.CLKE (Subtract (Arg0, CONFIG_IOE_DIE_CLOCK_START))
+ } Else {
+ \_SB.ICLK.CLKE (Arg0)
+ }
+ } Else {
+ If (LGreaterEqual (Arg0, CONFIG_IOE_DIE_CLOCK_START)) {
+ \_SB.ECLK.CLKD (Subtract (Arg0, CONFIG_IOE_DIE_CLOCK_START))
+ } Else {
+ \_SB.ICLK.CLKD (Arg0)
+ }
+ }
+}
diff --git a/src/soc/intel/common/block/pcie/Kconfig b/src/soc/intel/common/block/pcie/Kconfig
index f65d8c16f3..dccedb0df4 100644
--- a/src/soc/intel/common/block/pcie/Kconfig
+++ b/src/soc/intel/common/block/pcie/Kconfig
@@ -37,3 +37,19 @@ config PCIE_DEBUG_INFO
Enable debug logs in PCIe module. Allows debug information on memory
base and limit, prefetchable memory base and limit, prefetchable memory
base upper 32 bits and prefetchable memory limit upper 32 bits.
+
+config PCIE_CLOCK_CONTROL_THROUGH_P2SB
+ bool
+ default n
+ depends on SOC_INTEL_COMMON_BLOCK_PCIE_RTD3
+ help
+ Enables PCIe CLK control (on/off) through P2SB. The mechanism is supported
+ starting from MTL platform. In older platforms like ADL & TGL, PCIe CLK is
+ controlled by sending IPC CMD to PMC.
+
+config IOE_DIE_CLOCK_START
+ int
+ depends on SOC_INTEL_COMMON_BLOCK_IOE_P2SB
+ default 0
+ help
+ The beginning of IOE DIE pcie src clk number. IOE DIE is started from MTL.
diff --git a/src/soc/intel/common/block/pcie/rtd3/rtd3.c b/src/soc/intel/common/block/pcie/rtd3/rtd3.c
index 82336d94a9..abd7e46671 100644
--- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c
+++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c
@@ -28,6 +28,9 @@
/* ACPI path to the mutex that protects accesses to PMC ModPhy power gating registers */
#define RTD3_MUTEX_PATH "\\_SB.PCI0.R3MX"
+/* ACPI path to control PCIE CLK by P2SB */
+#define RTD3_PCIE_CLK_ENABLE_PATH "\\_SB.PCI0.SPCO"
+
enum modphy_pg_state {
PG_DISABLE = 0,
PG_ENABLE = 1,
@@ -121,6 +124,16 @@ static void pcie_rtd3_acpi_method_srck(unsigned int pcie_rp,
acpigen_pop_len(); /* Method */
}
+/* Method to enable/disable pcie clock by p2sb*/
+static void p2sb_acpi_set_pci_clock(u8 srcclk_pin, bool enable)
+{
+ acpigen_write_if_cond_ref_of(RTD3_PCIE_CLK_ENABLE_PATH);
+ acpigen_emit_namestring(RTD3_PCIE_CLK_ENABLE_PATH);
+ acpigen_write_integer(srcclk_pin);
+ acpigen_write_integer(enable);
+ acpigen_write_if_end();
+}
+
static void
pcie_rtd3_acpi_method_on(unsigned int pcie_rp,
const struct soc_intel_common_block_pcie_rtd3_config *config,
@@ -169,9 +182,13 @@ pcie_rtd3_acpi_method_on(unsigned int pcie_rp,
acpigen_write_sleep(config->enable_delay_ms);
}
- /* Enable SRCCLK for root port if pin is defined. */
- if (config->srcclk_pin >= 0)
- pmc_ipc_acpi_set_pci_clock(pcie_rp, config->srcclk_pin, true);
+ /* Enable SRCCLK for this root port if pin is defined. */
+ if (config->srcclk_pin >= 0) {
+ if (CONFIG(PCIE_CLOCK_CONTROL_THROUGH_P2SB))
+ p2sb_acpi_set_pci_clock(config->srcclk_pin, true);
+ else
+ pmc_ipc_acpi_set_pci_clock(pcie_rp, config->srcclk_pin, true);
+ }
/* De-assert reset GPIO to bring device out of reset. */
if (config->reset_gpio.pin_count) {
@@ -239,8 +256,12 @@ pcie_rtd3_acpi_method_off(int pcie_rp,
pcie_rtd3_enable_modphy_pg(pcie_rp, PG_ENABLE);
/* Disable SRCCLK for this root port if pin is defined. */
- if (config->srcclk_pin >= 0)
- pmc_ipc_acpi_set_pci_clock(pcie_rp, config->srcclk_pin, false);
+ if (config->srcclk_pin >= 0) {
+ if (CONFIG(PCIE_CLOCK_CONTROL_THROUGH_P2SB))
+ p2sb_acpi_set_pci_clock(config->srcclk_pin, false);
+ else
+ pmc_ipc_acpi_set_pci_clock(pcie_rp, config->srcclk_pin, false);
+ }
/* De-assert enable GPIO to turn off device power. */
if (config->enable_gpio.pin_count) {