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