diff options
Diffstat (limited to 'package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch')
-rw-r--r-- | package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch b/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch new file mode 100644 index 0000000000..bcc2ed4868 --- /dev/null +++ b/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch @@ -0,0 +1,367 @@ +From: Arend van Spriel <arend@broadcom.com> +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 <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> +--- + +--- 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]; + }; + |