From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:43:50 +0000
Subject: [PATCH] rtl88x2CE_WiFi_linux driver

---
 kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/pcie_core.c |  114 ++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 92 insertions(+), 22 deletions(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/pcie_core.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/pcie_core.c
index 551e5aa..5df4617 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/pcie_core.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/pcie_core.c
@@ -1,17 +1,18 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /** @file pcie_core.c
  *
  * Contains PCIe related functions that are shared between different driver models (e.g. firmware
  * builds, DHD builds, BMAC builds), in order to avoid code duplication.
  *
- * Copyright (C) 1999-2019, Broadcom Corporation
- * 
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2017, Broadcom Corporation
+ *
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * under the terms of the GNU General Public License version 2 (the "GPL"),
  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  * following added to such license:
- * 
+ *
  *      As a special exception, the copyright holders of this software give you
  * permission to link this software with independent modules, and to copy and
  * distribute the resulting executable under terms of your choice, provided that
@@ -19,7 +20,7 @@
  * the license of that module.  An independent module is a module which is not
  * derived from this software.  The special exception does not apply to any
  * modifications of the software.
- * 
+ *
  *      Notwithstanding the above, under no circumstances may you combine this
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
@@ -27,7 +28,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: pcie_core.c 444841 2013-12-21 04:32:29Z $
+ * $Id: pcie_core.c 701962 2017-05-30 06:13:15Z $
  */
 
 #include <bcm_cfg.h>
@@ -38,8 +39,13 @@
 #include <siutils.h>
 #include <hndsoc.h>
 #include <sbchipc.h>
-
+#include <pcicfg.h>
+#include <bcmdevs.h>
+#include <siutils_priv.h>
 #include "pcie_core.h"
+
+extern int dhdpcie_dongle_host_pre_wd_reset_sequence(si_t *sih, osl_t *osh);
+extern int dhdpcie_dongle_host_post_wd_reset_sequence(si_t *sih, osl_t *osh);
 
 /* local prototypes */
 
@@ -49,7 +55,8 @@
 
 #ifdef BCMDRIVER
 
-void pcie_watchdog_reset(osl_t *osh, si_t *sih, sbpcieregs_t *sbpcieregs)
+/* wd_mask/wd_val is only for chipc_corerev >= 65 */
+void pcie_watchdog_reset(osl_t *osh, si_t *sih, uint32 wd_mask, uint32 wd_val)
 {
 	uint32 val, i, lsc;
 	uint16 cfg_offset[] = {PCIECFGREG_STATUS_CMD, PCIECFGREG_PM_CSR,
@@ -58,39 +65,82 @@
 		PCIECFGREG_LINK_STATUS_CTRL2, PCIECFGREG_RBAR_CTRL,
 		PCIECFGREG_PML1_SUB_CTRL1, PCIECFGREG_REG_BAR2_CONFIG,
 		PCIECFGREG_REG_BAR3_CONFIG};
-	sbpcieregs_t *pcie = NULL;
+	sbpcieregs_t *pcieregs = NULL;
 	uint32 origidx = si_coreidx(sih);
+	int32 bcmerror = BCME_ERROR;
+
+#ifdef BCMQT
+	/* To avoid hang on FPGA, donot reset watchdog */
+	if (CCREV(sih->ccrev) < 65) {
+		si_setcoreidx(sih, origidx);
+		return;
+	}
+#endif // endif
+#ifdef BCMFPGA_HW
+		if (CCREV(sih->ccrev) < 67) {
+			/* To avoid hang on FPGA, donot reset watchdog */
+			si_setcoreidx(sih, origidx);
+			return;
+		}
+#endif // endif
 
 	/* Switch to PCIE2 core */
-	pcie = (sbpcieregs_t *)si_setcore(sih, PCIE2_CORE_ID, 0);
-	BCM_REFERENCE(pcie);
-	ASSERT(pcie != NULL);
+	pcieregs = (sbpcieregs_t *)si_setcore(sih, PCIE2_CORE_ID, 0);
+	BCM_REFERENCE(pcieregs);
+	ASSERT(pcieregs != NULL);
 
 	/* Disable/restore ASPM Control to protect the watchdog reset */
-	W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
-	lsc = R_REG(osh, &sbpcieregs->configdata);
+	W_REG(osh, &pcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
+	lsc = R_REG(osh, &pcieregs->configdata);
 	val = lsc & (~PCIE_ASPM_ENAB);
-	W_REG(osh, &sbpcieregs->configdata, val);
+	W_REG(osh, &pcieregs->configdata, val);
+
+	/*
+	 * CYW55560 - As part of watchdog reset, ARM gets reset and bootloader starts from fresh,
+	 * So, pre wd reset sequcnce defined to make sure that pre init for bootloader can be done
+	 */
+	if (sih->chip == CYW55560_CHIP_ID) {
+		if ((bcmerror = dhdpcie_dongle_host_pre_wd_reset_sequence(sih, osh))) {
+			SI_ERROR(("%s: error %d pre wd reset seq\n",  __FUNCTION__, bcmerror));
+			return;
+		}
+	}
 
 	si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, 4);
-	OSL_DELAY(100000);
 
-	W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
-	W_REG(osh, &sbpcieregs->configdata, lsc);
+#ifdef BCMQT
+	OSL_DELAY(10000000);
+#else
+	OSL_DELAY(100000);
+#endif // endif
+
+	/*
+	 * CYW55560 - Once watchdog reset initiated, bootloader takes much time to be ready,
+	 * [BL_READY bit set], to make sure that host should not access backplane till bootloader
+	 * is not ready, post wd reset sequence is performed.
+	 */
+	if (sih->chip == CYW55560_CHIP_ID) {
+		if ((bcmerror = dhdpcie_dongle_host_post_wd_reset_sequence(sih, osh))) {
+			SI_ERROR(("%s: error %d post wd reset seq.\n", __FUNCTION__, bcmerror));
+			return;
+		}
+	}
+
+	W_REG(osh, &pcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
+	W_REG(osh, &pcieregs->configdata, lsc);
 
 	if (sih->buscorerev <= 13) {
 		/* Write configuration registers back to the shadow registers
 		 * cause shadow registers are cleared out after watchdog reset.
 		 */
 		for (i = 0; i < ARRAYSIZE(cfg_offset); i++) {
-			W_REG(osh, &sbpcieregs->configaddr, cfg_offset[i]);
-			val = R_REG(osh, &sbpcieregs->configdata);
-			W_REG(osh, &sbpcieregs->configdata, val);
+			W_REG(osh, &pcieregs->configaddr, cfg_offset[i]);
+			val = R_REG(osh, &pcieregs->configdata);
+			W_REG(osh, &pcieregs->configdata, val);
 		}
 	}
 	si_setcoreidx(sih, origidx);
 }
-
 
 /* CRWLPCIEGEN2-117 pcie_pipe_Iddq should be controlled
  * by the L12 state from MAC to save power by putting the
@@ -113,4 +163,24 @@
 
 	si_setcoreidx(sih, origidx);
 }
+
+#define PCIE_PMCR_REFUP_MASK 0x3f0001e0
+#define PCIE_PMCR_REFEXT_MASK 0x400000
+#define PCIE_PMCR_REFUP_100US 0x38000080
+#define PCIE_PMCR_REFEXT_100US 0x400000
+
+/* Set PCIE TRefUp time to 100us */
+void pcie_set_trefup_time_100us(si_t *sih)
+{
+	si_corereg(sih, sih->buscoreidx,
+		OFFSETOF(sbpcieregs_t, configaddr), ~0, PCI_PMCR_REFUP);
+	si_corereg(sih, sih->buscoreidx,
+		OFFSETOF(sbpcieregs_t, configdata), PCIE_PMCR_REFUP_MASK, PCIE_PMCR_REFUP_100US);
+
+	si_corereg(sih, sih->buscoreidx,
+		OFFSETOF(sbpcieregs_t, configaddr), ~0, PCI_PMCR_REFUP_EXT);
+	si_corereg(sih, sih->buscoreidx,
+		OFFSETOF(sbpcieregs_t, configdata), PCIE_PMCR_REFEXT_MASK, PCIE_PMCR_REFEXT_100US);
+}
+
 #endif /* BCMDRIVER */

--
Gitblit v1.6.2