diff options
author | Ido Reis <idor@ti.com> | 2012-11-27 01:44:51 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2013-06-17 04:56:58 -0400 |
commit | e3b8bbb9e81536f19d6e0b2c6e8186db47dfd426 (patch) | |
tree | 699746df2df9e36326a6ad2baa4e9537eb0f40f1 /drivers/net/wireless/ti/wl18xx/main.c | |
parent | 1105a13bb8ad29cf83d46989ee462d196038be87 (diff) |
wl18xx: FDSP Code RAM Corruption fix
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@ti.com>
Signed-off-by: Ido Reis <idor@ti.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/ti/wl18xx/main.c')
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/main.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 9fa692d11025..ae85ae46c61b 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -594,8 +594,8 @@ static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { | |||
594 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, | 594 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, |
595 | }, | 595 | }, |
596 | [PART_PHY_INIT] = { | 596 | [PART_PHY_INIT] = { |
597 | .mem = { .start = 0x80926000, | 597 | .mem = { .start = WL18XX_PHY_INIT_MEM_ADDR, |
598 | .size = sizeof(struct wl18xx_mac_and_phy_params) }, | 598 | .size = WL18XX_PHY_INIT_MEM_SIZE }, |
599 | .reg = { .start = 0x00000000, .size = 0x00000000 }, | 599 | .reg = { .start = 0x00000000, .size = 0x00000000 }, |
600 | .mem2 = { .start = 0x00000000, .size = 0x00000000 }, | 600 | .mem2 = { .start = 0x00000000, .size = 0x00000000 }, |
601 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, | 601 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, |
@@ -799,6 +799,9 @@ static int wl18xx_pre_upload(struct wl1271 *wl) | |||
799 | u32 tmp; | 799 | u32 tmp; |
800 | int ret; | 800 | int ret; |
801 | 801 | ||
802 | BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) > | ||
803 | WL18XX_PHY_INIT_MEM_SIZE); | ||
804 | |||
802 | ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); | 805 | ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); |
803 | if (ret < 0) | 806 | if (ret < 0) |
804 | goto out; | 807 | goto out; |
@@ -815,6 +818,35 @@ static int wl18xx_pre_upload(struct wl1271 *wl) | |||
815 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); | 818 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); |
816 | 819 | ||
817 | ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp); | 820 | ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp); |
821 | if (ret < 0) | ||
822 | goto out; | ||
823 | |||
824 | /* | ||
825 | * Workaround for FDSP code RAM corruption (needed for PG2.1 | ||
826 | * and newer; for older chips it's a NOP). Change FDSP clock | ||
827 | * settings so that it's muxed to the ATGP clock instead of | ||
828 | * its own clock. | ||
829 | */ | ||
830 | |||
831 | ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); | ||
832 | if (ret < 0) | ||
833 | goto out; | ||
834 | |||
835 | /* disable FDSP clock */ | ||
836 | ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, | ||
837 | MEM_FDSP_CLK_120_DISABLE); | ||
838 | if (ret < 0) | ||
839 | goto out; | ||
840 | |||
841 | /* set ATPG clock toward FDSP Code RAM rather than its own clock */ | ||
842 | ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, | ||
843 | MEM_FDSP_CODERAM_FUNC_CLK_SEL); | ||
844 | if (ret < 0) | ||
845 | goto out; | ||
846 | |||
847 | /* re-enable FDSP clock */ | ||
848 | ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1, | ||
849 | MEM_FDSP_CLK_120_ENABLE); | ||
818 | 850 | ||
819 | out: | 851 | out: |
820 | return ret; | 852 | return ret; |