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