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
 467char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len)
 468{
 469        const char *fmt;
 470
 471        fmt = ((id > 0xa000) || (id < 0x4000)) ? "BCM%d/%u" : "BCM%x/%u";
 472        snprintf(buf, len, fmt, id, rev);
 473        return buf;
 474}
 475
 476static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
 477                                              u16 coreid, u32 base,
 478                                              u32 wrapbase)
 479{
 480        struct brcmf_core_priv *core;
 481
 482        core = kzalloc(sizeof(*core), GFP_KERNEL);
 483        if (!core)
 484                return ERR_PTR(-ENOMEM);
 485
 486        core->pub.id = coreid;
 487        core->pub.base = base;
 488        core->chip = ci;
 489        core->wrapbase = wrapbase;
 490
 491        list_add_tail(&core->list, &ci->cores);
 492        return &core->pub;
 493}
 494
 495/* safety check for chipinfo */
 496static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
 497{
 498        struct brcmf_core_priv *core;
 499        bool need_socram = false;
 500        bool has_socram = false;
 501        bool cpu_found = false;
 502        int idx = 1;
 503
 504        list_for_each_entry(core, &ci->cores, list) {
 505                brcmf_dbg(INFO, " [%-2d] core 0x%x:%-2d base 0x%08x wrap 0x%08x\n",
 506                          idx++, core->pub.id, core->pub.rev, core->pub.base,
 507                          core->wrapbase);
 508
 509                switch (core->pub.id) {
 510                case BCMA_CORE_ARM_CM3:
 511                        cpu_found = true;
 512                        need_socram = true;
 513                        break;
 514                case BCMA_CORE_INTERNAL_MEM:
 515                        has_socram = true;
 516                        break;
 517                case BCMA_CORE_ARM_CR4:
 518                        cpu_found = true;
 519                        break;
 520                case BCMA_CORE_ARM_CA7:
 521                        cpu_found = true;
 522                        break;
 523                default:
 524                        break;
 525                }
 526        }
 527
 528        if (!cpu_found) {
 529                brcmf_err("CPU core not detected\n");
 530                return -ENXIO;
 531        }
 532        /* check RAM core presence for ARM CM3 core */
 533        if (need_socram && !has_socram) {
 534                brcmf_err("RAM core not provided with ARM CM3 core\n");
 535                return -ENODEV;
 536        }
 537        return 0;
 538}
 539
 540static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg)
 541{
 542        return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg);
 543}
 544
 545static void brcmf_chip_core_write32(struct brcmf_core_priv *core,
 546                                    u16 reg, u32 val)
 547{
 548        core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val);
 549}
 550
 551static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx,
 552                                       u32 *banksize)
 553{
 554        u32 bankinfo;
 555        u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
 556
 557        bankidx |= idx;
 558        brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx);
 559        bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo));
 560        *banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1;
 561        *banksize *= SOCRAM_BANKINFO_SZBASE;
 562        return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK);
 563}
 564
 565static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
 566                                      u32 *srsize)
 567{
 568        u32 coreinfo;
 569        uint nb, banksize, lss;
 570        bool retent;
 571        int i;
 572
 573        *ramsize = 0;
 574        *srsize = 0;
 575
 576        if (WARN_ON(sr->pub.rev < 4))
 577                return;
 578
 579        if (!brcmf_chip_iscoreup(&sr->pub))
 580                brcmf_chip_resetcore(&sr->pub, 0, 0, 0);
 581
 582        /* Get info for determining size */
 583        coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo));
 584        nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
 585
 586        if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) {
 587                banksize = (coreinfo & SRCI_SRBSZ_MASK);
 588                lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
 589                if (lss != 0)
 590                        nb--;
 591                *ramsize = nb * (1 << (banksize + SR_BSZ_BASE));
 592                if (lss != 0)
 593                        *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
 594        } else {
 595                nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
 596                for (i = 0; i < nb; i++) {
 597                        retent = brcmf_chip_socram_banksize(sr, i, &banksize);
 598                        *ramsize += banksize;
 599                        if (retent)
 600                                *srsize += banksize;
 601                }
 602        }
 603
 604        /* hardcoded save&restore memory sizes */
 605        switch (sr->chip->pub.chip) {
 606        case BRCM_CC_4334_CHIP_ID:
 607                if (sr->chip->pub.chiprev < 2)
 608                        *srsize = (32 * 1024);
 609                break;
 610        case BRCM_CC_43430_CHIP_ID:
 611                /* assume sr for now as we can not check
 612                 * firmware sr capability at this point.
 613                 */
 614                *srsize = (64 * 1024);
 615                break;
 616        default:
 617                break;
 618        }
 619}
 620
 621/** Return the SYS MEM size */
 622static u32 brcmf_chip_sysmem_ramsize(struct brcmf_core_priv *sysmem)
 623{
 624        u32 memsize = 0;
 625        u32 coreinfo;
 626        u32 idx;
 627        u32 nb;
 628        u32 banksize;
 629
 630        if (!brcmf_chip_iscoreup(&sysmem->pub))
 631                brcmf_chip_resetcore(&sysmem->pub, 0, 0, 0);
 632
 633        coreinfo = brcmf_chip_core_read32(sysmem, SYSMEMREGOFFS(coreinfo));
 634        nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
 635
 636        for (idx = 0; idx < nb; idx++) {
 637                brcmf_chip_socram_banksize(sysmem, idx, &banksize);
 638                memsize += banksize;
 639        }
 640
 641        return memsize;
 642}
 643
 644/** Return the TCM-RAM size of the ARMCR4 core. */
 645static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
 646{
 647        u32 corecap;
 648        u32 memsize = 0;
 649        u32 nab;
 650        u32 nbb;
 651        u32 totb;
 652        u32 bxinfo;
 653        u32 idx;
 654
 655        corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP);
 656
 657        nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
 658        nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
 659        totb = nab + nbb;
 660
 661        for (idx = 0; idx < totb; idx++) {
 662                brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx);
 663                bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO);
 664                memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
 665        }
 666
 667        return memsize;
 668}
 669
 670static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
 671{
 672        switch (ci->pub.chip) {
 673        case BRCM_CC_4345_CHIP_ID:
 674                return 0x198000;
 675        case BRCM_CC_4335_CHIP_ID:
 676        case BRCM_CC_4339_CHIP_ID:
 677        case BRCM_CC_4350_CHIP_ID:
 678        case BRCM_CC_4354_CHIP_ID:
 679        case BRCM_CC_4356_CHIP_ID:
 680        case BRCM_CC_43567_CHIP_ID:
 681        case BRCM_CC_43569_CHIP_ID:
 682        case BRCM_CC_43570_CHIP_ID:
 683        case BRCM_CC_4358_CHIP_ID:
 684        case BRCM_CC_4359_CHIP_ID:
 685        case BRCM_CC_43602_CHIP_ID:
 686        case BRCM_CC_4371_CHIP_ID:
 687                return 0x180000;
 688        case BRCM_CC_43465_CHIP_ID:
 689        case BRCM_CC_43525_CHIP_ID:
 690        case BRCM_CC_4365_CHIP_ID:
 691        case BRCM_CC_4366_CHIP_ID:
 692        case BRCM_CC_43664_CHIP_ID:
 693                return 0x200000;
 694        case CY_CC_4373_CHIP_ID:
 695                return 0x160000;
 696        default:
 697                brcmf_err("unknown chip: %s\n", ci->pub.name);
 698                break;
 699        }
 700        return 0;
 701}
 702
 703static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
 704{
 705        struct brcmf_core_priv *mem_core;
 706        struct brcmf_core *mem;
 707
 708        mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
 709        if (mem) {
 710                mem_core = container_of(mem, struct brcmf_core_priv, pub);
 711                ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
 712                ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
 713                if (!ci->pub.rambase) {
 714                        brcmf_err("RAM base not provided with ARM CR4 core\n");
 715                        return -EINVAL;
 716                }
 717        } else {
 718                mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_SYS_MEM);
 719                if (mem) {
 720                        mem_core = container_of(mem, struct brcmf_core_priv,
 721                                                pub);
 722                        ci->pub.ramsize = brcmf_chip_sysmem_ramsize(mem_core);
 723                        ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
 724                        if (!ci->pub.rambase) {
 725                                brcmf_err("RAM base not provided with ARM CA7 core\n");
 726                                return -EINVAL;
 727                        }
 728                } else {
 729                        mem = brcmf_chip_get_core(&ci->pub,
 730                                                  BCMA_CORE_INTERNAL_MEM);
 731                        if (!mem) {
 732                                brcmf_err("No memory cores found\n");
 733                                return -ENOMEM;
 734                        }
 735                        mem_core = container_of(mem, struct brcmf_core_priv,
 736                                                pub);
 737                        brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
 738                                                  &ci->pub.srsize);
 739                }
 740        }
 741        brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
 742                  ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
 743                  ci->pub.srsize, ci->pub.srsize);
 744
 745        if (!ci->pub.ramsize) {
 746                brcmf_err("RAM size is undetermined\n");
 747                return -ENOMEM;
 748        }
 749
 750        if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) {
 751                brcmf_err("RAM size is incorrect\n");
 752                return -ENOMEM;
 753        }
 754
 755        return 0;
 756}
 757
 758static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
 759                                   u8 *type)
 760{
 761        u32 val;
 762
 763        /* read next descriptor */
 764        val = ci->ops->read32(ci->ctx, *eromaddr);
 765        *eromaddr += 4;
 766
 767        if (!type)
 768                return val;
 769
 770        /* determine descriptor type */
 771        *type = (val & DMP_DESC_TYPE_MSK);
 772        if ((*type & ~DMP_DESC_ADDRSIZE_GT32) == DMP_DESC_ADDRESS)
 773                *type = DMP_DESC_ADDRESS;
 774
 775        return val;
 776}
 777
 778static int brcmf_chip_dmp_get_regaddr(struct brcmf_chip_priv *ci, u32 *eromaddr,
 779                                      u32 *regbase, u32 *wrapbase)
 780{
 781        u8 desc;
 782        u32 val;
 783        u8 mpnum = 0;
 784        u8 stype, sztype, wraptype;
 785
 786        *regbase = 0;
 787        *wrapbase = 0;
 788
 789        val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
 790        if (desc == DMP_DESC_MASTER_PORT) {
 791                mpnum = (val & DMP_MASTER_PORT_NUM) >> DMP_MASTER_PORT_NUM_S;
 792                wraptype = DMP_SLAVE_TYPE_MWRAP;
 793        } else if (desc == DMP_DESC_ADDRESS) {
 794                /* revert erom address */
 795                *eromaddr -= 4;
 796                wraptype = DMP_SLAVE_TYPE_SWRAP;
 797        } else {
 798                *eromaddr -= 4;
 799                return -EILSEQ;
 800        }
 801
 802        do {
 803                /* locate address descriptor */
 804                do {
 805                        val = brcmf_chip_dmp_get_desc(ci, eromaddr, &desc);
 806                        /* unexpected table end */
 807                        if (desc == DMP_DESC_EOT) {
 808                                *eromaddr -= 4;
 809                                return -EFAULT;
 810                        }
 811                } while (desc != DMP_DESC_ADDRESS &&
 812                         desc != DMP_DESC_COMPONENT);
 813
 814                /* stop if we crossed current component border */
 815                if (desc == DMP_DESC_COMPONENT) {
 816                        *eromaddr -= 4;
 817                        return 0;
 818                }
 819
 820                /* skip upper 32-bit address descriptor */
 821                if (val & DMP_DESC_ADDRSIZE_GT32)
 822                        brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
 823
 824                sztype = (val & DMP_SLAVE_SIZE_TYPE) >> DMP_SLAVE_SIZE_TYPE_S;
 825
 826                /* next size descriptor can be skipped */
 827                if (sztype == DMP_SLAVE_SIZE_DESC) {
 828                        val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
 829                        /* skip upper size descriptor if present */
 830                        if (val & DMP_DESC_ADDRSIZE_GT32)
 831                                brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
 832                }
 833
 834                /* only look for 4K register regions */
 835                if (sztype != DMP_SLAVE_SIZE_4K)
 836                        continue;
 837
 838                stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
 839
 840                /* only regular slave and wrapper */
 841                if (*regbase == 0 && stype == DMP_SLAVE_TYPE_SLAVE)
 842                        *regbase = val & DMP_SLAVE_ADDR_BASE;
 843                if (*wrapbase == 0 && stype == wraptype)
 844                        *wrapbase = val & DMP_SLAVE_ADDR_BASE;
 845        } while (*regbase == 0 || *wrapbase == 0);
 846
 847        return 0;
 848}
 849
 850static
 851int brcmf_chip_dmp_erom_scan(struct brcmf_chip_priv *ci)
 852{
 853        struct brcmf_core *core;
 854        u32 eromaddr;
 855        u8 desc_type = 0;
 856        u32 val;
 857        u16 id;
 858        u8 nmp, nsp, nmw, nsw, rev;
 859        u32 base, wrap;
 860        int err;
 861
 862        eromaddr = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, eromptr));
 863
 864        while (desc_type != DMP_DESC_EOT) {
 865                val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
 866                if (!(val & DMP_DESC_VALID))
 867                        continue;
 868
 869                if (desc_type == DMP_DESC_EMPTY)
 870                        continue;
 871
 872                /* need a component descriptor */
 873                if (desc_type != DMP_DESC_COMPONENT)
 874                        continue;
 875
 876                id = (val & DMP_COMP_PARTNUM) >> DMP_COMP_PARTNUM_S;
 877
 878                /* next descriptor must be component as well */
 879                val = brcmf_chip_dmp_get_desc(ci, &eromaddr, &desc_type);
 880                if (WARN_ON((val & DMP_DESC_TYPE_MSK) != DMP_DESC_COMPONENT))
 881                        return -EFAULT;
 882
 883                /* only look at cores with master port(s) */
 884                nmp = (val & DMP_COMP_NUM_MPORT) >> DMP_COMP_NUM_MPORT_S;
 885                nsp = (val & DMP_COMP_NUM_SPORT) >> DMP_COMP_NUM_SPORT_S;
 886                nmw = (val & DMP_COMP_NUM_MWRAP) >> DMP_COMP_NUM_MWRAP_S;
 887                nsw = (val & DMP_COMP_NUM_SWRAP) >> DMP_COMP_NUM_SWRAP_S;
 888                rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S;
 889
 890                /* need core with ports */
 891                if (nmw + nsw == 0 &&
 892                    id != BCMA_CORE_PMU)
 893                        continue;
 894
 895                /* try to obtain register address info */
 896                err = brcmf_chip_dmp_get_regaddr(ci, &eromaddr, &base, &wrap);
 897                if (err)
 898                        continue;
 899
 900                /* finally a core to be added */
 901                core = brcmf_chip_add_core(ci, id, base, wrap);
 902                if (IS_ERR(core))
 903                        return PTR_ERR(core);
 904
 905                core->rev = rev;
 906        }
 907
 908        return 0;
 909}
 910
 911static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
 912{
 913        struct brcmf_core *core;
 914        u32 regdata;
 915        u32 socitype;
 916        int ret;
 917
 918        /* Get CC core rev
 919         * Chipid is assume to be at offset 0 from SI_ENUM_BASE
 920         * For different chiptypes or old sdio hosts w/o chipcommon,
 921         * other ways of recognition should be added here.
 922         */
 923        regdata = ci->ops->read32(ci->ctx, CORE_CC_REG(SI_ENUM_BASE, chipid));
 924        ci->pub.chip = regdata & CID_ID_MASK;
 925        ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
 926        socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
 927
 928        brcmf_chip_name(ci->pub.chip, ci->pub.chiprev,
 929                        ci->pub.name, sizeof(ci->pub.name));
 930        brcmf_dbg(INFO, "found %s chip: %s\n",
 931                  socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name);
 932
 933        if (socitype == SOCI_SB) {
 934                if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
 935                        brcmf_err("SB chip is not supported\n");
 936                        return -ENODEV;
 937                }
 938                ci->iscoreup = brcmf_chip_sb_iscoreup;
 939                ci->coredisable = brcmf_chip_sb_coredisable;
 940                ci->resetcore = brcmf_chip_sb_resetcore;
 941
 942                core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
 943                                           SI_ENUM_BASE, 0);
 944                brcmf_chip_sb_corerev(ci, core);
 945                core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
 946                                           BCM4329_CORE_BUS_BASE, 0);
 947                brcmf_chip_sb_corerev(ci, core);
 948                core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
 949                                           BCM4329_CORE_SOCRAM_BASE, 0);
 950                brcmf_chip_sb_corerev(ci, core);
 951                core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
 952                                           BCM4329_CORE_ARM_BASE, 0);
 953                brcmf_chip_sb_corerev(ci, core);
 954
 955                core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
 956                brcmf_chip_sb_corerev(ci, core);
 957        } else if (socitype == SOCI_AI) {
 958                ci->iscoreup = brcmf_chip_ai_iscoreup;
 959                ci->coredisable = brcmf_chip_ai_coredisable;
 960                ci->resetcore = brcmf_chip_ai_resetcore;
 961
 962                brcmf_chip_dmp_erom_scan(ci);
 963        } else {
 964                brcmf_err("chip backplane type %u is not supported\n",
 965                          socitype);
 966                return -ENODEV;
 967        }
 968
 969        ret = brcmf_chip_cores_check(ci);
 970        if (ret)
 971                return ret;
 972
 973        /* assure chip is passive for core access */
 974        brcmf_chip_set_passive(&ci->pub);
 975
 976        /* Call bus specific reset function now. Cores have been determined
 977         * but further access may require a chip specific reset at this point.
 978         */
 979        if (ci->ops->reset) {
 980                ci->ops->reset(ci->ctx, &ci->pub);
 981                brcmf_chip_set_passive(&ci->pub);
 982        }
 983
 984        return brcmf_chip_get_raminfo(ci);
 985}
 986
 987static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
 988{
 989        struct brcmf_core *core;
 990        struct brcmf_core_priv *cpu;
 991        u32 val;
 992
 993
 994        core = brcmf_chip_get_core(&chip->pub, id);
 995        if (!core)
 996                return;
 997
 998        switch (id) {
 999        case BCMA_CORE_ARM_CM3:
1000                brcmf_chip_coredisable(core, 0, 0);
1001                break;
1002        case BCMA_CORE_ARM_CR4:
1003        case BCMA_CORE_ARM_CA7:
1004                cpu = container_of(core, struct brcmf_core_priv, pub);
1005
1006                /* clear all IOCTL bits except HALT bit */
1007                val = chip->ops->read32(chip->ctx, cpu->wrapbase + BCMA_IOCTL);
1008                val &= ARMCR4_BCMA_IOCTL_CPUHALT;
1009                brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
1010                                     ARMCR4_BCMA_IOCTL_CPUHALT);
1011                break;
1012        default:
1013                brcmf_err("unknown id: %u\n", id);
1014                break;
1015        }
1016}
1017
1018static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
1019{
1020        struct brcmf_chip *pub;
1021        struct brcmf_core_priv *cc;
1022        struct brcmf_core *pmu;
1023        u32 base;
1024        u32 val;
1025        int ret = 0;
1026
1027        pub = &chip->pub;
1028        cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
1029        base = cc->pub.base;
1030
1031        /* get chipcommon capabilites */
1032        pub->cc_caps = chip->ops->read32(chip->ctx,
1033                                         CORE_CC_REG(base, capabilities));
1034        pub->cc_caps_ext = chip->ops->read32(chip->ctx,
1035                                             CORE_CC_REG(base,
1036                                                         capabilities_ext));
1037
1038        /* get pmu caps & rev */
1039        pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */
1040        if (pub->cc_caps & CC_CAP_PMU) {
1041                val = chip->ops->read32(chip->ctx,
1042                                        CORE_CC_REG(pmu->base, pmucapabilities));
1043                pub->pmurev = val & PCAP_REV_MASK;
1044                pub->pmucaps = val;
1045        }
1046
1047        brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, pmucaps=0x%x\n",
1048                  cc->pub.rev, pub->pmurev, pub->pmucaps);
1049
1050        /* execute bus core specific setup */
1051        if (chip->ops->setup)
1052                ret = chip->ops->setup(chip->ctx, pub);
1053
1054        return ret;
1055}
1056
1057struct brcmf_chip *brcmf_chip_attach(void *ctx,
1058                                     const struct brcmf_buscore_ops *ops)
1059{
1060        struct brcmf_chip_priv *chip;
1061        int err = 0;
1062
1063        if (WARN_ON(!ops->read32))
1064                err = -EINVAL;
1065        if (WARN_ON(!ops->write32))
1066                err = -EINVAL;
1067        if (WARN_ON(!ops->prepare))
1068                err = -EINVAL;
1069        if (WARN_ON(!ops->activate))
1070                err = -EINVAL;
1071        if (err < 0)
1072                return ERR_PTR(-EINVAL);
1073
1074        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1075        if (!chip)
1076                return ERR_PTR(-ENOMEM);
1077
1078        INIT_LIST_HEAD(&chip->cores);
1079        chip->num_cores = 0;
1080        chip->ops = ops;
1081        chip->ctx = ctx;
1082
1083        err = ops->prepare(ctx);
1084        if (err < 0)
1085                goto fail;
1086
1087        err = brcmf_chip_recognition(chip);
1088        if (err < 0)
1089                goto fail;
1090
1091        err = brcmf_chip_setup(chip);
1092        if (err < 0)
1093                goto fail;
1094
1095        return &chip->pub;
1096
1097fail:
1098        brcmf_chip_detach(&chip->pub);
1099        return ERR_PTR(err);
1100}
1101
1102void brcmf_chip_detach(struct brcmf_chip *pub)
1103{
1104        struct brcmf_chip_priv *chip;
1105        struct brcmf_core_priv *core;
1106        struct brcmf_core_priv *tmp;
1107
1108        chip = container_of(pub, struct brcmf_chip_priv, pub);
1109        list_for_each_entry_safe(core, tmp, &chip->cores, list) {
1110                list_del(&core->list);
1111                kfree(core);
1112        }
1113        kfree(chip);
1114}
1115
1116struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid)
1117{
1118        struct brcmf_chip_priv *chip;
1119        struct brcmf_core_priv *core;
1120
1121        chip = container_of(pub, struct brcmf_chip_priv, pub);
1122        list_for_each_entry(core, &chip->cores, list)
1123                if (core->pub.id == coreid)
1124                        return &core->pub;
1125
1126        return NULL;
1127}
1128
1129struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *pub)
1130{
1131        struct brcmf_chip_priv *chip;
1132        struct brcmf_core_priv *cc;
1133
1134        chip = container_of(pub, struct brcmf_chip_priv, pub);
1135        cc = list_first_entry(&chip->cores, struct brcmf_core_priv, list);
1136        if (WARN_ON(!cc || cc->pub.id != BCMA_CORE_CHIPCOMMON))
1137                return brcmf_chip_get_core(pub, BCMA_CORE_CHIPCOMMON);
1138        return &cc->pub;
1139}
1140
1141struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub)
1142{
1143        struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub);
1144        struct brcmf_core *pmu;
1145
1146        /* See if there is separated PMU core available */
1147        if (cc->rev >= 35 &&
1148            pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {
1149                pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU);
1150                if (pmu)
1151                        return pmu;
1152        }
1153
1154        /* Fallback to ChipCommon core for older hardware */
1155        return cc;
1156}
1157
1158bool brcmf_chip_iscoreup(struct brcmf_core *pub)
1159{
1160        struct brcmf_core_priv *core;
1161
1162        core = container_of(pub, struct brcmf_core_priv, pub);
1163        return core->chip->iscoreup(core);
1164}
1165
1166void brcmf_chip_coredisable(struct brcmf_core *pub, u32 prereset, u32 reset)
1167{
1168        struct brcmf_core_priv *core;
1169
1170        core = container_of(pub, struct brcmf_core_priv, pub);
1171        core->chip->coredisable(core, prereset, reset);
1172}
1173
1174void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
1175                          u32 postreset)
1176{
1177        struct brcmf_core_priv *core;
1178
1179        core = container_of(pub, struct brcmf_core_priv, pub);
1180        core->chip->resetcore(core, prereset, reset, postreset);
1181}
1182
1183static void
1184brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
1185{
1186        struct brcmf_core *core;
1187        struct brcmf_core_priv *sr;
1188
1189        brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
1190        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1191        brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1192                                   D11_BCMA_IOCTL_PHYCLOCKEN,
1193                             D11_BCMA_IOCTL_PHYCLOCKEN,
1194                             D11_BCMA_IOCTL_PHYCLOCKEN);
1195        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
1196        brcmf_chip_resetcore(core, 0, 0, 0);
1197
1198        /* disable bank #3 remap for this device */
1199        if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
1200                sr = container_of(core, struct brcmf_core_priv, pub);
1201                brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
1202                brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
1203        }
1204}
1205
1206static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
1207{
1208        struct brcmf_core *core;
1209
1210        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
1211        if (!brcmf_chip_iscoreup(core)) {
1212                brcmf_err("SOCRAM core is down after reset?\n");
1213                return false;
1214        }
1215
1216        chip->ops->activate(chip->ctx, &chip->pub, 0);
1217
1218        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
1219        brcmf_chip_resetcore(core, 0, 0, 0);
1220
1221        return true;
1222}
1223
1224static inline void
1225brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)
1226{
1227        struct brcmf_core *core;
1228
1229        brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
1230
1231        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1232        brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1233                                   D11_BCMA_IOCTL_PHYCLOCKEN,
1234                             D11_BCMA_IOCTL_PHYCLOCKEN,
1235                             D11_BCMA_IOCTL_PHYCLOCKEN);
1236}
1237
1238static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
1239{
1240        struct brcmf_core *core;
1241
1242        chip->ops->activate(chip->ctx, &chip->pub, rstvec);
1243
1244        /* restore ARM */
1245        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
1246        brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
1247
1248        return true;
1249}
1250
1251static inline void
1252brcmf_chip_ca7_set_passive(struct brcmf_chip_priv *chip)
1253{
1254        struct brcmf_core *core;
1255
1256        brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CA7);
1257
1258        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
1259        brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
1260                                   D11_BCMA_IOCTL_PHYCLOCKEN,
1261                             D11_BCMA_IOCTL_PHYCLOCKEN,
1262                             D11_BCMA_IOCTL_PHYCLOCKEN);
1263}
1264
1265static bool brcmf_chip_ca7_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
1266{
1267        struct brcmf_core *core;
1268
1269        chip->ops->activate(chip->ctx, &chip->pub, rstvec);
1270
1271        /* restore ARM */
1272        core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CA7);
1273        brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
1274
1275        return true;
1276}
1277
1278void brcmf_chip_set_passive(struct brcmf_chip *pub)
1279{
1280        struct brcmf_chip_priv *chip;
1281        struct brcmf_core *arm;
1282
1283        brcmf_dbg(TRACE, "Enter\n");
1284
1285        chip = container_of(pub, struct brcmf_chip_priv, pub);
1286        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
1287        if (arm) {
1288                brcmf_chip_cr4_set_passive(chip);
1289                return;
1290        }
1291        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);
1292        if (arm) {
1293                brcmf_chip_ca7_set_passive(chip);
1294                return;
1295        }
1296        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);
1297        if (arm) {
1298                brcmf_chip_cm3_set_passive(chip);
1299                return;
1300        }
1301}
1302
1303bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
1304{
1305        struct brcmf_chip_priv *chip;
1306        struct brcmf_core *arm;
1307
1308        brcmf_dbg(TRACE, "Enter\n");
1309
1310        chip = container_of(pub, struct brcmf_chip_priv, pub);
1311        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
1312        if (arm)
1313                return brcmf_chip_cr4_set_active(chip, rstvec);
1314        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);
1315        if (arm)
1316                return brcmf_chip_ca7_set_active(chip, rstvec);
1317        arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);
1318        if (arm)
1319                return brcmf_chip_cm3_set_active(chip);
1320
1321        return false;
1322}
1323
1324bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
1325{
1326        u32 base, addr, reg, pmu_cc3_mask = ~0;
1327        struct brcmf_chip_priv *chip;
1328        struct brcmf_core *pmu = brcmf_chip_get_pmu(pub);
1329
1330        brcmf_dbg(TRACE, "Enter\n");
1331
1332        /* old chips with PMU version less than 17 don't support save restore */
1333        if (pub->pmurev < 17)
1334                return false;
1335
1336        base = brcmf_chip_get_chipcommon(pub)->base;
1337        chip = container_of(pub, struct brcmf_chip_priv, pub);
1338
1339        switch (pub->chip) {
1340        case BRCM_CC_4354_CHIP_ID:
1341        case BRCM_CC_4356_CHIP_ID:
1342        case BRCM_CC_4345_CHIP_ID:
1343                /* explicitly check SR engine enable bit */
1344                pmu_cc3_mask = BIT(2);
1345                /* fall-through */
1346        case BRCM_CC_43241_CHIP_ID:
1347        case BRCM_CC_4335_CHIP_ID:
1348        case BRCM_CC_4339_CHIP_ID:
1349                /* read PMU chipcontrol register 3 */
1350                addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
1351                chip->ops->write32(chip->ctx, addr, 3);
1352                addr = CORE_CC_REG(pmu->base, chipcontrol_data);
1353                reg = chip->ops->read32(chip->ctx, addr);
1354                return (reg & pmu_cc3_mask) != 0;
1355        case BRCM_CC_43430_CHIP_ID:
1356                addr = CORE_CC_REG(base, sr_control1);
1357                reg = chip->ops->read32(chip->ctx, addr);
1358                return reg != 0;
1359        default:
1360                addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
1361                reg = chip->ops->read32(chip->ctx, addr);
1362                if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
1363                        return false;
1364
1365                addr = CORE_CC_REG(pmu->base, retention_ctl);
1366                reg = chip->ops->read32(chip->ctx, addr);
1367                return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
1368                               PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
1369        }
1370}
1371