Parcourir la source

qcacmn: clear pcie low power interrupt register after suspend

For specific QCA6174 device, need clear LOW_POWER_INT_MASK register
bit3/4 to disable pcie low power interrupt after suspend, bit3 is for
INTR_L1SS and bit4 is for INTR_CLKPM, this is to fix issue that PMIC
VREG_L30A don't turn off when XO is in shutdown state.

Change-Id: I4833e4143c48a3bf734745a5e772a7a76a94d63c
CRs-Fixed: 3028269
Zhaoyang Liu il y a 3 ans
Parent
commit
08e7ee70fe
2 fichiers modifiés avec 73 ajouts et 0 suppressions
  1. 66 0
      hif/src/pcie/if_pci.c
  2. 7 0
      hif/src/pcie/if_pci.h

+ 66 - 0
hif/src/pcie/if_pci.c

@@ -2204,6 +2204,65 @@ void hif_pci_prevent_linkdown(struct hif_softc *scn, bool flag)
 }
 #endif
 
+#ifdef CONFIG_PCI_LOW_POWER_INT_REG
+/**
+ * hif_pci_config_low_power_int_register(): configure pci low power
+ * interrupt  register.
+ * @enable: true to enable the bits, false clear.
+ *
+ * Configure the bits INTR_L1SS and INTR_CLKPM of
+ * PCIE_LOW_POWER_INT_MASK register.
+ *
+ * Return: n/a
+ */
+static void hif_pci_config_low_power_int_register(struct hif_softc *scn,
+						  bool enable)
+{
+	void *address;
+	uint32_t value;
+	struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
+	struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
+	uint32_t target_type = tgt_info->target_type;
+
+	/*
+	 * Only configure the bits INTR_L1SS and INTR_CLKPM of
+	 * PCIE_LOW_POWER_INT_MASK register for QCA6174 for high
+	 * consumption issue. NFA344A power consumption is above 80mA
+	 * after entering Modern Standby. But the power will drop to normal
+	 * after PERST# de-assert.
+	 */
+	if ((target_type == TARGET_TYPE_AR6320) ||
+	    (target_type == TARGET_TYPE_AR6320V1) ||
+	    (target_type == TARGET_TYPE_AR6320V2) ||
+	    (target_type == TARGET_TYPE_AR6320V3)) {
+		hif_info("Configure PCI low power int mask register");
+
+		address = scn->mem + PCIE_LOW_POWER_INT_MASK_OFFSET;
+
+		/* Configure bit3 INTR_L1SS */
+		value = hif_read32_mb(scn, address);
+		if (enable)
+			value |= INTR_L1SS;
+		else
+			value &= ~INTR_L1SS;
+		hif_write32_mb(scn, address, value);
+
+		/* Configure bit4 INTR_CLKPM */
+		value = hif_read32_mb(scn, address);
+		if (enable)
+			value |= INTR_CLKPM;
+		else
+			value &= ~INTR_CLKPM;
+		hif_write32_mb(scn, address, value);
+	}
+}
+#else
+static inline void hif_pci_config_low_power_int_register(struct hif_softc *scn,
+							 bool enable)
+{
+}
+#endif
+
 /**
  * hif_pci_bus_suspend(): prepare hif for suspend
  *
@@ -2224,6 +2283,13 @@ int hif_pci_bus_suspend(struct hif_softc *scn)
 	/* Stop the HIF Sleep Timer */
 	hif_cancel_deferred_target_sleep(scn);
 
+	/*
+	 * Only need clear the bits INTR_L1SS/INTR_CLKPM after suspend.
+	 * No need do enable bits after resume, as firmware will restore
+	 * the bits after resume.
+	 */
+	hif_pci_config_low_power_int_register(scn, false);
+
 	scn->bus_suspended = true;
 
 	return 0;

+ 7 - 0
hif/src/pcie/if_pci.h

@@ -46,6 +46,13 @@
 #define FORCE_WAKE_DELAY_MS 5
 #endif /* FORCE_WAKE */
 
+#ifdef CONFIG_PCI_LOW_POWER_INT_REG
+/* PCIe low power interrupt mask register */
+#define PCIE_LOW_POWER_INT_MASK_OFFSET	0x38044
+#define INTR_L1SS			BIT(3)
+#define INTR_CLKPM			BIT(4)
+#endif
+
 #ifdef QCA_HIF_HIA_EXTND
 extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk;
 #endif