aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/336-0005-brcmfmac-extract-ram-size-info-from-internal-memory-.patch
diff options
context:
space:
mode:
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-.patch367
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];
+ };
+