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