brintos

brintos / linux-shallow public Read only

0
0
Text · 38.2 KiB · 2ef92ef Raw
1471 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2014 Broadcom Corporation4 */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		022#define SOCI_AI		123 24/* PL-368 DMP definitions */25#define DMP_DESC_TYPE_MSK	0x0000000F26#define  DMP_DESC_EMPTY		0x0000000027#define  DMP_DESC_VALID		0x0000000128#define  DMP_DESC_COMPONENT	0x0000000129#define  DMP_DESC_MASTER_PORT	0x0000000330#define  DMP_DESC_ADDRESS	0x0000000531#define  DMP_DESC_ADDRSIZE_GT32	0x0000000832#define  DMP_DESC_EOT		0x0000000F33 34#define DMP_COMP_DESIGNER	0xFFF0000035#define DMP_COMP_DESIGNER_S	2036#define DMP_COMP_PARTNUM	0x000FFF0037#define DMP_COMP_PARTNUM_S	838#define DMP_COMP_CLASS		0x000000F039#define DMP_COMP_CLASS_S	440#define DMP_COMP_REVISION	0xFF00000041#define DMP_COMP_REVISION_S	2442#define DMP_COMP_NUM_SWRAP	0x00F8000043#define DMP_COMP_NUM_SWRAP_S	1944#define DMP_COMP_NUM_MWRAP	0x0007C00045#define DMP_COMP_NUM_MWRAP_S	1446#define DMP_COMP_NUM_SPORT	0x00003E0047#define DMP_COMP_NUM_SPORT_S	948#define DMP_COMP_NUM_MPORT	0x000001F049#define DMP_COMP_NUM_MPORT_S	450 51#define DMP_MASTER_PORT_UID	0x0000FF0052#define DMP_MASTER_PORT_UID_S	853#define DMP_MASTER_PORT_NUM	0x000000F054#define DMP_MASTER_PORT_NUM_S	455 56#define DMP_SLAVE_ADDR_BASE	0xFFFFF00057#define DMP_SLAVE_ADDR_BASE_S	1258#define DMP_SLAVE_PORT_NUM	0x00000F0059#define DMP_SLAVE_PORT_NUM_S	860#define DMP_SLAVE_TYPE		0x000000C061#define DMP_SLAVE_TYPE_S	662#define  DMP_SLAVE_TYPE_SLAVE	063#define  DMP_SLAVE_TYPE_BRIDGE	164#define  DMP_SLAVE_TYPE_SWRAP	265#define  DMP_SLAVE_TYPE_MWRAP	366#define DMP_SLAVE_SIZE_TYPE	0x0000003067#define DMP_SLAVE_SIZE_TYPE_S	468#define  DMP_SLAVE_SIZE_4K	069#define  DMP_SLAVE_SIZE_8K	170#define  DMP_SLAVE_SIZE_16K	271#define  DMP_SLAVE_SIZE_DESC	372 73/* EROM CompIdentB */74#define CIB_REV_MASK		0xff00000075#define CIB_REV_SHIFT		2476 77/* ARM CR4 core specific control flag bits */78#define ARMCR4_BCMA_IOCTL_CPUHALT	0x002079 80/* D11 core specific control flag bits */81#define D11_BCMA_IOCTL_PHYCLOCKEN	0x000482#define D11_BCMA_IOCTL_PHYRESET		0x000883 84/* chip core base & ramsize */85/* bcm4329 */86/* SDIO device core, ID 0x829 */87#define BCM4329_CORE_BUS_BASE		0x1801100088/* internal memory core, ID 0x80e */89#define BCM4329_CORE_SOCRAM_BASE	0x1800300090/* ARM Cortex M3 core, ID 0x82a */91#define BCM4329_CORE_ARM_BASE		0x1800200092 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	0x00010000146#define SOCRAM_BANKINFO_SZMASK		0x0000007f147#define SOCRAM_BANKIDX_ROM_MASK		0x00000100148 149#define SOCRAM_BANKIDX_MEMTYPE_SHIFT	8150/* socram bankinfo memtype */151#define SOCRAM_MEMTYPE_RAM		0152#define SOCRAM_MEMTYPE_R0M		1153#define SOCRAM_MEMTYPE_DEVRAM		2154 155#define SOCRAM_BANKINFO_SZBASE		8192156#define SRCI_LSS_MASK		0x00f00000157#define SRCI_LSS_SHIFT		20158#define	SRCI_SRNB_MASK		0xf0159#define	SRCI_SRNB_MASK_EXT	0x100160#define	SRCI_SRNB_SHIFT		4161#define	SRCI_SRBSZ_MASK		0xf162#define	SRCI_SRBSZ_SHIFT	0163#define SR_BSZ_BASE		14164 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	0xf0211#define	ARMCR4_TCBBNB_SHIFT	4212#define	ARMCR4_TCBANB_MASK	0xf213#define	ARMCR4_TCBANB_SHIFT	0214 215#define	ARMCR4_BSZ_MASK		0x7f216#define	ARMCR4_BSZ_MULT		8192217#define	ARMCR4_BLK_1K_MASK	0x200218 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 clear296		 * (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 for395	 * 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 and402	 * forcing them on throughout the core403	 */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 check647		 * 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 CY_CC_43752_CHIP_ID:742	case BRCM_CC_4377_CHIP_ID:743		return 0x170000;744	case BRCM_CC_4378_CHIP_ID:745		return 0x352000;746	case BRCM_CC_4387_CHIP_ID:747		return 0x740000;748	default:749		brcmf_err("unknown chip: %s\n", ci->pub.name);750		break;751	}752	return INVALID_RAMBASE;753}754 755int brcmf_chip_get_raminfo(struct brcmf_chip *pub)756{757	struct brcmf_chip_priv *ci = container_of(pub, struct brcmf_chip_priv,758						  pub);759	struct brcmf_core_priv *mem_core;760	struct brcmf_core *mem;761 762	mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);763	if (mem) {764		mem_core = container_of(mem, struct brcmf_core_priv, pub);765		ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);766		ci->pub.rambase = brcmf_chip_tcm_rambase(ci);767		if (ci->pub.rambase == INVALID_RAMBASE) {768			brcmf_err("RAM base not provided with ARM CR4 core\n");769			return -EINVAL;770		}771	} else {772		mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_SYS_MEM);773		if (mem) {774			mem_core = container_of(mem, struct brcmf_core_priv,775						pub);776			ci->pub.ramsize = brcmf_chip_sysmem_ramsize(mem_core);777			ci->pub.rambase = brcmf_chip_tcm_rambase(ci);778			if (ci->pub.rambase == INVALID_RAMBASE) {779				brcmf_err("RAM base not provided with ARM CA7 core\n");780				return -EINVAL;781			}782		} else {783			mem = brcmf_chip_get_core(&ci->pub,784						  BCMA_CORE_INTERNAL_MEM);785			if (!mem) {786				brcmf_err("No memory cores found\n");787				return -ENOMEM;788			}789			mem_core = container_of(mem, struct brcmf_core_priv,790						pub);791			brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,792						  &ci->pub.srsize);793		}794	}795	brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",796		  ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,797		  ci->pub.srsize, ci->pub.srsize);798 799	if (!ci->pub.ramsize) {800		brcmf_err("RAM size is undetermined\n");801		return -ENOMEM;802	}803 804	if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) {805		brcmf_err("RAM size is incorrect\n");806		return -ENOMEM;807	}808 809	return 0;810}811 812static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,813				   u8 *type)814{815	u32 val;816 817	/* read next descriptor */818	val = ci->ops->read32(ci->ctx, *eromaddr);819	*eromaddr += 4;820 821	if (!type)822		return val;823 824	/* determine descriptor type */825	*type = (val & DMP_DESC_TYPE_MSK);826	if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)827		*type = DMP_DESC_ADDRESS;828 829	return val;830}831 832static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,833				      u32 *regbase, u32 *wrapbase)834{835	u8 desc;836	u32 val, szdesc;837	u8 stype, sztype, wraptype;838 839	*regbase = 0;840	*wrapbase = 0;841 842	val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);843	if (desc == DMP_DESC_MASTER_PORT) {844		wraptype = DMP_SLAVE_TYPE_MWRAP;845	} else if (desc == DMP_DESC_ADDRESS) {846		/* revert erom address */847		*eromaddr -= 4;848		wraptype = DMP_SLAVE_TYPE_SWRAP;849	} else {850		*eromaddr -= 4;851		return -EILSEQ;852	}853 854	do {855		/* locate address descriptor */856		do {857			val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);858			/* unexpected table end */859			if (desc == DMP_DESC_EOT) {860				*eromaddr -= 4;861				return -EFAULT;862			}863		} while (desc != DMP_DESC_ADDRESS &&864			 desc != DMP_DESC_COMPONENT);865 866		/* stop if we crossed current component border */867		if (desc == DMP_DESC_COMPONENT) {868			*eromaddr -= 4;869			return 0;870		}871 872		/* skip upper 32-bit address descriptor */873		if (val & DMP_DESC_ADDRSIZE_GT32)874			brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);875 876		sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;877 878		/* next size descriptor can be skipped */879		if (sztype == DMP_SLAVE_SIZE_DESC) {880			szdesc = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);881			/* skip upper size descriptor if present */882			if (szdesc & DMP_DESC_ADDRSIZE_GT32)883				brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);884		}885 886		/* look for 4K or 8K register regions */887		if (sztype != DMP_SLAVE_SIZE_4K &&888		    sztype != DMP_SLAVE_SIZE_8K)889			continue;890 891		stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;892 893		/* only regular slave and wrapper */894		if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)895			*regbase = val & DMP_SLAVE_ADDR_BASE;896		if (*wrapbase == 0 && stype == wraptype)897			*wrapbase = val & DMP_SLAVE_ADDR_BASE;898	} while (*regbase == 0 || *wrapbase == 0);899 900	return 0;901}902 903static904int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)905{906	struct brcmf_core *core;907	u32 eromaddr;908	u8 desc_type = 0;909	u32 val;910	u16 id;911	u8 nmw, nsw, rev;912	u32 base, wrap;913	int err;914 915	eromaddr = ci->ops->read32(ci->ctx,916				   CORE_CC_REG(ci->pub.enum_base, eromptr));917 918	while (desc_type != DMP_DESC_EOT) {919		val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);920		if (!(val & DMP_DESC_VALID))921			continue;922 923		if (desc_type == DMP_DESC_EMPTY)924			continue;925 926		/* need a component descriptor */927		if (desc_type != DMP_DESC_COMPONENT)928			continue;929 930		id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;931 932		/* next descriptor must be component as well */933		val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);934		if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))935			return -EFAULT;936 937		/* only look at cores with master port(s) */938		nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;939		nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;940		rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;941 942		/* need core with ports */943		if (nmw + nsw == 0 &&944		    id != BCMA_CORE_PMU &&945		    id != BCMA_CORE_GCI)946			continue;947 948		/* try to obtain register address info */949		err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);950		if (err)951			continue;952 953		/* finally a core to be added */954		core = brcmf_chip_add_core(ci, id, base, wrap);955		if (IS_ERR(core))956			return PTR_ERR(core);957 958		core->rev = rev;959	}960 961	return 0;962}963 964u32 brcmf_chip_enum_base(u16 devid)965{966	return SI_ENUM_BASE_DEFAULT;967}968 969static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)970{971	struct brcmf_core *core;972	u32 regdata;973	u32 socitype;974	int ret;975	const u32 READ_FAILED = 0xFFFFFFFF;976 977	/* Get CC core rev978	 * Chipid is assume to be at offset 0 from SI_ENUM_BASE979	 * For different chiptypes or old sdio hosts w/o chipcommon,980	 * other ways of recognition should be added here.981	 */982	regdata = ci->ops->read32(ci->ctx,983				  CORE_CC_REG(ci->pub.enum_base, chipid));984	if (regdata == READ_FAILED) {985		brcmf_err("MMIO read failed: 0x%08x\n", regdata);986		return -ENODEV;987	}988 989	ci->pub.chip = regdata & CID_ID_MASK;990	ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;991	socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;992 993	brcmf_chip_name(ci->pub.chip, ci->pub.chiprev,994			ci->pub.name, sizeof(ci->pub.name));995	brcmf_dbg(INFO, "found %s chip: %s\n",996		  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name);997 998	if (socitype == SOCI_SB) {999		if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {1000			brcmf_err("SB chip is not supported\n");1001			return -ENODEV;1002		}1003		ci->iscoreup = brcmf_chip_sb_iscoreup;1004		ci->coredisable = brcmf_chip_sb_coredisable;1005		ci->resetcore = brcmf_chip_sb_resetcore;1006 1007		core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,1008					   SI_ENUM_BASE_DEFAULT, 0);1009		brcmf_chip_sb_corerev(ci, core);1010		core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,1011					   BCM4329_CORE_BUS_BASE, 0);1012		brcmf_chip_sb_corerev(ci, core);1013		core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,1014					   BCM4329_CORE_SOCRAM_BASE, 0);1015		brcmf_chip_sb_corerev(ci, core);1016		core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,1017					   BCM4329_CORE_ARM_BASE, 0);1018		brcmf_chip_sb_corerev(ci, core);1019 1020		core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);1021		brcmf_chip_sb_corerev(ci, core);1022	} else if (socitype == SOCI_AI) {1023		ci->iscoreup = brcmf_chip_ai_iscoreup;1024		ci->coredisable = brcmf_chip_ai_coredisable;1025		ci->resetcore = brcmf_chip_ai_resetcore;1026 1027		brcmf_chip_dmp_erom_scan(ci);1028	} else {1029		brcmf_err("chip backplane type %u is not supported\n",1030			  socitype);1031		return -ENODEV;1032	}1033 1034	ret = brcmf_chip_cores_check(ci);1035	if (ret)1036		return ret;1037 1038	/* assure chip is passive for core access */1039	brcmf_chip_set_passive(&ci->pub);1040 1041	/* Call bus specific reset function now. Cores have been determined1042	 * but further access may require a chip specific reset at this point.1043	 */1044	if (ci->ops->reset) {1045		ci->ops->reset(ci->ctx, &ci->pub);1046		brcmf_chip_set_passive(&ci->pub);1047	}1048 1049	return brcmf_chip_get_raminfo(&ci->pub);1050}1051 1052static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)1053{1054	struct brcmf_core *core;1055	struct brcmf_core_priv *cpu;1056	u32 val;1057 1058 1059	core = brcmf_chip_get_core(&chip->pub, id);1060	if (!core)1061		return;1062 1063	switch (id) {1064	case BCMA_CORE_ARM_CM3:1065		brcmf_chip_coredisable(core, 0, 0);1066		break;1067	case BCMA_CORE_ARM_CR4:1068	case BCMA_CORE_ARM_CA7:1069		cpu = container_of(core, struct brcmf_core_priv, pub);1070 1071		/* clear all IOCTL bits except HALT bit */1072		val = chip->ops->read32(chip->ctx, cpu->wrapbase + BCMA_IOCTL);1073		val &= ARMCR4_BCMA_IOCTL_CPUHALT;1074		brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,1075				     ARMCR4_BCMA_IOCTL_CPUHALT);1076		break;1077	default:1078		brcmf_err("unknown id: %u\n", id);1079		break;1080	}1081}1082 1083static int brcmf_chip_setup(struct brcmf_chip_priv *chip)1084{1085	struct brcmf_chip *pub;1086	struct brcmf_core_priv *cc;1087	struct brcmf_core *pmu;1088	u32 base;1089	u32 val;1090	int ret = 0;1091 1092	pub = &chip->pub;1093	cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);1094	base = cc->pub.base;1095 1096	/* get chipcommon capabilites */1097	pub->cc_caps = chip->ops->read32(chip->ctx,1098					 CORE_CC_REG(base, capabilities));1099	pub->cc_caps_ext = chip->ops->read32(chip->ctx,1100					     CORE_CC_REG(base,1101							 capabilities_ext));1102 1103	/* get pmu caps & rev */1104	pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */1105	if (pub->cc_caps & CC_CAP_PMU) {1106		val = chip->ops->read32(chip->ctx,1107					CORE_CC_REG(pmu->base, pmucapabilities));1108		pub->pmurev = val & PCAP_REV_MASK;1109		pub->pmucaps = val;1110	}1111 1112	brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",1113		  cc->pub.rev, pub->pmurev, pub->pmucaps);1114 1115	/* execute bus core specific setup */1116	if (chip->ops->setup)1117		ret = chip->ops->setup(chip->ctx, pub);1118 1119	return ret;1120}1121 1122struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid,1123				     const struct brcmf_buscore_ops *ops)1124{1125	struct brcmf_chip_priv *chip;1126	int err = 0;1127 1128	if (WARN_ON(!ops->read32))1129		err = -EINVAL;1130	if (WARN_ON(!ops->write32))1131		err = -EINVAL;1132	if (WARN_ON(!ops->prepare))1133		err = -EINVAL;1134	if (WARN_ON(!ops->activate))1135		err = -EINVAL;1136	if (err < 0)1137		return ERR_PTR(-EINVAL);1138 1139	chip = kzalloc(sizeof(*chip), GFP_KERNEL);1140	if (!chip)1141		return ERR_PTR(-ENOMEM);1142 1143	INIT_LIST_HEAD(&chip->cores);1144	chip->num_cores = 0;1145	chip->ops = ops;1146	chip->ctx = ctx;1147	chip->pub.enum_base = brcmf_chip_enum_base(devid);1148 1149	err = ops->prepare(ctx);1150	if (err < 0)1151		goto fail;1152 1153	err = brcmf_chip_recognition(chip);1154	if (err < 0)1155		goto fail;1156 1157	err = brcmf_chip_setup(chip);1158	if (err < 0)1159		goto fail;1160 1161	return &chip->pub;1162 1163fail:1164	brcmf_chip_detach(&chip->pub);1165	return ERR_PTR(err);1166}1167 1168void brcmf_chip_detach(struct brcmf_chip *pub)1169{1170	struct brcmf_chip_priv *chip;1171	struct brcmf_core_priv *core;1172	struct brcmf_core_priv *tmp;1173 1174	chip = container_of(pub, struct brcmf_chip_priv, pub);1175	list_for_each_entry_safe(core, tmp, &chip->cores, list) {1176		list_del(&core->list);1177		kfree(core);1178	}1179	kfree(chip);1180}1181 1182struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit)1183{1184	struct brcmf_chip_priv *chip;1185	struct brcmf_core_priv *core;1186 1187	chip = container_of(pub, struct brcmf_chip_priv, pub);1188	list_for_each_entry(core, &chip->cores, list) {1189		if (core->pub.id == BCMA_CORE_80211) {1190			if (unit-- == 0)1191				return &core->pub;1192		}1193	}1194	return NULL;1195}1196 1197struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)1198{1199	struct brcmf_chip_priv *chip;1200	struct brcmf_core_priv *core;1201 1202	chip = container_of(pub, struct brcmf_chip_priv, pub);1203	list_for_each_entry(core, &chip->cores, list)1204		if (core->pub.id == coreid)1205			return &core->pub;1206 1207	return NULL;1208}1209 1210struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)1211{1212	struct brcmf_chip_priv *chip;1213	struct brcmf_core_priv *cc;1214 1215	chip = container_of(pub, struct brcmf_chip_priv, pub);1216	cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);1217	if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))1218		return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);1219	return &cc->pub;1220}1221 1222struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub)1223{1224	struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub);1225	struct brcmf_core *pmu;1226 1227	/* See if there is separated PMU core available */1228	if (cc->rev >= 35 &&1229	    pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {1230		pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU);1231		if (pmu)1232			return pmu;1233	}1234 1235	/* Fallback to ChipCommon core for older hardware */1236	return cc;1237}1238 1239bool brcmf_chip_iscoreup(struct brcmf_core *pub)1240{1241	struct brcmf_core_priv *core;1242 1243	core = container_of(pub, struct brcmf_core_priv, pub);1244	return core->chip->iscoreup(core);1245}1246 1247void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)1248{1249	struct brcmf_core_priv *core;1250 1251	core = container_of(pub, struct brcmf_core_priv, pub);1252	core->chip->coredisable(core, prereset, reset);1253}1254 1255void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,1256			  u32 postreset)1257{1258	struct brcmf_core_priv *core;1259 1260	core = container_of(pub, struct brcmf_core_priv, pub);1261	core->chip->resetcore(core, prereset, reset, postreset);1262}1263 1264static void1265brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)1266{1267	struct brcmf_core *core;1268	struct brcmf_core_priv *sr;1269 1270	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);1271	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);1272	brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |1273				   D11_BCMA_IOCTL_PHYCLOCKEN,1274			     D11_BCMA_IOCTL_PHYCLOCKEN,1275			     D11_BCMA_IOCTL_PHYCLOCKEN);1276	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);1277	brcmf_chip_resetcore(core, 0, 0, 0);1278 1279	/* disable bank #3 remap for this device */1280	if (chip->pub.chip == BRCM_CC_43430_CHIP_ID ||1281	    chip->pub.chip == CY_CC_43439_CHIP_ID) {1282		sr = container_of(core, struct brcmf_core_priv, pub);1283		brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);1284		brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);1285	}1286}1287 1288static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)1289{1290	struct brcmf_core *core;1291 1292	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);1293	if (!brcmf_chip_iscoreup(core)) {1294		brcmf_err("SOCRAM core is down after reset?\n");1295		return false;1296	}1297 1298	chip->ops->activate(chip->ctx, &chip->pub, 0);1299 1300	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);1301	brcmf_chip_resetcore(core, 0, 0, 0);1302 1303	return true;1304}1305 1306static inline void1307brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)1308{1309	int i;1310	struct brcmf_core *core;1311 1312	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);1313 1314	/* Disable the cores only and let the firmware enable them.1315	 * Releasing reset ourselves breaks BCM4387 in weird ways.1316	 */1317	for (i = 0; (core = brcmf_chip_get_d11core(&chip->pub, i)); i++)1318		brcmf_chip_coredisable(core, D11_BCMA_IOCTL_PHYRESET |1319				       D11_BCMA_IOCTL_PHYCLOCKEN,1320				       D11_BCMA_IOCTL_PHYCLOCKEN);1321}1322 1323static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)1324{1325	struct brcmf_core *core;1326 1327	chip->ops->activate(chip->ctx, &chip->pub, rstvec);1328 1329	/* restore ARM */1330	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);1331	brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);1332 1333	return true;1334}1335 1336static inline void1337brcmf_chip_ca7_set_passive(struct brcmf_chip_priv *chip)1338{1339	struct brcmf_core *core;1340 1341	brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CA7);1342 1343	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);1344	brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |1345				   D11_BCMA_IOCTL_PHYCLOCKEN,1346			     D11_BCMA_IOCTL_PHYCLOCKEN,1347			     D11_BCMA_IOCTL_PHYCLOCKEN);1348}1349 1350static bool brcmf_chip_ca7_set_active(struct brcmf_chip_priv *chip, u32 rstvec)1351{1352	struct brcmf_core *core;1353 1354	chip->ops->activate(chip->ctx, &chip->pub, rstvec);1355 1356	/* restore ARM */1357	core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CA7);1358	brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);1359 1360	return true;1361}1362 1363void brcmf_chip_set_passive(struct brcmf_chip *pub)1364{1365	struct brcmf_chip_priv *chip;1366	struct brcmf_core *arm;1367 1368	brcmf_dbg(TRACE, "Enter\n");1369 1370	chip = container_of(pub, struct brcmf_chip_priv, pub);1371	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);1372	if (arm) {1373		brcmf_chip_cr4_set_passive(chip);1374		return;1375	}1376	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);1377	if (arm) {1378		brcmf_chip_ca7_set_passive(chip);1379		return;1380	}1381	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);1382	if (arm) {1383		brcmf_chip_cm3_set_passive(chip);1384		return;1385	}1386}1387 1388bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)1389{1390	struct brcmf_chip_priv *chip;1391	struct brcmf_core *arm;1392 1393	brcmf_dbg(TRACE, "Enter\n");1394 1395	chip = container_of(pub, struct brcmf_chip_priv, pub);1396	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);1397	if (arm)1398		return brcmf_chip_cr4_set_active(chip, rstvec);1399	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);1400	if (arm)1401		return brcmf_chip_ca7_set_active(chip, rstvec);1402	arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);1403	if (arm)1404		return brcmf_chip_cm3_set_active(chip);1405 1406	return false;1407}1408 1409bool brcmf_chip_sr_capable(struct brcmf_chip *pub)1410{1411	u32 base, addr, reg, pmu_cc3_mask = ~0;1412	struct brcmf_chip_priv *chip;1413	struct brcmf_core *pmu = brcmf_chip_get_pmu(pub);1414 1415	brcmf_dbg(TRACE, "Enter\n");1416 1417	/* old chips with PMU version less than 17 don't support save restore */1418	if (pub->pmurev < 17)1419		return false;1420 1421	base = brcmf_chip_get_chipcommon(pub)->base;1422	chip = container_of(pub, struct brcmf_chip_priv, pub);1423 1424	switch (pub->chip) {1425	case BRCM_CC_4354_CHIP_ID:1426	case BRCM_CC_4356_CHIP_ID:1427	case BRCM_CC_4345_CHIP_ID:1428	case BRCM_CC_43454_CHIP_ID:1429		/* explicitly check SR engine enable bit */1430		pmu_cc3_mask = BIT(2);1431		fallthrough;1432	case BRCM_CC_43241_CHIP_ID:1433	case BRCM_CC_4335_CHIP_ID:1434	case BRCM_CC_4339_CHIP_ID:1435		/* read PMU chipcontrol register 3 */1436		addr = CORE_CC_REG(pmu->base, chipcontrol_addr);1437		chip->ops->write32(chip->ctx, addr, 3);1438		addr = CORE_CC_REG(pmu->base, chipcontrol_data);1439		reg = chip->ops->read32(chip->ctx, addr);1440		return (reg & pmu_cc3_mask) != 0;1441	case BRCM_CC_43430_CHIP_ID:1442	case CY_CC_43439_CHIP_ID:1443		addr = CORE_CC_REG(base, sr_control1);1444		reg = chip->ops->read32(chip->ctx, addr);1445		return reg != 0;1446	case BRCM_CC_4355_CHIP_ID:1447	case CY_CC_4373_CHIP_ID:1448		/* explicitly check SR engine enable bit */1449		addr = CORE_CC_REG(base, sr_control0);1450		reg = chip->ops->read32(chip->ctx, addr);1451		return (reg & CC_SR_CTL0_ENABLE_MASK) != 0;1452	case BRCM_CC_4359_CHIP_ID:1453	case CY_CC_43752_CHIP_ID:1454	case CY_CC_43012_CHIP_ID:1455		addr = CORE_CC_REG(pmu->base, retention_ctl);1456		reg = chip->ops->read32(chip->ctx, addr);1457		return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |1458			       PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;1459	default:1460		addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);1461		reg = chip->ops->read32(chip->ctx, addr);1462		if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)1463			return false;1464 1465		addr = CORE_CC_REG(pmu->base, retention_ctl);1466		reg = chip->ops->read32(chip->ctx, addr);1467		return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |1468			       PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;1469	}1470}1471