aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 1e01ae254622..f198a48bc2ca 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -22,6 +22,7 @@
22#include <brcm_hw_ids.h> 22#include <brcm_hw_ids.h>
23#include <brcmu_wifi.h> 23#include <brcmu_wifi.h>
24#include <brcmu_utils.h> 24#include <brcmu_utils.h>
25#include <soc.h>
25#include "dhd.h" 26#include "dhd.h"
26#include "dhd_dbg.h" 27#include "dhd_dbg.h"
27#include "sdio_host.h" 28#include "sdio_host.h"
@@ -51,6 +52,85 @@
51#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ 52#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
52#define SBIDH_VC_SHIFT 16 53#define SBIDH_VC_SHIFT 16
53 54
55void
56brcmf_sdio_chip_coredisable(struct brcmf_sdio_dev *sdiodev, u32 corebase)
57{
58 u32 regdata;
59
60 regdata = brcmf_sdcard_reg_read(sdiodev,
61 CORE_SB(corebase, sbtmstatelow), 4);
62 if (regdata & SBTML_RESET)
63 return;
64
65 regdata = brcmf_sdcard_reg_read(sdiodev,
66 CORE_SB(corebase, sbtmstatelow), 4);
67 if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
68 /*
69 * set target reject and spin until busy is clear
70 * (preserve core-specific bits)
71 */
72 regdata = brcmf_sdcard_reg_read(sdiodev,
73 CORE_SB(corebase, sbtmstatelow), 4);
74 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow),
75 4, regdata | SBTML_REJ);
76
77 regdata = brcmf_sdcard_reg_read(sdiodev,
78 CORE_SB(corebase, sbtmstatelow), 4);
79 udelay(1);
80 SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
81 CORE_SB(corebase, sbtmstatehigh), 4) &
82 SBTMH_BUSY), 100000);
83
84 regdata = brcmf_sdcard_reg_read(sdiodev,
85 CORE_SB(corebase, sbtmstatehigh), 4);
86 if (regdata & SBTMH_BUSY)
87 brcmf_dbg(ERROR, "core state still busy\n");
88
89 regdata = brcmf_sdcard_reg_read(sdiodev,
90 CORE_SB(corebase, sbidlow), 4);
91 if (regdata & SBIDL_INIT) {
92 regdata = brcmf_sdcard_reg_read(sdiodev,
93 CORE_SB(corebase, sbimstate), 4) |
94 SBIM_RJ;
95 brcmf_sdcard_reg_write(sdiodev,
96 CORE_SB(corebase, sbimstate), 4,
97 regdata);
98 regdata = brcmf_sdcard_reg_read(sdiodev,
99 CORE_SB(corebase, sbimstate), 4);
100 udelay(1);
101 SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
102 CORE_SB(corebase, sbimstate), 4) &
103 SBIM_BY), 100000);
104 }
105
106 /* set reset and reject while enabling the clocks */
107 brcmf_sdcard_reg_write(sdiodev,
108 CORE_SB(corebase, sbtmstatelow), 4,
109 (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
110 SBTML_REJ | SBTML_RESET));
111 regdata = brcmf_sdcard_reg_read(sdiodev,
112 CORE_SB(corebase, sbtmstatelow), 4);
113 udelay(10);
114
115 /* clear the initiator reject bit */
116 regdata = brcmf_sdcard_reg_read(sdiodev,
117 CORE_SB(corebase, sbidlow), 4);
118 if (regdata & SBIDL_INIT) {
119 regdata = brcmf_sdcard_reg_read(sdiodev,
120 CORE_SB(corebase, sbimstate), 4) &
121 ~SBIM_RJ;
122 brcmf_sdcard_reg_write(sdiodev,
123 CORE_SB(corebase, sbimstate), 4,
124 regdata);
125 }
126 }
127
128 /* leave reset and reject asserted */
129 brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4,
130 (SBTML_REJ | SBTML_RESET));
131 udelay(1);
132}
133
54static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, 134static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
55 struct chip_info *ci, u32 regs) 135 struct chip_info *ci, u32 regs)
56{ 136{