soc/intel/common/block/pcie/rtd3: Skip Power On if _STA returns 1

RTD3,_ON method sometimes can create delays during system boot.
Even when the power is already up, kernel still tries to call _ON
method to power up device, but it's unnecessary.

RTD3._STA returns device power, so _ON method can check _STA and see
if the power on process can be skipped

BUG=b:249931687
TEST=system can boot to OS with RTD3 pcie storage and save ~80 ms on
     Crota. Suspend stress test passes 100 cycles

Change-Id: I296ce1b85417a5dbaca558511cd7fc51a3a38c84
Signed-off-by: Kane Chen <kane.chen@intel.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/69189
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Reviewed-by: Subrata Banik <subratabanik@google.com>
diff --git a/src/soc/intel/common/block/pcie/rtd3/rtd3.c b/src/soc/intel/common/block/pcie/rtd3/rtd3.c
index f99ae44..7a64734 100644
--- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c
+++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c
@@ -143,10 +143,30 @@
 static void
 pcie_rtd3_acpi_method_on(unsigned int pcie_rp,
 			 const struct soc_intel_common_block_pcie_rtd3_config *config,
-			 enum pcie_rp_type rp_type)
+			 enum pcie_rp_type rp_type,
+			 const struct device *dev)
 {
+	const struct device *parent = dev->bus->dev;
+
 	acpigen_write_method_serialized("_ON", 0);
 
+	/* The _STA returns current power status of device, so we can skip _ON
+	 * if _STA returns 1
+	 * Example:
+	 * Local0 = \_SB.PCI0.RP01.RTD3._STA ()
+	 * If ((Local0 == One))
+	 * {
+	 *   Return (One)
+	 * }
+	 */
+	acpigen_write_store();
+	acpigen_emit_namestring(acpi_device_path_join(parent, "RTD3._STA"));
+	acpigen_emit_byte(LOCAL0_OP);
+	acpigen_write_if_lequal_op_int(LOCAL0_OP, ONE_OP);
+	acpigen_write_return_op(ONE_OP);
+	acpigen_write_if_end();
+
+
 	/* When this feature is enabled, ONSK indicates if the previous _OFF was
 	 * skipped. If so, since the device was not in Off state, and the current
 	 * _ON can be skipped as well.
@@ -448,7 +468,7 @@
 	}
 
 	pcie_rtd3_acpi_method_status(config);
-	pcie_rtd3_acpi_method_on(pcie_rp, config, rp_type);
+	pcie_rtd3_acpi_method_on(pcie_rp, config, rp_type, dev);
 	pcie_rtd3_acpi_method_off(pcie_rp, config, rp_type);
 	acpigen_pop_len(); /* PowerResource */