123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- From: Arend van Spriel <[email protected]>
- Date: Wed, 11 Mar 2015 16:11:31 +0100
- Subject: [PATCH] brcmfmac: extract ram size info from internal memory
- registers
- Instead of hard-coded memory sizes it is possible to obtain that
- information from the internal memory registers.
- Reviewed-by: Hante Meuleman <[email protected]>
- Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
- Reviewed-by: Pieter-Paul Giesberts <[email protected]>
- Signed-off-by: Arend van Spriel <[email protected]>
- Signed-off-by: Kalle Valo <[email protected]>
- ---
- --- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
- +++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
- @@ -100,9 +100,6 @@
- #define BCM4329_CORE_SOCRAM_BASE 0x18003000
- /* ARM Cortex M3 core, ID 0x82a */
- #define BCM4329_CORE_ARM_BASE 0x18002000
- -#define BCM4329_RAMSIZE 0x48000
- -/* bcm43143 */
- -#define BCM43143_RAMSIZE 0x70000
-
- #define CORE_SB(base, field) \
- (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
- @@ -150,6 +147,78 @@ struct sbconfig {
- u32 sbidhigh; /* identification */
- };
-
- +/* bankidx and bankinfo reg defines corerev >= 8 */
- +#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000
- +#define SOCRAM_BANKINFO_SZMASK 0x0000007f
- +#define SOCRAM_BANKIDX_ROM_MASK 0x00000100
- +
- +#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8
- +/* socram bankinfo memtype */
- +#define SOCRAM_MEMTYPE_RAM 0
- +#define SOCRAM_MEMTYPE_R0M 1
- +#define SOCRAM_MEMTYPE_DEVRAM 2
- +
- +#define SOCRAM_BANKINFO_SZBASE 8192
- +#define SRCI_LSS_MASK 0x00f00000
- +#define SRCI_LSS_SHIFT 20
- +#define SRCI_SRNB_MASK 0xf0
- +#define SRCI_SRNB_SHIFT 4
- +#define SRCI_SRBSZ_MASK 0xf
- +#define SRCI_SRBSZ_SHIFT 0
- +#define SR_BSZ_BASE 14
- +
- +struct sbsocramregs {
- + u32 coreinfo;
- + u32 bwalloc;
- + u32 extracoreinfo;
- + u32 biststat;
- + u32 bankidx;
- + u32 standbyctrl;
- +
- + u32 errlogstatus; /* rev 6 */
- + u32 errlogaddr; /* rev 6 */
- + /* used for patching rev 3 & 5 */
- + u32 cambankidx;
- + u32 cambankstandbyctrl;
- + u32 cambankpatchctrl;
- + u32 cambankpatchtblbaseaddr;
- + u32 cambankcmdreg;
- + u32 cambankdatareg;
- + u32 cambankmaskreg;
- + u32 PAD[1];
- + u32 bankinfo; /* corev 8 */
- + u32 bankpda;
- + u32 PAD[14];
- + u32 extmemconfig;
- + u32 extmemparitycsr;
- + u32 extmemparityerrdata;
- + u32 extmemparityerrcnt;
- + u32 extmemwrctrlandsize;
- + u32 PAD[84];
- + u32 workaround;
- + u32 pwrctl; /* corerev >= 2 */
- + u32 PAD[133];
- + u32 sr_control; /* corerev >= 15 */
- + u32 sr_status; /* corerev >= 15 */
- + u32 sr_address; /* corerev >= 15 */
- + u32 sr_data; /* corerev >= 15 */
- +};
- +
- +#define SOCRAMREGOFFS(_f) offsetof(struct sbsocramregs, _f)
- +
- +#define ARMCR4_CAP (0x04)
- +#define ARMCR4_BANKIDX (0x40)
- +#define ARMCR4_BANKINFO (0x44)
- +#define ARMCR4_BANKPDA (0x4C)
- +
- +#define ARMCR4_TCBBNB_MASK 0xf0
- +#define ARMCR4_TCBBNB_SHIFT 4
- +#define ARMCR4_TCBANB_MASK 0xf
- +#define ARMCR4_TCBANB_SHIFT 0
- +
- +#define ARMCR4_BSZ_MASK 0x3f
- +#define ARMCR4_BSZ_MULT 8192
- +
- struct brcmf_core_priv {
- struct brcmf_core pub;
- u32 wrapbase;
- @@ -443,10 +512,6 @@ static int brcmf_chip_cores_check(struct
- break;
- case BCMA_CORE_ARM_CR4:
- cpu_found = true;
- - if (ci->pub.rambase == 0) {
- - brcmf_err("RAM base not provided with ARM CR4 core\n");
- - return -ENOMEM;
- - }
- break;
- default:
- break;
- @@ -462,60 +527,160 @@ static int brcmf_chip_cores_check(struct
- brcmf_err("RAM core not provided with ARM CM3 core\n");
- return -ENODEV;
- }
- - if (!ci->pub.ramsize) {
- - brcmf_err("RAM size is undetermined\n");
- - return -ENOMEM;
- - }
- return 0;
- }
-
- -static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
- +static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg)
- {
- - switch (ci->pub.chip) {
- - case BRCM_CC_4329_CHIP_ID:
- - ci->pub.ramsize = BCM4329_RAMSIZE;
- - break;
- - case BRCM_CC_43143_CHIP_ID:
- - ci->pub.ramsize = BCM43143_RAMSIZE;
- - break;
- - case BRCM_CC_43241_CHIP_ID:
- - ci->pub.ramsize = 0x90000;
- - break;
- - case BRCM_CC_4330_CHIP_ID:
- - ci->pub.ramsize = 0x48000;
- - break;
- + return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg);
- +}
- +
- +static void brcmf_chip_core_write32(struct brcmf_core_priv *core,
- + u16 reg, u32 val)
- +{
- + core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val);
- +}
- +
- +static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx,
- + u32 *banksize)
- +{
- + u32 bankinfo;
- + u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
- +
- + bankidx |= idx;
- + brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx);
- + bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo));
- + *banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1;
- + *banksize *= SOCRAM_BANKINFO_SZBASE;
- + return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK);
- +}
- +
- +static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
- + u32 *srsize)
- +{
- + u32 coreinfo;
- + uint nb, banksize, lss;
- + bool retent;
- + int i;
- +
- + *ramsize = 0;
- + *srsize = 0;
- +
- + if (WARN_ON(sr->pub.rev < 4))
- + return;
- +
- + if (!brcmf_chip_iscoreup(&sr->pub))
- + brcmf_chip_resetcore(&sr->pub, 0, 0, 0);
- +
- + /* Get info for determining size */
- + coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo));
- + nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- +
- + if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) {
- + banksize = (coreinfo & SRCI_SRBSZ_MASK);
- + lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
- + if (lss != 0)
- + nb--;
- + *ramsize = nb * (1 << (banksize + SR_BSZ_BASE));
- + if (lss != 0)
- + *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
- + } else {
- + nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- + for (i = 0; i < nb; i++) {
- + retent = brcmf_chip_socram_banksize(sr, i, &banksize);
- + *ramsize += banksize;
- + if (retent)
- + *srsize += banksize;
- + }
- + }
- +
- + /* hardcoded save&restore memory sizes */
- + switch (sr->chip->pub.chip) {
- case BRCM_CC_4334_CHIP_ID:
- - case BRCM_CC_43340_CHIP_ID:
- - ci->pub.ramsize = 0x80000;
- + if (sr->chip->pub.chiprev < 2)
- + *srsize = (32 * 1024);
- break;
- - case BRCM_CC_4335_CHIP_ID:
- - ci->pub.ramsize = 0xc0000;
- - ci->pub.rambase = 0x180000;
- - break;
- - case BRCM_CC_43362_CHIP_ID:
- - ci->pub.ramsize = 0x3c000;
- + default:
- break;
- + }
- +}
- +
- +/** Return the TCM-RAM size of the ARMCR4 core. */
- +static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
- +{
- + u32 corecap;
- + u32 memsize = 0;
- + u32 nab;
- + u32 nbb;
- + u32 totb;
- + u32 bxinfo;
- + u32 idx;
- +
- + corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP);
- +
- + nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
- + nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
- + totb = nab + nbb;
- +
- + for (idx = 0; idx < totb; idx++) {
- + brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx);
- + bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO);
- + memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
- + }
- +
- + return memsize;
- +}
- +
- +static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
- +{
- + switch (ci->pub.chip) {
- case BRCM_CC_4345_CHIP_ID:
- - ci->pub.ramsize = 0xc8000;
- - ci->pub.rambase = 0x198000;
- - break;
- + return 0x198000;
- + case BRCM_CC_4335_CHIP_ID:
- case BRCM_CC_4339_CHIP_ID:
- case BRCM_CC_4354_CHIP_ID:
- case BRCM_CC_4356_CHIP_ID:
- case BRCM_CC_43567_CHIP_ID:
- case BRCM_CC_43569_CHIP_ID:
- case BRCM_CC_43570_CHIP_ID:
- - ci->pub.ramsize = 0xc0000;
- - ci->pub.rambase = 0x180000;
- - break;
- case BRCM_CC_43602_CHIP_ID:
- - ci->pub.ramsize = 0xf0000;
- - ci->pub.rambase = 0x180000;
- - break;
- + return 0x180000;
- default:
- brcmf_err("unknown chip: %s\n", ci->pub.name);
- break;
- }
- + return 0;
- +}
- +
- +static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
- +{
- + struct brcmf_core_priv *mem_core;
- + struct brcmf_core *mem;
- +
- + mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
- + if (mem) {
- + mem_core = container_of(mem, struct brcmf_core_priv, pub);
- + ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
- + ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
- + if (!ci->pub.rambase) {
- + brcmf_err("RAM base not provided with ARM CR4 core\n");
- + return -EINVAL;
- + }
- + } else {
- + mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM);
- + mem_core = container_of(mem, struct brcmf_core_priv, pub);
- + brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
- + &ci->pub.srsize);
- + }
- + brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
- + ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
- + ci->pub.srsize, ci->pub.srsize);
- +
- + if (!ci->pub.ramsize) {
- + brcmf_err("RAM size is undetermined\n");
- + return -ENOMEM;
- + }
- + return 0;
- }
-
- static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
- @@ -668,6 +833,7 @@ static int brcmf_chip_recognition(struct
- struct brcmf_core *core;
- u32 regdata;
- u32 socitype;
- + int ret;
-
- /* Get CC core rev
- * Chipid is assume to be at offset 0 from SI_ENUM_BASE
- @@ -720,9 +886,13 @@ static int brcmf_chip_recognition(struct
- return -ENODEV;
- }
-
- - brcmf_chip_get_raminfo(ci);
- -
- - return brcmf_chip_cores_check(ci);
- + ret = brcmf_chip_cores_check(ci);
- + if (ret)
- + return ret;
- +
- + /* assure chip is passive for core access */
- + brcmf_chip_set_passive(&ci->pub);
- + return brcmf_chip_get_raminfo(ci);
- }
-
- static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
- @@ -827,8 +997,6 @@ struct brcmf_chip *brcmf_chip_attach(voi
- if (err < 0)
- goto fail;
-
- - /* assure chip is passive for download */
- - brcmf_chip_set_passive(&chip->pub);
- return &chip->pub;
-
- fail:
- --- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
- +++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
- @@ -30,7 +30,8 @@
- * @pmucaps: PMU capabilities.
- * @pmurev: PMU revision.
- * @rambase: RAM base address (only applicable for ARM CR4 chips).
- - * @ramsize: amount of RAM on chip.
- + * @ramsize: amount of RAM on chip including retention.
- + * @srsize: amount of retention RAM on chip.
- * @name: string representation of the chip identifier.
- */
- struct brcmf_chip {
- @@ -41,6 +42,7 @@ struct brcmf_chip {
- u32 pmurev;
- u32 rambase;
- u32 ramsize;
- + u32 srsize;
- char name[8];
- };
-
|