forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/pcie_core.c
....@@ -1,17 +1,18 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /** @file pcie_core.c
32 *
43 * Contains PCIe related functions that are shared between different driver models (e.g. firmware
54 * builds, DHD builds, BMAC builds), in order to avoid code duplication.
65 *
7
- * Copyright (C) 1999-2019, Broadcom Corporation
8
- *
6
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
7
+ *
8
+ * Copyright (C) 1999-2017, Broadcom Corporation
9
+ *
910 * Unless you and Broadcom execute a separate written software license
1011 * agreement governing use of this software, this software is licensed to you
1112 * under the terms of the GNU General Public License version 2 (the "GPL"),
1213 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1314 * following added to such license:
14
- *
15
+ *
1516 * As a special exception, the copyright holders of this software give you
1617 * permission to link this software with independent modules, and to copy and
1718 * distribute the resulting executable under terms of your choice, provided that
....@@ -19,7 +20,7 @@
1920 * the license of that module. An independent module is a module which is not
2021 * derived from this software. The special exception does not apply to any
2122 * modifications of the software.
22
- *
23
+ *
2324 * Notwithstanding the above, under no circumstances may you combine this
2425 * software in any way with any other Broadcom software provided under a license
2526 * other than the GPL, without Broadcom's express prior written consent.
....@@ -27,7 +28,7 @@
2728 *
2829 * <<Broadcom-WL-IPTag/Open:>>
2930 *
30
- * $Id: pcie_core.c 444841 2013-12-21 04:32:29Z $
31
+ * $Id: pcie_core.c 701962 2017-05-30 06:13:15Z $
3132 */
3233
3334 #include <bcm_cfg.h>
....@@ -38,8 +39,13 @@
3839 #include <siutils.h>
3940 #include <hndsoc.h>
4041 #include <sbchipc.h>
41
-
42
+#include <pcicfg.h>
43
+#include <bcmdevs.h>
44
+#include <siutils_priv.h>
4245 #include "pcie_core.h"
46
+
47
+extern int dhdpcie_dongle_host_pre_wd_reset_sequence(si_t *sih, osl_t *osh);
48
+extern int dhdpcie_dongle_host_post_wd_reset_sequence(si_t *sih, osl_t *osh);
4349
4450 /* local prototypes */
4551
....@@ -49,7 +55,8 @@
4955
5056 #ifdef BCMDRIVER
5157
52
-void pcie_watchdog_reset(osl_t *osh, si_t *sih, sbpcieregs_t *sbpcieregs)
58
+/* wd_mask/wd_val is only for chipc_corerev >= 65 */
59
+void pcie_watchdog_reset(osl_t *osh, si_t *sih, uint32 wd_mask, uint32 wd_val)
5360 {
5461 uint32 val, i, lsc;
5562 uint16 cfg_offset[] = {PCIECFGREG_STATUS_CMD, PCIECFGREG_PM_CSR,
....@@ -58,39 +65,82 @@
5865 PCIECFGREG_LINK_STATUS_CTRL2, PCIECFGREG_RBAR_CTRL,
5966 PCIECFGREG_PML1_SUB_CTRL1, PCIECFGREG_REG_BAR2_CONFIG,
6067 PCIECFGREG_REG_BAR3_CONFIG};
61
- sbpcieregs_t *pcie = NULL;
68
+ sbpcieregs_t *pcieregs = NULL;
6269 uint32 origidx = si_coreidx(sih);
70
+ int32 bcmerror = BCME_ERROR;
71
+
72
+#ifdef BCMQT
73
+ /* To avoid hang on FPGA, donot reset watchdog */
74
+ if (CCREV(sih->ccrev) < 65) {
75
+ si_setcoreidx(sih, origidx);
76
+ return;
77
+ }
78
+#endif // endif
79
+#ifdef BCMFPGA_HW
80
+ if (CCREV(sih->ccrev) < 67) {
81
+ /* To avoid hang on FPGA, donot reset watchdog */
82
+ si_setcoreidx(sih, origidx);
83
+ return;
84
+ }
85
+#endif // endif
6386
6487 /* Switch to PCIE2 core */
65
- pcie = (sbpcieregs_t *)si_setcore(sih, PCIE2_CORE_ID, 0);
66
- BCM_REFERENCE(pcie);
67
- ASSERT(pcie != NULL);
88
+ pcieregs = (sbpcieregs_t *)si_setcore(sih, PCIE2_CORE_ID, 0);
89
+ BCM_REFERENCE(pcieregs);
90
+ ASSERT(pcieregs != NULL);
6891
6992 /* Disable/restore ASPM Control to protect the watchdog reset */
70
- W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
71
- lsc = R_REG(osh, &sbpcieregs->configdata);
93
+ W_REG(osh, &pcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
94
+ lsc = R_REG(osh, &pcieregs->configdata);
7295 val = lsc & (~PCIE_ASPM_ENAB);
73
- W_REG(osh, &sbpcieregs->configdata, val);
96
+ W_REG(osh, &pcieregs->configdata, val);
97
+
98
+ /*
99
+ * CYW55560 - As part of watchdog reset, ARM gets reset and bootloader starts from fresh,
100
+ * So, pre wd reset sequcnce defined to make sure that pre init for bootloader can be done
101
+ */
102
+ if (sih->chip == CYW55560_CHIP_ID) {
103
+ if ((bcmerror = dhdpcie_dongle_host_pre_wd_reset_sequence(sih, osh))) {
104
+ SI_ERROR(("%s: error %d pre wd reset seq\n", __FUNCTION__, bcmerror));
105
+ return;
106
+ }
107
+ }
74108
75109 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, 4);
76
- OSL_DELAY(100000);
77110
78
- W_REG(osh, &sbpcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
79
- W_REG(osh, &sbpcieregs->configdata, lsc);
111
+#ifdef BCMQT
112
+ OSL_DELAY(10000000);
113
+#else
114
+ OSL_DELAY(100000);
115
+#endif // endif
116
+
117
+ /*
118
+ * CYW55560 - Once watchdog reset initiated, bootloader takes much time to be ready,
119
+ * [BL_READY bit set], to make sure that host should not access backplane till bootloader
120
+ * is not ready, post wd reset sequence is performed.
121
+ */
122
+ if (sih->chip == CYW55560_CHIP_ID) {
123
+ if ((bcmerror = dhdpcie_dongle_host_post_wd_reset_sequence(sih, osh))) {
124
+ SI_ERROR(("%s: error %d post wd reset seq.\n", __FUNCTION__, bcmerror));
125
+ return;
126
+ }
127
+ }
128
+
129
+ W_REG(osh, &pcieregs->configaddr, PCIECFGREG_LINK_STATUS_CTRL);
130
+ W_REG(osh, &pcieregs->configdata, lsc);
80131
81132 if (sih->buscorerev <= 13) {
82133 /* Write configuration registers back to the shadow registers
83134 * cause shadow registers are cleared out after watchdog reset.
84135 */
85136 for (i = 0; i < ARRAYSIZE(cfg_offset); i++) {
86
- W_REG(osh, &sbpcieregs->configaddr, cfg_offset[i]);
87
- val = R_REG(osh, &sbpcieregs->configdata);
88
- W_REG(osh, &sbpcieregs->configdata, val);
137
+ W_REG(osh, &pcieregs->configaddr, cfg_offset[i]);
138
+ val = R_REG(osh, &pcieregs->configdata);
139
+ W_REG(osh, &pcieregs->configdata, val);
89140 }
90141 }
91142 si_setcoreidx(sih, origidx);
92143 }
93
-
94144
95145 /* CRWLPCIEGEN2-117 pcie_pipe_Iddq should be controlled
96146 * by the L12 state from MAC to save power by putting the
....@@ -113,4 +163,24 @@
113163
114164 si_setcoreidx(sih, origidx);
115165 }
166
+
167
+#define PCIE_PMCR_REFUP_MASK 0x3f0001e0
168
+#define PCIE_PMCR_REFEXT_MASK 0x400000
169
+#define PCIE_PMCR_REFUP_100US 0x38000080
170
+#define PCIE_PMCR_REFEXT_100US 0x400000
171
+
172
+/* Set PCIE TRefUp time to 100us */
173
+void pcie_set_trefup_time_100us(si_t *sih)
174
+{
175
+ si_corereg(sih, sih->buscoreidx,
176
+ OFFSETOF(sbpcieregs_t, configaddr), ~0, PCI_PMCR_REFUP);
177
+ si_corereg(sih, sih->buscoreidx,
178
+ OFFSETOF(sbpcieregs_t, configdata), PCIE_PMCR_REFUP_MASK, PCIE_PMCR_REFUP_100US);
179
+
180
+ si_corereg(sih, sih->buscoreidx,
181
+ OFFSETOF(sbpcieregs_t, configaddr), ~0, PCI_PMCR_REFUP_EXT);
182
+ si_corereg(sih, sih->buscoreidx,
183
+ OFFSETOF(sbpcieregs_t, configdata), PCIE_PMCR_REFEXT_MASK, PCIE_PMCR_REFEXT_100US);
184
+}
185
+
116186 #endif /* BCMDRIVER */