Search Linux Wireless

[PATCH 10/20] wl18xx: FDSP Code RAM Corruption fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ido Reis <idor@xxxxxx>

In PG2.0 there is an issue where PHY's FDSP Code RAM sometimes gets
corrupted when exiting from ELP mode. This issue is related to FDSP
Code RAM clock implementation.

PG2.1 introduces a HW fix for this issue that requires the driver to
change the FDSP Code Ram clock settings (mux it to ATGP clock instead
of its own clock).

This workaround uses PHY_FPGA_SPARE_1 register and is relevant to WL8
PG2.1 devices.

The fix is also backward compatible with older PG2.0 devices where the
register PHY_FPGA_SPARE_1 is not used and not connected.

The fix is done in the wl18xx_pre_upload function (must be performed
before uploading the FW code) and includes the following steps:

1. Disable FDSP clock
2. Set ATPG clock toward FDSP Code RAM rather than its own clock.
3. Re-enable FDSP clock

Signed-off-by: Yair Shapira <yair.shapira@xxxxxx>
Signed-off-by: Ido Reis <idor@xxxxxx>
Signed-off-by: Arik Nemtsov <arik@xxxxxxxxxx>
---
 drivers/net/wireless/ti/wl18xx/main.c |   34 +++++++++++++++++++++++++++++++--
 drivers/net/wireless/ti/wl18xx/reg.h  |   20 +++++++++++++++++++
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 4f3c142..8fd13f3 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -559,6 +559,9 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
 	},
 };
 
+#define WL18XX_PHY_INIT_MEM_SIZE \
+	(WL18XX_PHY_END_MEM_ADDR - WL18XX_PHY_INIT_MEM_ADDR + 4)
+
 static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
 	[PART_TOP_PRCM_ELP_SOC] = {
 		.mem  = { .start = 0x00A02000, .size  = 0x00010000 },
@@ -585,8 +588,8 @@ static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
 		.mem3 = { .start = 0x00000000, .size  = 0x00000000 },
 	},
 	[PART_PHY_INIT] = {
-		.mem  = { .start = 0x80926000,
-			  .size = sizeof(struct wl18xx_mac_and_phy_params) },
+		.mem  = { .start = WL18XX_PHY_INIT_MEM_ADDR,
+			  .size = WL18XX_PHY_INIT_MEM_SIZE },
 		.reg  = { .start = 0x00000000, .size = 0x00000000 },
 		.mem2 = { .start = 0x00000000, .size = 0x00000000 },
 		.mem3 = { .start = 0x00000000, .size = 0x00000000 },
@@ -787,6 +790,9 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
 	u32 tmp;
 	int ret;
 
+	BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
+		WL18XX_PHY_INIT_MEM_SIZE);
+
 	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
 	if (ret < 0)
 		goto out;
@@ -803,6 +809,30 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
 	wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
 
 	ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
+	if (ret < 0)
+		goto out;
+
+	/* Set ATPG clock toward FDSP Code RAM rather than its own clock */
+	/* Disable FDSP clock */
+
+	ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
+	if (ret < 0)
+		goto out;
+
+	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
+			     MEM_FDSP_CLK_120_DISABLE);
+	if (ret < 0)
+		goto out;
+
+	/* Set ATPG clock toward FDSP Code RAM rather than its own clock */
+	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
+			     MEM_FDSP_CODERAM_FUNC_CLK_SEL);
+	if (ret < 0)
+		goto out;
+
+	/* Re-enable FDSP clock */
+	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
+			     MEM_FDSP_CLK_120_ENABLE);
 
 out:
 	return ret;
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h
index 937b71d..ed35519 100644
--- a/drivers/net/wireless/ti/wl18xx/reg.h
+++ b/drivers/net/wireless/ti/wl18xx/reg.h
@@ -188,4 +188,24 @@ enum {
 	NUM_BOARD_TYPES,
 };
 
+/*
+ * The following definitions are used to change the PHY ATPG clock towards
+ * FDSP code RAM. This is done during FW boot before we download the FW.
+ *
+ * This change is required by PG2.1 and has not impact on previous PGs.
+ */
+
+/* FPGA_SPARE_1 register - bits are set as described below */
+#define WL18XX_PHY_FPGA_SPARE_1		0x8093CA40
+#define WL18XX_PHY_END_MEM_ADDR		WL18XX_PHY_FPGA_SPARE_1
+
+/* Bit to disable FDSP clock */
+#define MEM_FDSP_CLK_120_DISABLE        0x80000000
+
+/* Bit to set ATPG clock toward FDSP Code RAM rather than its own clock */
+#define MEM_FDSP_CODERAM_FUNC_CLK_SEL	0xC0000000
+
+/* Bit to re-enable FDSP clock */
+#define MEM_FDSP_CLK_120_ENABLE		0x40000000
+
 #endif /* __REG_H__ */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux