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 <meuleman@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
38f29e1f42
commit
0da32ba4ee
2 changed files with 219 additions and 49 deletions
|
@ -100,9 +100,6 @@
|
||||||
#define BCM4329_CORE_SOCRAM_BASE 0x18003000
|
#define BCM4329_CORE_SOCRAM_BASE 0x18003000
|
||||||
/* ARM Cortex M3 core, ID 0x82a */
|
/* ARM Cortex M3 core, ID 0x82a */
|
||||||
#define BCM4329_CORE_ARM_BASE 0x18002000
|
#define BCM4329_CORE_ARM_BASE 0x18002000
|
||||||
#define BCM4329_RAMSIZE 0x48000
|
|
||||||
/* bcm43143 */
|
|
||||||
#define BCM43143_RAMSIZE 0x70000
|
|
||||||
|
|
||||||
#define CORE_SB(base, field) \
|
#define CORE_SB(base, field) \
|
||||||
(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
|
(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
|
||||||
|
@ -150,6 +147,78 @@ struct sbconfig {
|
||||||
u32 sbidhigh; /* identification */
|
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_priv {
|
||||||
struct brcmf_core pub;
|
struct brcmf_core pub;
|
||||||
u32 wrapbase;
|
u32 wrapbase;
|
||||||
|
@ -443,10 +512,6 @@ static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
|
||||||
break;
|
break;
|
||||||
case BCMA_CORE_ARM_CR4:
|
case BCMA_CORE_ARM_CR4:
|
||||||
cpu_found = true;
|
cpu_found = true;
|
||||||
if (ci->pub.rambase == 0) {
|
|
||||||
brcmf_err("RAM base not provided with ARM CR4 core\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -462,60 +527,160 @@ static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
|
||||||
brcmf_err("RAM core not provided with ARM CM3 core\n");
|
brcmf_err("RAM core not provided with ARM CM3 core\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
if (!ci->pub.ramsize) {
|
|
||||||
brcmf_err("RAM size is undetermined\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
return 0;
|
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)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
if (sr->chip->pub.chiprev < 2)
|
||||||
|
*srsize = (32 * 1024);
|
||||||
|
break;
|
||||||
|
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) {
|
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;
|
|
||||||
case BRCM_CC_4334_CHIP_ID:
|
|
||||||
case BRCM_CC_43340_CHIP_ID:
|
|
||||||
ci->pub.ramsize = 0x80000;
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
case BRCM_CC_4345_CHIP_ID:
|
case BRCM_CC_4345_CHIP_ID:
|
||||||
ci->pub.ramsize = 0xc8000;
|
return 0x198000;
|
||||||
ci->pub.rambase = 0x198000;
|
case BRCM_CC_4335_CHIP_ID:
|
||||||
break;
|
|
||||||
case BRCM_CC_4339_CHIP_ID:
|
case BRCM_CC_4339_CHIP_ID:
|
||||||
case BRCM_CC_4354_CHIP_ID:
|
case BRCM_CC_4354_CHIP_ID:
|
||||||
case BRCM_CC_4356_CHIP_ID:
|
case BRCM_CC_4356_CHIP_ID:
|
||||||
case BRCM_CC_43567_CHIP_ID:
|
case BRCM_CC_43567_CHIP_ID:
|
||||||
case BRCM_CC_43569_CHIP_ID:
|
case BRCM_CC_43569_CHIP_ID:
|
||||||
case BRCM_CC_43570_CHIP_ID:
|
case BRCM_CC_43570_CHIP_ID:
|
||||||
ci->pub.ramsize = 0xc0000;
|
|
||||||
ci->pub.rambase = 0x180000;
|
|
||||||
break;
|
|
||||||
case BRCM_CC_43602_CHIP_ID:
|
case BRCM_CC_43602_CHIP_ID:
|
||||||
ci->pub.ramsize = 0xf0000;
|
return 0x180000;
|
||||||
ci->pub.rambase = 0x180000;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
brcmf_err("unknown chip: %s\n", ci->pub.name);
|
brcmf_err("unknown chip: %s\n", ci->pub.name);
|
||||||
break;
|
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,
|
static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
|
||||||
|
@ -668,6 +833,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
|
||||||
struct brcmf_core *core;
|
struct brcmf_core *core;
|
||||||
u32 regdata;
|
u32 regdata;
|
||||||
u32 socitype;
|
u32 socitype;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Get CC core rev
|
/* Get CC core rev
|
||||||
* Chipid is assume to be at offset 0 from SI_ENUM_BASE
|
* Chipid is assume to be at offset 0 from SI_ENUM_BASE
|
||||||
|
@ -720,9 +886,13 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
brcmf_chip_get_raminfo(ci);
|
ret = brcmf_chip_cores_check(ci);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return brcmf_chip_cores_check(ci);
|
/* 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)
|
static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
|
||||||
|
@ -827,8 +997,6 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* assure chip is passive for download */
|
|
||||||
brcmf_chip_set_passive(&chip->pub);
|
|
||||||
return &chip->pub;
|
return &chip->pub;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
* @pmucaps: PMU capabilities.
|
* @pmucaps: PMU capabilities.
|
||||||
* @pmurev: PMU revision.
|
* @pmurev: PMU revision.
|
||||||
* @rambase: RAM base address (only applicable for ARM CR4 chips).
|
* @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.
|
* @name: string representation of the chip identifier.
|
||||||
*/
|
*/
|
||||||
struct brcmf_chip {
|
struct brcmf_chip {
|
||||||
|
@ -41,6 +42,7 @@ struct brcmf_chip {
|
||||||
u32 pmurev;
|
u32 pmurev;
|
||||||
u32 rambase;
|
u32 rambase;
|
||||||
u32 ramsize;
|
u32 ramsize;
|
||||||
|
u32 srsize;
|
||||||
char name[8];
|
char name[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue