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        case CY_CC_4373_CHIP_ID:
 694                return 0x160000;
 695        default:
 696                brcmf_err("unknown chip: %s\n", ci->pub.name);
 697                break;
 698        }
 699        return 0;
 700}
 701
 702static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
 703{
 704        struct brcmf_core_priv *mem_core;
 705        struct brcmf_core *mem;
 706
 707        mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
 708        if (mem) {
 709                mem_core = container_of(mem, struct brcmf_core_priv, pub);
 710                ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
 711                ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
 712                if (!ci->pub.rambase) {
 713                        brcmf_err("RAM base not provided with ARM CR4 core\n");
 714                        return -EINVAL;
 715                }
 716        } else {
 717                mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_SYS_MEM);
 718                if (mem) {
 719                        mem_core = container_of(mem, struct brcmf_core_priv,
 720                                                pub);
 721                        ci->pub.ramsize = brcmf_chip_sysmem_ramsize(mem_core);
 722                        ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
 723                        if (!ci->pub.rambase) {
 724                                brcmf_err("RAM base not provided with ARM CA7 core\n");
 725                                return -EINVAL;
 726                        }
 727                } else {
 728                        mem = brcmf_chip_get_core(&ci->pub,
 729                                                  BCMA_CORE_INTERNAL_MEM);
 730                        if (!mem) {
 731                                brcmf_err("No memory cores found\n");
 732                                return -ENOMEM;
 733                        }
 734                        mem_core = container_of(mem, struct brcmf_core_priv,
 735                                                pub);
 736                        brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
 737                                                  &ci->pub.srsize);
 738                }
 739        }
 740        brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
 741                  ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
 742                  ci->pub.srsize, ci->pub.srsize);
 743
 744        if (!ci->pub.ramsize) {
 745                brcmf_err("RAM size is undetermined\n");
 746                return -ENOMEM;
 747        }
 748
 749        if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) {
 750                brcmf_err("RAM size is incorrect\n");
 751                return -ENOMEM;
 752        }
 753
 754        return 0;
 755}
 756
 757static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
 758                                   u8 *type)
 759{
 760        u32 val;
 761
 762        /* read next descriptor */
 763        val = ci->ops->read32(ci->ctx, *eromaddr);
 764        *eromaddr += 4;
 765
 766        if (!type)
 767                return val;
 768
 769        /* determine descriptor type */
 770        *type = (val & DMP_DESC_TYPE_MSK);
 771        if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
 772                *type = DMP_DESC_ADDRESS;
 773
 774        return val;
 775}
 776
 777static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
 778                                      u32 *regbase, u32 *wrapbase)
 779{
 780        u8 desc;
 781        u32 val;
 782        u8 mpnum = 0;
 783        u8 stype, sztype, wraptype;
 784
 785        *regbase = 0;
 786        *wrapbase = 0;
 787
 788        val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
 789        if (desc == DMP_DESC_MASTER_PORT) {
 790                mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
 791                wraptype = DMP_SLAVE_TYPE_MWRAP;
 792        } else if (desc == DMP_DESC_ADDRESS) {
 793                /* revert erom address */
 794                *eromaddr -= 4;
 795                wraptype = DMP_SLAVE_TYPE_SWRAP;
 796        } else {
 797                *eromaddr -= 4;
 798                return -EILSEQ;
 799        }
 800
 801        do {
 802                /* locate address descriptor */
 803                do {
 804                        val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
 805                        /* unexpected table end */
 806                        if (desc == DMP_DESC_EOT) {
 807                                *eromaddr -= 4;
 808                                return -EFAULT;
 809                        }
 810                } while (desc != DMP_DESC_ADDRESS &&
 811                         desc != DMP_DESC_COMPONENT);
 812
 813                /* stop if we crossed current component border */
 814                if (desc == DMP_DESC_COMPONENT) {
 815                        *eromaddr -= 4;
 816                        return 0;
 817                }
 818
 819                /* skip upper 32-bit address descriptor */
 820                if (val & DMP_DESC_ADDRSIZE_GT32)
 821                        brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
 822
 823                sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
 824
 825                /* next size descriptor can be skipped */
 826                if (sztype == DMP_SLAVE_SIZE_DESC) {
 827                        val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
 828                        /* skip upper size descriptor if present */
 829                        if (val & DMP_DESC_ADDRSIZE_GT32)
 830                                brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
 831                }
 832
 833                /* only look for 4K register regions */
 834                if (sztype != DMP_SLAVE_SIZE_4K)
 835                        continue;
 836
 837                stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
 838
 839                /* only regular slave and wrapper */
 840                if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
 841                        *regbase = val & DMP_SLAVE_ADDR_BASE;
 842                if (*wrapbase == 0 && stype == wraptype)
 843                        *wrapbase = val & DMP_SLAVE_ADDR_BASE;
 844        } while (*regbase == 0 || *wrapbase == 0);
 845
 846        return 0;
 847}
 848
 849static
 850int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
 851{
 852        struct brcmf_core *core;
 853        u32 eromaddr;
 854        u8 desc_type = 0;
 855        u32 val;
 856        u16 id;
 857        u8 nmp, nsp, nmw, nsw, rev;
 858        u32 base, wrap;
 859        int err;
 860
 861        eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
 862
 863        while (desc_type != DMP_DESC_EOT) {
 864                val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
 865                if (!(val & DMP_DESC_VALID))
 866                        continue;
 867
 868                if (desc_type == DMP_DESC_EMPTY)
 869                        continue;
 870
 871                /* need a component descriptor */
 872                if (desc_type != DMP_DESC_COMPONENT)
 873                        continue;
 874
 875                id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
 876
 877                /* next descriptor must be component as well */
 878                val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
 879                if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
 880                        return -EFAULT;
 881
 882                /* only look at cores with master port(s) */
 883                nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
 884                nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
 885                nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
 886                nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
 887                rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
 888
 889                /* need core with ports */
 890                if (nmw + nsw == 0 &&
 891                    id != BCMA_CORE_PMU)
 892                        continue;
 893
 894                /* try to obtain register address info */
 895                err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
 896                if (err)
 897                        continue;
 898
 899                /* finally a core to be added */
 900                core = brcmf_chip_add_core(ci, id, base, wrap);
 901                if (IS_ERR(core))
 902                        return PTR_ERR(core);
 903
 904                core->rev = rev;
 905        }
 906
 907        return 0;
 908}
 909
 910static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
 911{
 912        struct brcmf_core *core;
 913        u32 regdata;
 914        u32 socitype;
 915        int ret;
 916
 917        /* Get CC core rev
 918         * Chipid is assume to be at offset 0 from SI_ENUM_BASE
 919         * For different chiptypes or old sdio hosts w/o chipcommon,
 920         * other ways of recognition should be added here.
 921         */
 922        regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
 923        ci->pub.chip = regdata & CID_ID_MASK;
 924        ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
 925        socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 926
 927        brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name));
 928        brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n",
 929                  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name,
 930                  ci->pub.chiprev);
 931
 932        if (socitype == SOCI_SB) {
 933                if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
 934                        brcmf_err("SB chip is not supported\n");
 935                        return -ENODEV;
 936                }
 937                ci->iscoreup = brcmf_chip_sb_iscoreup;
 938                ci->coredisable = brcmf_chip_sb_coredisable;
 939                ci->resetcore = brcmf_chip_sb_resetcore;
 940
 941                core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
 942                                           SI_ENUM_BASE, 0);
 943                brcmf_chip_sb_corerev(ci, core);
 944                core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
 945                                           BCM4329_CORE_BUS_BASE, 0);
 946                brcmf_chip_sb_corerev(ci, core);
 947                core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
 948                                           BCM4329_CORE_SOCRAM_BASE, 0);
 949                brcmf_chip_sb_corerev(ci, core);
 950                core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
 951                                           BCM4329_CORE_ARM_BASE, 0);
 952                brcmf_chip_sb_corerev(ci, core);
 953
 954                core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
 955                brcmf_chip_sb_corerev(ci, core);
 956        } else if (socitype == SOCI_AI) {
 957                ci->iscoreup = brcmf_chip_ai_iscoreup;
 958                ci->coredisable = brcmf_chip_ai_coredisable;
 959                ci->resetcore = brcmf_chip_ai_resetcore;
 960
 961                brcmf_chip_dmp_erom_scan(ci);
 962        } else {
 963                brcmf_err("chip backplane type %u is not supported\n",
 964                          socitype);
 965                return -ENODEV;
 966        }
 967
 968        ret = brcmf_chip_cores_check(ci);
 969        if (ret)
 970                return ret;
 971
 972        /* assure chip is passive for core access */
 973        brcmf_chip_set_passive(&ci->pub);
 974
 975        /* Call bus specific reset function now. Cores have been determined
 976         * but further access may require a chip specific reset at this point.
 977         */
 978        if (ci->ops->reset) {
 979                ci->ops->reset(ci->ctx, &ci->pub);
 980                brcmf_chip_set_passive(&ci->pub);
 981        }
 982
 983        return brcmf_chip_get_raminfo(ci);
 984}
 985
 986static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
 987{
 988        struct brcmf_core *core;
 989        struct brcmf_core_priv *cpu;
 990        u32 val;
 991
 992
 993        core = brcmf_chip_get_core(&chip->pub, id);
 994        if (!core)
 995                return;
 996
 997        switch (id) {
 998        case BCMA_CORE_ARM_CM3:
 999                brcmf_chip_coredisable(core, 0, 0);
1000                break;
1001        case BCMA_CORE_ARM_CR4:
1002        case BCMA_CORE_ARM_CA7:
1003                cpu = container_of(core, struct brcmf_core_priv, pub);
1004
1005                /* clear all IOCTL bits except HALT bit */
1006                val = chip->ops->read32(chip->ctx, cpu->wrapbase + BCMA_IOCTL);
1007                val &= ARMCR4_BCMA_IOCTL_CPUHALT;
1008                brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
1009                                     ARMCR4_BCMA_IOCTL_CPUHALT);
1010                break;
1011        default:
1012                brcmf_err("unknown id: %u\n", id);
1013                break;
1014        }
1015}
1016
1017static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
1018{
1019        struct brcmf_chip *pub;
1020        struct brcmf_core_priv *cc;
1021        struct brcmf_core *pmu;
1022        u32 base;
1023        u32 val;
1024        int ret = 0;
1025
1026        pub = &chip->pub;
1027        cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
1028        base = cc->pub.base;
1029
1030        /* get chipcommon capabilites */
1031        pub->cc_caps = chip->ops->read32(chip->ctx,
1032                                         CORE_CC_REG(base, capabilities));
1033        pub->cc_caps_ext = chip->ops->read32(chip->ctx,
1034                                             CORE_CC_REG(base,
1035                                                         capabilities_ext));
1036
1037        /* get pmu caps & rev */
1038        pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */
1039        if (pub->cc_caps & CC_CAP_PMU) {
1040                val = chip->ops->read32(chip->ctx,
1041                                        CORE_CC_REG(pmu->base, pmucapabilities));
1042                pub->pmurev = val & PCAP_REV_MASK;
1043                pub->pmucaps = val;
1044        }
1045
1046        brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
1047                  cc->pub.rev, pub->pmurev, pub->pmucaps);
1048
1049        /* execute bus core specific setup */
1050        if (chip->ops->setup)
1051                ret = chip->ops->setup(chip->ctx, pub);
1052
1053        return ret;
1054}
1055
1056struct brcmf_chip *brcmf_chip_attach(void *ctx,
1057                                     const struct brcmf_buscore_ops *ops)
1058{
1059        struct brcmf_chip_priv *chip;
1060        int err = 0;
1061
1062        if (WARN_ON(!ops->read32))
1063                err = -EINVAL;
1064        if (WARN_ON(!ops->write32))
1065                err = -EINVAL;
1066        if (WARN_ON(!ops->prepare))
1067                err = -EINVAL;
1068        if (WARN_ON(!ops->activate))
1069                err = -EINVAL;
1070        if (err < 0)
1071                return ERR_PTR(-EINVAL);
1072
1073        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1074        if (!chip)
1075                return ERR_PTR(-ENOMEM);
1076
1077        INIT_LIST_HEAD(&chip->cores);
1078        chip->num_cores = 0;
1079        chip->ops = ops;
1080        chip->ctx = ctx;
1081
1082        err = ops->prepare(ctx);
1083        if (err < 0)
1084                goto fail;
1085
1086        err = brcmf_chip_recognition(chip);
1087        if (err < 0)
1088                goto fail;
1089
1090        err = brcmf_chip_setup(chip);
1091        if (err < 0)
1092                goto fail;
1093
1094        return &chip->pub;
1095
1096fail:
1097        brcmf_chip_detach(&chip->pub);
1098        return ERR_PTR(err);
1099}
1100
1101void brcmf_chip_detach(struct brcmf_chip *pub)
1102{
1103        struct brcmf_chip_priv *chip;
1104        struct brcmf_core_priv *core;
1105        struct brcmf_core_priv *tmp;
1106
1107        chip = container_of(pub, struct brcmf_chip_priv, pub);
1108        list_for_each_entry_safe(core, tmp, &chip->cores, list) {
1109                list_del(&core->list);
1110                kfree(core);
1111        }
1112        kfree(chip);
1113}
1114
1115struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
1116{
1117        struct brcmf_chip_priv *chip;
1118        struct brcmf_core_priv *core;
1119
1120        chip = container_of(pub, struct brcmf_chip_priv, pub);
1121        list_for_each_entry(core, &chip->cores, list)
1122                if (core->pub.id == coreid)
1123                        return &core->pub;
1124
1125        return NULL;
1126}
1127
1128struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
1129{
1130        struct brcmf_chip_priv *chip;
1131        struct brcmf_core_priv *cc;
1132
1133        chip = container_of(pub, struct brcmf_chip_priv, pub);
1134        cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
1135        if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
1136                return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
1137        return &cc->pub;
1138}
1139
1140struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub)
1141{
1142        struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub);
1143        struct brcmf_core *pmu;
1144
1145        /* See if there is separated PMU core available */
1146        if (cc->rev >= 35 &&
1147            pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {
1148                pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU);
1149                if (pmu)
1150                        return pmu;
1151        }
1152
1153        /* Fallback to ChipCommon core for older hardware */
1154        return cc;
1155}
1156
1157bool brcmf_chip_iscoreup(struct brcmf_core *pub)
1158{
1159        struct brcmf_core_priv *core;
1160
1161        core = container_of(pub, struct brcmf_core_priv, pub);
1162        return core->chip->iscoreup(core);
1163}
1164
1165void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
1166{
1167        struct brcmf_core_priv *core;
1168
1169        core = container_of(pub, struct brcmf_core_priv, pub);
1170        core->chip->coredisable(core, prereset, reset);
1171}
1172
1173void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
1174                          u32 postreset)
1175{
1176        struct brcmf_core_priv *core;
1177
1178        core = container_of(pub, struct brcmf_core_priv, pub);
1179        core->chip->resetcore(core, prereset, reset, postreset);
1180}
1181
1182static void
1183brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
1184{
1185        struct brcmf_core *core;
1186        struct brcmf_core_priv *sr;
1187
1188        brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
1189        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1190        brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1191                                   D11_BCMA_IOCTL_PHYCLOCKEN,
1192                             D11_BCMA_IOCTL_PHYCLOCKEN,
1193                             D11_BCMA_IOCTL_PHYCLOCKEN);
1194        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
1195        brcmf_chip_resetcore(core, 0, 0, 0);
1196
1197        /* disable bank #3 remap for this device */
1198        if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
1199                sr = container_of(core, struct brcmf_core_priv, pub);
1200                brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
1201                brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
1202        }
1203}
1204
1205static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
1206{
1207        struct brcmf_core *core;
1208
1209        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
1210        if (!brcmf_chip_iscoreup(core)) {
1211                brcmf_err("SOCRAM core is down after reset?\n");
1212                return false;
1213        }
1214
1215        chip->ops->activate(chip->ctx, &chip->pub, 0);
1216
1217        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
1218        brcmf_chip_resetcore(core, 0, 0, 0);
1219
1220        return true;
1221}
1222
1223static inline void
1224brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)
1225{
1226        struct brcmf_core *core;
1227
1228        brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
1229
1230        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1231        brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1232                                   D11_BCMA_IOCTL_PHYCLOCKEN,
1233                             D11_BCMA_IOCTL_PHYCLOCKEN,
1234                             D11_BCMA_IOCTL_PHYCLOCKEN);
1235}
1236
1237static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
1238{
1239        struct brcmf_core *core;
1240
1241        chip->ops->activate(chip->ctx, &chip->pub, rstvec);
1242
1243        /* restore ARM */
1244        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
1245        brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
1246
1247        return true;
1248}
1249
1250static inline void
1251brcmf_chip_ca7_set_passive(struct brcmf_chip_priv *chip)
1252{
1253        struct brcmf_core *core;
1254
1255        brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CA7);
1256
1257        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1258        brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1259                                   D11_BCMA_IOCTL_PHYCLOCKEN,
1260                             D11_BCMA_IOCTL_PHYCLOCKEN,
1261                             D11_BCMA_IOCTL_PHYCLOCKEN);
1262}
1263
1264static bool brcmf_chip_ca7_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
1265{
1266        struct brcmf_core *core;
1267
1268        chip->ops->activate(chip->ctx, &chip->pub, rstvec);
1269
1270        /* restore ARM */
1271        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CA7);
1272        brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
1273
1274        return true;
1275}
1276
1277void brcmf_chip_set_passive(struct brcmf_chip *pub)
1278{
1279        struct brcmf_chip_priv *chip;
1280        struct brcmf_core *arm;
1281
1282        brcmf_dbg(TRACE, "Enter\n");
1283
1284        chip = container_of(pub, struct brcmf_chip_priv, pub);
1285        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
1286        if (arm) {
1287                brcmf_chip_cr4_set_passive(chip);
1288                return;
1289        }
1290        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);
1291        if (arm) {
1292                brcmf_chip_ca7_set_passive(chip);
1293                return;
1294        }
1295        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);
1296        if (arm) {
1297                brcmf_chip_cm3_set_passive(chip);
1298                return;
1299        }
1300}
1301
1302bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
1303{
1304        struct brcmf_chip_priv *chip;
1305        struct brcmf_core *arm;
1306
1307        brcmf_dbg(TRACE, "Enter\n");
1308
1309        chip = container_of(pub, struct brcmf_chip_priv, pub);
1310        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
1311        if (arm)
1312                return brcmf_chip_cr4_set_active(chip, rstvec);
1313        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);
1314        if (arm)
1315                return brcmf_chip_ca7_set_active(chip, rstvec);
1316        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);
1317        if (arm)
1318                return brcmf_chip_cm3_set_active(chip);
1319
1320        return false;
1321}
1322
1323bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
1324{
1325        u32 base, addr, reg, pmu_cc3_mask = ~0;
1326        struct brcmf_chip_priv *chip;
1327        struct brcmf_core *pmu = brcmf_chip_get_pmu(pub);
1328
1329        brcmf_dbg(TRACE, "Enter\n");
1330
1331        /* old chips with PMU version less than 17 don't support save restore */
1332        if (pub->pmurev < 17)
1333                return false;
1334
1335        base = brcmf_chip_get_chipcommon(pub)->base;
1336        chip = container_of(pub, struct brcmf_chip_priv, pub);
1337
1338        switch (pub->chip) {
1339        case BRCM_CC_4354_CHIP_ID:
1340        case BRCM_CC_4356_CHIP_ID:
1341                /* explicitly check SR engine enable bit */
1342                pmu_cc3_mask = BIT(2);
1343                /* fall-through */
1344        case BRCM_CC_43241_CHIP_ID:
1345        case BRCM_CC_4335_CHIP_ID:
1346        case BRCM_CC_4339_CHIP_ID:
1347                /* read PMU chipcontrol register 3 */
1348                addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
1349                chip->ops->write32(chip->ctx, addr, 3);
1350                addr = CORE_CC_REG(pmu->base, chipcontrol_data);
1351                reg = chip->ops->read32(chip->ctx, addr);
1352                return (reg & pmu_cc3_mask) != 0;
1353        case BRCM_CC_43430_CHIP_ID:
1354                addr = CORE_CC_REG(base, sr_control1);
1355                reg = chip->ops->read32(chip->ctx, addr);
1356                return reg != 0;
1357        default:
1358                addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
1359                reg = chip->ops->read32(chip->ctx, addr);
1360                if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
1361                        return false;
1362
1363                addr = CORE_CC_REG(pmu->base, retention_ctl);
1364                reg = chip->ops->read32(chip->ctx, addr);
1365                return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
1366                               PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
1367        }
1368}
1369