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