File Index
Files and directories
Sign in
FILE

chip.c

File preview with syntax highlighting.

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