1/*
2 * Copyright (c) 2014 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/kernel.h>
17#include <linux/delay.h>
18#include <linux/list.h>
19#include <linux/ssb/ssb_regs.h>
20#include <linux/bcma/bcma.h>
21#include <linux/bcma/bcma_regs.h>
22
23#include <defs.h>
24#include <soc.h>
25#include <brcm_hw_ids.h>
26#include <brcmu_utils.h>
27#include <chipcommon.h>
28#include "debug.h"
29#include "chip.h"
30
31/* SOC Interconnect types (aka chip types) */
32#define SOCI_SB		0
33#define SOCI_AI		1
34
35/* PL-368 DMP definitions */
36#define DMP_DESC_TYPE_MSK	0x0000000F
37#define  DMP_DESC_EMPTY		0x00000000
38#define  DMP_DESC_VALID		0x00000001
39#define  DMP_DESC_COMPONENT	0x00000001
40#define  DMP_DESC_MASTER_PORT	0x00000003
41#define  DMP_DESC_ADDRESS	0x00000005
42#define  DMP_DESC_ADDRSIZE_GT32	0x00000008
43#define  DMP_DESC_EOT		0x0000000F
44
45#define DMP_COMP_DESIGNER	0xFFF00000
46#define DMP_COMP_DESIGNER_S	20
47#define DMP_COMP_PARTNUM	0x000FFF00
48#define DMP_COMP_PARTNUM_S	8
49#define DMP_COMP_CLASS		0x000000F0
50#define DMP_COMP_CLASS_S	4
51#define DMP_COMP_REVISION	0xFF000000
52#define DMP_COMP_REVISION_S	24
53#define DMP_COMP_NUM_SWRAP	0x00F80000
54#define DMP_COMP_NUM_SWRAP_S	19
55#define DMP_COMP_NUM_MWRAP	0x0007C000
56#define DMP_COMP_NUM_MWRAP_S	14
57#define DMP_COMP_NUM_SPORT	0x00003E00
58#define DMP_COMP_NUM_SPORT_S	9
59#define DMP_COMP_NUM_MPORT	0x000001F0
60#define DMP_COMP_NUM_MPORT_S	4
61
62#define DMP_MASTER_PORT_UID	0x0000FF00
63#define DMP_MASTER_PORT_UID_S	8
64#define DMP_MASTER_PORT_NUM	0x000000F0
65#define DMP_MASTER_PORT_NUM_S	4
66
67#define DMP_SLAVE_ADDR_BASE	0xFFFFF000
68#define DMP_SLAVE_ADDR_BASE_S	12
69#define DMP_SLAVE_PORT_NUM	0x00000F00
70#define DMP_SLAVE_PORT_NUM_S	8
71#define DMP_SLAVE_TYPE		0x000000C0
72#define DMP_SLAVE_TYPE_S	6
73#define  DMP_SLAVE_TYPE_SLAVE	0
74#define  DMP_SLAVE_TYPE_BRIDGE	1
75#define  DMP_SLAVE_TYPE_SWRAP	2
76#define  DMP_SLAVE_TYPE_MWRAP	3
77#define DMP_SLAVE_SIZE_TYPE	0x00000030
78#define DMP_SLAVE_SIZE_TYPE_S	4
79#define  DMP_SLAVE_SIZE_4K	0
80#define  DMP_SLAVE_SIZE_8K	1
81#define  DMP_SLAVE_SIZE_16K	2
82#define  DMP_SLAVE_SIZE_DESC	3
83
84/* EROM CompIdentB */
85#define CIB_REV_MASK		0xff000000
86#define CIB_REV_SHIFT		24
87
88/* ARM CR4 core specific control flag bits */
89#define ARMCR4_BCMA_IOCTL_CPUHALT	0x0020
90
91/* D11 core specific control flag bits */
92#define D11_BCMA_IOCTL_PHYCLOCKEN	0x0004
93#define D11_BCMA_IOCTL_PHYRESET		0x0008
94
95/* chip core base & ramsize */
96/* bcm4329 */
97/* SDIO device core, ID 0x829 */
98#define BCM4329_CORE_BUS_BASE		0x18011000
99/* internal memory core, ID 0x80e */
100#define BCM4329_CORE_SOCRAM_BASE	0x18003000
101/* ARM Cortex M3 core, ID 0x82a */
102#define BCM4329_CORE_ARM_BASE		0x18002000
103
104#define CORE_SB(base, field) \
105		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
106#define	SBCOREREV(sbidh) \
107	((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
108	  ((sbidh) & SSB_IDHIGH_RCLO))
109
110struct sbconfig {
111	u32 PAD[2];
112	u32 sbipsflag;	/* initiator port ocp slave flag */
113	u32 PAD[3];
114	u32 sbtpsflag;	/* target port ocp slave flag */
115	u32 PAD[11];
116	u32 sbtmerrloga;	/* (sonics >= 2.3) */
117	u32 PAD;
118	u32 sbtmerrlog;	/* (sonics >= 2.3) */
119	u32 PAD[3];
120	u32 sbadmatch3;	/* address match3 */
121	u32 PAD;
122	u32 sbadmatch2;	/* address match2 */
123	u32 PAD;
124	u32 sbadmatch1;	/* address match1 */
125	u32 PAD[7];
126	u32 sbimstate;	/* initiator agent state */
127	u32 sbintvec;	/* interrupt mask */
128	u32 sbtmstatelow;	/* target state */
129	u32 sbtmstatehigh;	/* target state */
130	u32 sbbwa0;		/* bandwidth allocation table0 */
131	u32 PAD;
132	u32 sbimconfiglow;	/* initiator configuration */
133	u32 sbimconfighigh;	/* initiator configuration */
134	u32 sbadmatch0;	/* address match0 */
135	u32 PAD;
136	u32 sbtmconfiglow;	/* target configuration */
137	u32 sbtmconfighigh;	/* target configuration */
138	u32 sbbconfig;	/* broadcast configuration */
139	u32 PAD;
140	u32 sbbstate;	/* broadcast state */
141	u32 PAD[3];
142	u32 sbactcnfg;	/* activate configuration */
143	u32 PAD[3];
144	u32 sbflagst;	/* current sbflags */
145	u32 PAD[3];
146	u32 sbidlow;		/* identification */
147	u32 sbidhigh;	/* identification */
148};
149
150/* bankidx and bankinfo reg defines corerev >= 8 */
151#define SOCRAM_BANKINFO_RETNTRAM_MASK	0x00010000
152#define SOCRAM_BANKINFO_SZMASK		0x0000007f
153#define SOCRAM_BANKIDX_ROM_MASK		0x00000100
154
155#define SOCRAM_BANKIDX_MEMTYPE_SHIFT	8
156/* socram bankinfo memtype */
157#define SOCRAM_MEMTYPE_RAM		0
158#define SOCRAM_MEMTYPE_R0M		1
159#define SOCRAM_MEMTYPE_DEVRAM		2
160
161#define SOCRAM_BANKINFO_SZBASE		8192
162#define SRCI_LSS_MASK		0x00f00000
163#define SRCI_LSS_SHIFT		20
164#define	SRCI_SRNB_MASK		0xf0
165#define	SRCI_SRNB_SHIFT		4
166#define	SRCI_SRBSZ_MASK		0xf
167#define	SRCI_SRBSZ_SHIFT	0
168#define SR_BSZ_BASE		14
169
170struct sbsocramregs {
171	u32 coreinfo;
172	u32 bwalloc;
173	u32 extracoreinfo;
174	u32 biststat;
175	u32 bankidx;
176	u32 standbyctrl;
177
178	u32 errlogstatus;	/* rev 6 */
179	u32 errlogaddr;	/* rev 6 */
180	/* used for patching rev 3 & 5 */
181	u32 cambankidx;
182	u32 cambankstandbyctrl;
183	u32 cambankpatchctrl;
184	u32 cambankpatchtblbaseaddr;
185	u32 cambankcmdreg;
186	u32 cambankdatareg;
187	u32 cambankmaskreg;
188	u32 PAD[1];
189	u32 bankinfo;	/* corev 8 */
190	u32 bankpda;
191	u32 PAD[14];
192	u32 extmemconfig;
193	u32 extmemparitycsr;
194	u32 extmemparityerrdata;
195	u32 extmemparityerrcnt;
196	u32 extmemwrctrlandsize;
197	u32 PAD[84];
198	u32 workaround;
199	u32 pwrctl;		/* corerev >= 2 */
200	u32 PAD[133];
201	u32 sr_control;     /* corerev >= 15 */
202	u32 sr_status;      /* corerev >= 15 */
203	u32 sr_address;     /* corerev >= 15 */
204	u32 sr_data;        /* corerev >= 15 */
205};
206
207#define SOCRAMREGOFFS(_f)	offsetof(struct sbsocramregs, _f)
208
209#define ARMCR4_CAP		(0x04)
210#define ARMCR4_BANKIDX		(0x40)
211#define ARMCR4_BANKINFO		(0x44)
212#define ARMCR4_BANKPDA		(0x4C)
213
214#define	ARMCR4_TCBBNB_MASK	0xf0
215#define	ARMCR4_TCBBNB_SHIFT	4
216#define	ARMCR4_TCBANB_MASK	0xf
217#define	ARMCR4_TCBANB_SHIFT	0
218
219#define	ARMCR4_BSZ_MASK		0x3f
220#define	ARMCR4_BSZ_MULT		8192
221
222struct brcmf_core_priv {
223	struct brcmf_core pub;
224	u32 wrapbase;
225	struct list_head list;
226	struct brcmf_chip_priv *chip;
227};
228
229struct brcmf_chip_priv {
230	struct brcmf_chip pub;
231	const struct brcmf_buscore_ops *ops;
232	void *ctx;
233	/* assured first core is chipcommon, second core is buscore */
234	struct list_head cores;
235	u16 num_cores;
236
237	bool (*iscoreup)(struct brcmf_core_priv *core);
238	void (*coredisable)(struct brcmf_core_priv *core, u32 prereset,
239			    u32 reset);
240	void (*resetcore)(struct brcmf_core_priv *core, u32 prereset, u32 reset,
241			  u32 postreset);
242};
243
244static void brcmf_chip_sb_corerev(struct brcmf_chip_priv *ci,
245				  struct brcmf_core *core)
246{
247	u32 regdata;
248
249	regdata = ci->ops->read32(ci->ctx, CORE_SB(core->base, sbidhigh));
250	core->rev = SBCOREREV(regdata);
251}
252
253static bool brcmf_chip_sb_iscoreup(struct brcmf_core_priv *core)
254{
255	struct brcmf_chip_priv *ci;
256	u32 regdata;
257	u32 address;
258
259	ci = core->chip;
260	address = CORE_SB(core->pub.base, sbtmstatelow);
261	regdata = ci->ops->read32(ci->ctx, address);
262	regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
263		    SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
264	return SSB_TMSLOW_CLOCK == regdata;
265}
266
267static bool brcmf_chip_ai_iscoreup(struct brcmf_core_priv *core)
268{
269	struct brcmf_chip_priv *ci;
270	u32 regdata;
271	bool ret;
272
273	ci = core->chip;
274	regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
275	ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
276
277	regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
278	ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
279
280	return ret;
281}
282
283static void brcmf_chip_sb_coredisable(struct brcmf_core_priv *core,
284				      u32 prereset, u32 reset)
285{
286	struct brcmf_chip_priv *ci;
287	u32 val, base;
288
289	ci = core->chip;
290	base = core->pub.base;
291	val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
292	if (val & SSB_TMSLOW_RESET)
293		return;
294
295	val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
296	if ((val & SSB_TMSLOW_CLOCK) != 0) {
297		/*
298		 * set target reject and spin until busy is clear
299		 * (preserve core-specific bits)
300		 */
301		val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
302		ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
303					 val | SSB_TMSLOW_REJECT);
304
305		val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
306		udelay(1);
307		SPINWAIT((ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh))
308			  & SSB_TMSHIGH_BUSY), 100000);
309
310		val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
311		if (val & SSB_TMSHIGH_BUSY)
312			brcmf_err("core state still busy\n");
313
314		val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
315		if (val & SSB_IDLOW_INITIATOR) {
316			val = ci->ops->read32(ci->ctx,
317					      CORE_SB(base, sbimstate));
318			val |= SSB_IMSTATE_REJECT;
319			ci->ops->write32(ci->ctx,
320					 CORE_SB(base, sbimstate), val);
321			val = ci->ops->read32(ci->ctx,
322					      CORE_SB(base, sbimstate));
323			udelay(1);
324			SPINWAIT((ci->ops->read32(ci->ctx,
325						  CORE_SB(base, sbimstate)) &
326				  SSB_IMSTATE_BUSY), 100000);
327		}
328
329		/* set reset and reject while enabling the clocks */
330		val = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
331		      SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
332		ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow), val);
333		val = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
334		udelay(10);
335
336		/* clear the initiator reject bit */
337		val = ci->ops->read32(ci->ctx, CORE_SB(base, sbidlow));
338		if (val & SSB_IDLOW_INITIATOR) {
339			val = ci->ops->read32(ci->ctx,
340					      CORE_SB(base, sbimstate));
341			val &= ~SSB_IMSTATE_REJECT;
342			ci->ops->write32(ci->ctx,
343					 CORE_SB(base, sbimstate), val);
344		}
345	}
346
347	/* leave reset and reject asserted */
348	ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
349			 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
350	udelay(1);
351}
352
353static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
354				      u32 prereset, u32 reset)
355{
356	struct brcmf_chip_priv *ci;
357	u32 regdata;
358
359	ci = core->chip;
360
361	/* if core is already in reset, skip reset */
362	regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
363	if ((regdata & BCMA_RESET_CTL_RESET) != 0)
364		goto in_reset_configure;
365
366	/* configure reset */
367	ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
368			 prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
369	ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
370
371	/* put in reset */
372	ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL,
373			 BCMA_RESET_CTL_RESET);
374	usleep_range(10, 20);
375
376	/* wait till reset is 1 */
377	SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
378		 BCMA_RESET_CTL_RESET, 300);
379
380in_reset_configure:
381	/* in-reset configure */
382	ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
383			 reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
384	ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
385}
386
387static void brcmf_chip_sb_resetcore(struct brcmf_core_priv *core, u32 prereset,
388				    u32 reset, u32 postreset)
389{
390	struct brcmf_chip_priv *ci;
391	u32 regdata;
392	u32 base;
393
394	ci = core->chip;
395	base = core->pub.base;
396	/*
397	 * Must do the disable sequence first to work for
398	 * arbitrary current core state.
399	 */
400	brcmf_chip_sb_coredisable(core, 0, 0);
401
402	/*
403	 * Now do the initialization sequence.
404	 * set reset while enabling the clock and
405	 * forcing them on throughout the core
406	 */
407	ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
408			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
409			 SSB_TMSLOW_RESET);
410	regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
411	udelay(1);
412
413	/* clear any serror */
414	regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatehigh));
415	if (regdata & SSB_TMSHIGH_SERR)
416		ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatehigh), 0);
417
418	regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbimstate));
419	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
420		regdata &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
421		ci->ops->write32(ci->ctx, CORE_SB(base, sbimstate), regdata);
422	}
423
424	/* clear reset and allow it to propagate throughout the core */
425	ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
426			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
427	regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
428	udelay(1);
429
430	/* leave clock enabled */
431	ci->ops->write32(ci->ctx, CORE_SB(base, sbtmstatelow),
432			 SSB_TMSLOW_CLOCK);
433	regdata = ci->ops->read32(ci->ctx, CORE_SB(base, sbtmstatelow));
434	udelay(1);
435}
436
437static void brcmf_chip_ai_resetcore(struct brcmf_core_priv *core, u32 prereset,
438				    u32 reset, u32 postreset)
439{
440	struct brcmf_chip_priv *ci;
441	int count;
442
443	ci = core->chip;
444
445	/* must disable first to work for arbitrary current core state */
446	brcmf_chip_ai_coredisable(core, prereset, reset);
447
448	count = 0;
449	while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) &
450	       BCMA_RESET_CTL_RESET) {
451		ci->ops->write32(ci->ctx, core->wrapbase + BCMA_RESET_CTL, 0);
452		count++;
453		if (count > 50)
454			break;
455		usleep_range(40, 60);
456	}
457
458	ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
459			 postreset | BCMA_IOCTL_CLK);
460	ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL);
461}
462
463static char *brcmf_chip_name(uint chipid, char *buf, uint len)
464{
465	const char *fmt;
466
467	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
468	snprintf(buf, len, fmt, chipid);
469	return buf;
470}
471
472static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
473					      u16 coreid, u32 base,
474					      u32 wrapbase)
475{
476	struct brcmf_core_priv *core;
477
478	core = kzalloc(sizeof(*core), GFP_KERNEL);
479	if (!core)
480		return ERR_PTR(-ENOMEM);
481
482	core->pub.id = coreid;
483	core->pub.base = base;
484	core->chip = ci;
485	core->wrapbase = wrapbase;
486
487	list_add_tail(&core->list, &ci->cores);
488	return &core->pub;
489}
490
491/* safety check for chipinfo */
492static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
493{
494	struct brcmf_core_priv *core;
495	bool need_socram = false;
496	bool has_socram = false;
497	bool cpu_found = false;
498	int idx = 1;
499
500	list_for_each_entry(core, &ci->cores, list) {
501		brcmf_dbg(INFO, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
502			  idx++, core->pub.id, core->pub.rev, core->pub.base,
503			  core->wrapbase);
504
505		switch (core->pub.id) {
506		case BCMA_CORE_ARM_CM3:
507			cpu_found = true;
508			need_socram = true;
509			break;
510		case BCMA_CORE_INTERNAL_MEM:
511			has_socram = true;
512			break;
513		case BCMA_CORE_ARM_CR4:
514			cpu_found = true;
515			break;
516		default:
517			break;
518		}
519	}
520
521	if (!cpu_found) {
522		brcmf_err("CPU core not detected\n");
523		return -ENXIO;
524	}
525	/* check RAM core presence for ARM CM3 core */
526	if (need_socram && !has_socram) {
527		brcmf_err("RAM core not provided with ARM CM3 core\n");
528		return -ENODEV;
529	}
530	return 0;
531}
532
533static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg)
534{
535	return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg);
536}
537
538static void brcmf_chip_core_write32(struct brcmf_core_priv *core,
539				    u16 reg, u32 val)
540{
541	core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val);
542}
543
544static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx,
545				       u32 *banksize)
546{
547	u32 bankinfo;
548	u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
549
550	bankidx |= idx;
551	brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx);
552	bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo));
553	*banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1;
554	*banksize *= SOCRAM_BANKINFO_SZBASE;
555	return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK);
556}
557
558static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
559				      u32 *srsize)
560{
561	u32 coreinfo;
562	uint nb, banksize, lss;
563	bool retent;
564	int i;
565
566	*ramsize = 0;
567	*srsize = 0;
568
569	if (WARN_ON(sr->pub.rev < 4))
570		return;
571
572	if (!brcmf_chip_iscoreup(&sr->pub))
573		brcmf_chip_resetcore(&sr->pub, 0, 0, 0);
574
575	/* Get info for determining size */
576	coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo));
577	nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
578
579	if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) {
580		banksize = (coreinfo & SRCI_SRBSZ_MASK);
581		lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
582		if (lss != 0)
583			nb--;
584		*ramsize = nb * (1 << (banksize + SR_BSZ_BASE));
585		if (lss != 0)
586			*ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
587	} else {
588		nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
589		for (i = 0; i < nb; i++) {
590			retent = brcmf_chip_socram_banksize(sr, i, &banksize);
591			*ramsize += banksize;
592			if (retent)
593				*srsize += banksize;
594		}
595	}
596
597	/* hardcoded save&restore memory sizes */
598	switch (sr->chip->pub.chip) {
599	case BRCM_CC_4334_CHIP_ID:
600		if (sr->chip->pub.chiprev < 2)
601			*srsize = (32 * 1024);
602		break;
603	case BRCM_CC_43430_CHIP_ID:
604		/* assume sr for now as we can not check
605		 * firmware sr capability at this point.
606		 */
607		*srsize = (64 * 1024);
608		break;
609	default:
610		break;
611	}
612}
613
614/** Return the TCM-RAM size of the ARMCR4 core. */
615static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
616{
617	u32 corecap;
618	u32 memsize = 0;
619	u32 nab;
620	u32 nbb;
621	u32 totb;
622	u32 bxinfo;
623	u32 idx;
624
625	corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP);
626
627	nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
628	nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
629	totb = nab + nbb;
630
631	for (idx = 0; idx < totb; idx++) {
632		brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx);
633		bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO);
634		memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
635	}
636
637	return memsize;
638}
639
640static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
641{
642	switch (ci->pub.chip) {
643	case BRCM_CC_4345_CHIP_ID:
644		return 0x198000;
645	case BRCM_CC_4335_CHIP_ID:
646	case BRCM_CC_4339_CHIP_ID:
647	case BRCM_CC_4354_CHIP_ID:
648	case BRCM_CC_4356_CHIP_ID:
649	case BRCM_CC_43567_CHIP_ID:
650	case BRCM_CC_43569_CHIP_ID:
651	case BRCM_CC_43570_CHIP_ID:
652	case BRCM_CC_43602_CHIP_ID:
653		return 0x180000;
654	default:
655		brcmf_err("unknown chip: %s\n", ci->pub.name);
656		break;
657	}
658	return 0;
659}
660
661static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
662{
663	struct brcmf_core_priv *mem_core;
664	struct brcmf_core *mem;
665
666	mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
667	if (mem) {
668		mem_core = container_of(mem, struct brcmf_core_priv, pub);
669		ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
670		ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
671		if (!ci->pub.rambase) {
672			brcmf_err("RAM base not provided with ARM CR4 core\n");
673			return -EINVAL;
674		}
675	} else {
676		mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM);
677		mem_core = container_of(mem, struct brcmf_core_priv, pub);
678		brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
679					  &ci->pub.srsize);
680	}
681	brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
682		  ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
683		  ci->pub.srsize, ci->pub.srsize);
684
685	if (!ci->pub.ramsize) {
686		brcmf_err("RAM size is undetermined\n");
687		return -ENOMEM;
688	}
689	return 0;
690}
691
692static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
693				   u8 *type)
694{
695	u32 val;
696
697	/* read next descriptor */
698	val = ci->ops->read32(ci->ctx, *eromaddr);
699	*eromaddr += 4;
700
701	if (!type)
702		return val;
703
704	/* determine descriptor type */
705	*type = (val & DMP_DESC_TYPE_MSK);
706	if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
707		*type = DMP_DESC_ADDRESS;
708
709	return val;
710}
711
712static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
713				      u32 *regbase, u32 *wrapbase)
714{
715	u8 desc;
716	u32 val;
717	u8 mpnum = 0;
718	u8 stype, sztype, wraptype;
719
720	*regbase = 0;
721	*wrapbase = 0;
722
723	val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
724	if (desc == DMP_DESC_MASTER_PORT) {
725		mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
726		wraptype = DMP_SLAVE_TYPE_MWRAP;
727	} else if (desc == DMP_DESC_ADDRESS) {
728		/* revert erom address */
729		*eromaddr -= 4;
730		wraptype = DMP_SLAVE_TYPE_SWRAP;
731	} else {
732		*eromaddr -= 4;
733		return -EILSEQ;
734	}
735
736	do {
737		/* locate address descriptor */
738		do {
739			val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
740			/* unexpected table end */
741			if (desc == DMP_DESC_EOT) {
742				*eromaddr -= 4;
743				return -EFAULT;
744			}
745		} while (desc != DMP_DESC_ADDRESS);
746
747		/* skip upper 32-bit address descriptor */
748		if (val & DMP_DESC_ADDRSIZE_GT32)
749			brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
750
751		sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
752
753		/* next size descriptor can be skipped */
754		if (sztype == DMP_SLAVE_SIZE_DESC) {
755			val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
756			/* skip upper size descriptor if present */
757			if (val & DMP_DESC_ADDRSIZE_GT32)
758				brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
759		}
760
761		/* only look for 4K register regions */
762		if (sztype != DMP_SLAVE_SIZE_4K)
763			continue;
764
765		stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
766
767		/* only regular slave and wrapper */
768		if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
769			*regbase = val & DMP_SLAVE_ADDR_BASE;
770		if (*wrapbase == 0 && stype == wraptype)
771			*wrapbase = val & DMP_SLAVE_ADDR_BASE;
772	} while (*regbase == 0 || *wrapbase == 0);
773
774	return 0;
775}
776
777static
778int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
779{
780	struct brcmf_core *core;
781	u32 eromaddr;
782	u8 desc_type = 0;
783	u32 val;
784	u16 id;
785	u8 nmp, nsp, nmw, nsw, rev;
786	u32 base, wrap;
787	int err;
788
789	eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
790
791	while (desc_type != DMP_DESC_EOT) {
792		val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
793		if (!(val & DMP_DESC_VALID))
794			continue;
795
796		if (desc_type == DMP_DESC_EMPTY)
797			continue;
798
799		/* need a component descriptor */
800		if (desc_type != DMP_DESC_COMPONENT)
801			continue;
802
803		id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
804
805		/* next descriptor must be component as well */
806		val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
807		if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
808			return -EFAULT;
809
810		/* only look at cores with master port(s) */
811		nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
812		nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
813		nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
814		nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
815		rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
816
817		/* need core with ports */
818		if (nmw + nsw == 0)
819			continue;
820
821		/* try to obtain register address info */
822		err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
823		if (err)
824			continue;
825
826		/* finally a core to be added */
827		core = brcmf_chip_add_core(ci, id, base, wrap);
828		if (IS_ERR(core))
829			return PTR_ERR(core);
830
831		core->rev = rev;
832	}
833
834	return 0;
835}
836
837static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
838{
839	struct brcmf_core *core;
840	u32 regdata;
841	u32 socitype;
842	int ret;
843
844	/* Get CC core rev
845	 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
846	 * For different chiptypes or old sdio hosts w/o chipcommon,
847	 * other ways of recognition should be added here.
848	 */
849	regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
850	ci->pub.chip = regdata & CID_ID_MASK;
851	ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
852	socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
853
854	brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name));
855	brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n",
856		  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
857		  ci->pub.chiprev);
858
859	if (socitype == SOCI_SB) {
860		if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
861			brcmf_err("SB chip is not supported\n");
862			return -ENODEV;
863		}
864		ci->iscoreup = brcmf_chip_sb_iscoreup;
865		ci->coredisable = brcmf_chip_sb_coredisable;
866		ci->resetcore = brcmf_chip_sb_resetcore;
867
868		core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
869					   SI_ENUM_BASE, 0);
870		brcmf_chip_sb_corerev(ci, core);
871		core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
872					   BCM4329_CORE_BUS_BASE, 0);
873		brcmf_chip_sb_corerev(ci, core);
874		core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
875					   BCM4329_CORE_SOCRAM_BASE, 0);
876		brcmf_chip_sb_corerev(ci, core);
877		core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
878					   BCM4329_CORE_ARM_BASE, 0);
879		brcmf_chip_sb_corerev(ci, core);
880
881		core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
882		brcmf_chip_sb_corerev(ci, core);
883	} else if (socitype == SOCI_AI) {
884		ci->iscoreup = brcmf_chip_ai_iscoreup;
885		ci->coredisable = brcmf_chip_ai_coredisable;
886		ci->resetcore = brcmf_chip_ai_resetcore;
887
888		brcmf_chip_dmp_erom_scan(ci);
889	} else {
890		brcmf_err("chip backplane type %u is not supported\n",
891			  socitype);
892		return -ENODEV;
893	}
894
895	ret = brcmf_chip_cores_check(ci);
896	if (ret)
897		return ret;
898
899	/* assure chip is passive for core access */
900	brcmf_chip_set_passive(&ci->pub);
901	return brcmf_chip_get_raminfo(ci);
902}
903
904static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
905{
906	struct brcmf_core *core;
907	struct brcmf_core_priv *cr4;
908	u32 val;
909
910
911	core = brcmf_chip_get_core(&chip->pub, id);
912	if (!core)
913		return;
914
915	switch (id) {
916	case BCMA_CORE_ARM_CM3:
917		brcmf_chip_coredisable(core, 0, 0);
918		break;
919	case BCMA_CORE_ARM_CR4:
920		cr4 = container_of(core, struct brcmf_core_priv, pub);
921
922		/* clear all IOCTL bits except HALT bit */
923		val = chip->ops->read32(chip->ctx, cr4->wrapbase + BCMA_IOCTL);
924		val &= ARMCR4_BCMA_IOCTL_CPUHALT;
925		brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
926				     ARMCR4_BCMA_IOCTL_CPUHALT);
927		break;
928	default:
929		brcmf_err("unknown id: %u\n", id);
930		break;
931	}
932}
933
934static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
935{
936	struct brcmf_chip *pub;
937	struct brcmf_core_priv *cc;
938	u32 base;
939	u32 val;
940	int ret = 0;
941
942	pub = &chip->pub;
943	cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
944	base = cc->pub.base;
945
946	/* get chipcommon capabilites */
947	pub->cc_caps = chip->ops->read32(chip->ctx,
948					 CORE_CC_REG(base, capabilities));
949
950	/* get pmu caps & rev */
951	if (pub->cc_caps & CC_CAP_PMU) {
952		val = chip->ops->read32(chip->ctx,
953					CORE_CC_REG(base, pmucapabilities));
954		pub->pmurev = val & PCAP_REV_MASK;
955		pub->pmucaps = val;
956	}
957
958	brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
959		  cc->pub.rev, pub->pmurev, pub->pmucaps);
960
961	/* execute bus core specific setup */
962	if (chip->ops->setup)
963		ret = chip->ops->setup(chip->ctx, pub);
964
965	return ret;
966}
967
968struct brcmf_chip *brcmf_chip_attach(void *ctx,
969				     const struct brcmf_buscore_ops *ops)
970{
971	struct brcmf_chip_priv *chip;
972	int err = 0;
973
974	if (WARN_ON(!ops->read32))
975		err = -EINVAL;
976	if (WARN_ON(!ops->write32))
977		err = -EINVAL;
978	if (WARN_ON(!ops->prepare))
979		err = -EINVAL;
980	if (WARN_ON(!ops->activate))
981		err = -EINVAL;
982	if (err < 0)
983		return ERR_PTR(-EINVAL);
984
985	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
986	if (!chip)
987		return ERR_PTR(-ENOMEM);
988
989	INIT_LIST_HEAD(&chip->cores);
990	chip->num_cores = 0;
991	chip->ops = ops;
992	chip->ctx = ctx;
993
994	err = ops->prepare(ctx);
995	if (err < 0)
996		goto fail;
997
998	err = brcmf_chip_recognition(chip);
999	if (err < 0)
1000		goto fail;
1001
1002	err = brcmf_chip_setup(chip);
1003	if (err < 0)
1004		goto fail;
1005
1006	return &chip->pub;
1007
1008fail:
1009	brcmf_chip_detach(&chip->pub);
1010	return ERR_PTR(err);
1011}
1012
1013void brcmf_chip_detach(struct brcmf_chip *pub)
1014{
1015	struct brcmf_chip_priv *chip;
1016	struct brcmf_core_priv *core;
1017	struct brcmf_core_priv *tmp;
1018
1019	chip = container_of(pub, struct brcmf_chip_priv, pub);
1020	list_for_each_entry_safe(core, tmp, &chip->cores, list) {
1021		list_del(&core->list);
1022		kfree(core);
1023	}
1024	kfree(chip);
1025}
1026
1027struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
1028{
1029	struct brcmf_chip_priv *chip;
1030	struct brcmf_core_priv *core;
1031
1032	chip = container_of(pub, struct brcmf_chip_priv, pub);
1033	list_for_each_entry(core, &chip->cores, list)
1034		if (core->pub.id == coreid)
1035			return &core->pub;
1036
1037	return NULL;
1038}
1039
1040struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
1041{
1042	struct brcmf_chip_priv *chip;
1043	struct brcmf_core_priv *cc;
1044
1045	chip = container_of(pub, struct brcmf_chip_priv, pub);
1046	cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
1047	if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
1048		return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
1049	return &cc->pub;
1050}
1051
1052bool brcmf_chip_iscoreup(struct brcmf_core *pub)
1053{
1054	struct brcmf_core_priv *core;
1055
1056	core = container_of(pub, struct brcmf_core_priv, pub);
1057	return core->chip->iscoreup(core);
1058}
1059
1060void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
1061{
1062	struct brcmf_core_priv *core;
1063
1064	core = container_of(pub, struct brcmf_core_priv, pub);
1065	core->chip->coredisable(core, prereset, reset);
1066}
1067
1068void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
1069			  u32 postreset)
1070{
1071	struct brcmf_core_priv *core;
1072
1073	core = container_of(pub, struct brcmf_core_priv, pub);
1074	core->chip->resetcore(core, prereset, reset, postreset);
1075}
1076
1077static void
1078brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
1079{
1080	struct brcmf_core *core;
1081	struct brcmf_core_priv *sr;
1082
1083	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
1084	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1085	brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1086				   D11_BCMA_IOCTL_PHYCLOCKEN,
1087			     D11_BCMA_IOCTL_PHYCLOCKEN,
1088			     D11_BCMA_IOCTL_PHYCLOCKEN);
1089	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
1090	brcmf_chip_resetcore(core, 0, 0, 0);
1091
1092	/* disable bank #3 remap for this device */
1093	if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
1094		sr = container_of(core, struct brcmf_core_priv, pub);
1095		brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
1096		brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
1097	}
1098}
1099
1100static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
1101{
1102	struct brcmf_core *core;
1103
1104	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
1105	if (!brcmf_chip_iscoreup(core)) {
1106		brcmf_err("SOCRAM core is down after reset?\n");
1107		return false;
1108	}
1109
1110	chip->ops->activate(chip->ctx, &chip->pub, 0);
1111
1112	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
1113	brcmf_chip_resetcore(core, 0, 0, 0);
1114
1115	return true;
1116}
1117
1118static inline void
1119brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)
1120{
1121	struct brcmf_core *core;
1122
1123	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
1124
1125	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1126	brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1127				   D11_BCMA_IOCTL_PHYCLOCKEN,
1128			     D11_BCMA_IOCTL_PHYCLOCKEN,
1129			     D11_BCMA_IOCTL_PHYCLOCKEN);
1130}
1131
1132static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
1133{
1134	struct brcmf_core *core;
1135
1136	chip->ops->activate(chip->ctx, &chip->pub, rstvec);
1137
1138	/* restore ARM */
1139	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
1140	brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
1141
1142	return true;
1143}
1144
1145void brcmf_chip_set_passive(struct brcmf_chip *pub)
1146{
1147	struct brcmf_chip_priv *chip;
1148	struct brcmf_core *arm;
1149
1150	brcmf_dbg(TRACE, "Enter\n");
1151
1152	chip = container_of(pub, struct brcmf_chip_priv, pub);
1153	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
1154	if (arm) {
1155		brcmf_chip_cr4_set_passive(chip);
1156		return;
1157	}
1158
1159	brcmf_chip_cm3_set_passive(chip);
1160}
1161
1162bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
1163{
1164	struct brcmf_chip_priv *chip;
1165	struct brcmf_core *arm;
1166
1167	brcmf_dbg(TRACE, "Enter\n");
1168
1169	chip = container_of(pub, struct brcmf_chip_priv, pub);
1170	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
1171	if (arm)
1172		return brcmf_chip_cr4_set_active(chip, rstvec);
1173
1174	return brcmf_chip_cm3_set_active(chip);
1175}
1176
1177bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
1178{
1179	u32 base, addr, reg, pmu_cc3_mask = ~0;
1180	struct brcmf_chip_priv *chip;
1181
1182	brcmf_dbg(TRACE, "Enter\n");
1183
1184	/* old chips with PMU version less than 17 don't support save restore */
1185	if (pub->pmurev < 17)
1186		return false;
1187
1188	base = brcmf_chip_get_chipcommon(pub)->base;
1189	chip = container_of(pub, struct brcmf_chip_priv, pub);
1190
1191	switch (pub->chip) {
1192	case BRCM_CC_4354_CHIP_ID:
1193		/* explicitly check SR engine enable bit */
1194		pmu_cc3_mask = BIT(2);
1195		/* fall-through */
1196	case BRCM_CC_43241_CHIP_ID:
1197	case BRCM_CC_4335_CHIP_ID:
1198	case BRCM_CC_4339_CHIP_ID:
1199		/* read PMU chipcontrol register 3 */
1200		addr = CORE_CC_REG(base, chipcontrol_addr);
1201		chip->ops->write32(chip->ctx, addr, 3);
1202		addr = CORE_CC_REG(base, chipcontrol_data);
1203		reg = chip->ops->read32(chip->ctx, addr);
1204		return (reg & pmu_cc3_mask) != 0;
1205	case BRCM_CC_43430_CHIP_ID:
1206		addr = CORE_CC_REG(base, sr_control1);
1207		reg = chip->ops->read32(chip->ctx, addr);
1208		return reg != 0;
1209	default:
1210		addr = CORE_CC_REG(base, pmucapabilities_ext);
1211		reg = chip->ops->read32(chip->ctx, addr);
1212		if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
1213			return false;
1214
1215		addr = CORE_CC_REG(base, retention_ctl);
1216		reg = chip->ops->read32(chip->ctx, addr);
1217		return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
1218			       PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
1219	}
1220}
1221