summaryrefslogtreecommitdiff
path: root/target/linux/brcm-2.4/files
diff options
context:
space:
mode:
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2008-01-06 19:28:07 +0000
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>2008-01-06 19:28:07 +0000
commit90fba37c49479ed4e5233dc0d348cdf7d24c9ee1 (patch)
tree58af9e3b3204308a2b7853127331f4d693e1b744 /target/linux/brcm-2.4/files
parentb59f896089edf83ce4cd1951001b6cc889bdd287 (diff)
update brcm-2.4 to 2.4.35.4, integrate new broadcom system code, update broadcom-wl to a contributed version (v4.150.10.5) - no bcm57xx support yet, will follow shortly
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@10137 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm-2.4/files')
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/Makefile4
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmsrom.c2928
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmutils.c247
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/cfe_env.c233
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/compressed/Makefile33
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/export.c19
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/gpio.c3
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndchipc.c380
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c1257
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdefs.h2
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdevs.h233
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmendian.h4
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmnvram.h51
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmsrom.h216
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmutils.h433
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndchipc.h31
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndcpu.h10
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndmips.h7
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpci.h9
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpmu.h37
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linux_gpio.h33
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linuxver.h40
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/mipsinc.h6
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/osl.h82
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/pcicfg.h19
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbchipc.h507
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbconfig.h51
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbextif.h9
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbhndmips.h4
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbmemc.h4
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpci.h11
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcie.h53
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcmcia.h44
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsdram.h15
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsocram.h44
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsprom.h277
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbutils.h75
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sflash.h20
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/trxhdr.h12
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/typedefs.h37
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram.c54
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram_linux.c12
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/pcibios.c22
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbmips.c849
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c267
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbutils.c2681
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/setup.c3
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c422
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/time.c14
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.c105
-rw-r--r--target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.h65
-rw-r--r--target/linux/brcm-2.4/files/drivers/mtd/devices/sflash.c733
-rw-r--r--target/linux/brcm-2.4/files/drivers/mtd/maps/bcm947xx-flash.c3
53 files changed, 8528 insertions, 4182 deletions
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/Makefile b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/Makefile
index 55e1757efc..f2096137e4 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/Makefile
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/Makefile
@@ -9,8 +9,8 @@ O_TARGET := bcm947xx.o
export-objs := export.o
obj-y := prom.o setup.o time.o sbmips.o gpio.o
-obj-y += nvram.o nvram_linux.o sflash.o
-obj-y += sbutils.o bcmutils.o bcmsrom.o hndchipc.o
+obj-y += nvram.o nvram_linux.o cfe_env.o hndpmu.o
+obj-y += sbutils.o utils.o bcmsrom.o hndchipc.o
obj-$(CONFIG_PCI) += sbpci.o pcibios.o
obj-y += export.o
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmsrom.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmsrom.c
index 1d08218a42..d5737d72fc 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmsrom.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmsrom.c
@@ -1,509 +1,1048 @@
/*
- * Misc useful routines to access NIC SROM/OTP .
+ * Routines to access SPROM and to parse SROM/CIS variables.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: bcmsrom.c,v 1.1.1.14 2006/04/15 01:28:25 michael Exp $
+ * $Id$
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
-#include <bcmutils.h>
-#include <bcmsrom.h>
+#include <stdarg.h>
+#include <sbchipc.h>
#include <bcmdevs.h>
#include <bcmendian.h>
#include <sbpcmcia.h>
#include <pcicfg.h>
+#include <sbconfig.h>
#include <sbutils.h>
+#include <bcmsrom.h>
#include <bcmnvram.h>
+#include "utils.h"
/* debug/trace */
#if defined(WLTEST)
#define BS_ERROR(args) printf args
#else
#define BS_ERROR(args)
-#endif /* BCMDBG_ERR || WLTEST */
-
-#define VARS_MAX 4096 /* should be reduced */
+#endif
#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
-static int initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count);
-static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, uint *count);
-static int initvars_flash_sb(void *sbh, char **vars, uint *count);
-static int srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count);
-static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd);
-static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data);
-static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data);
-static int sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords,
- bool check_crc);
+typedef struct varbuf
+{
+ char *buf; /* pointer to current position */
+ unsigned int size; /* current (residual) size in bytes */
+} varbuf_t;
+
+static int initvars_srom_sb (sb_t * sbh, osl_t * osh, void *curmap,
+ char **vars, uint * count);
+static void _initvars_srom_pci (uint8 sromrev, uint16 * srom, uint off,
+ varbuf_t * b);
+static int initvars_srom_pci (sb_t * sbh, void *curmap, char **vars,
+ uint * count);
+static int initvars_cis_pcmcia (sb_t * sbh, osl_t * osh, char **vars,
+ uint * count);
+#if !defined(BCMUSBDEV) && !defined(BCMSDIODEV)
+static int initvars_flash_sb (sb_t * sbh, char **vars, uint * count);
+#endif /* !BCMUSBDEV && !BCMSDIODEV */
+static int sprom_cmd_pcmcia (osl_t * osh, uint8 cmd);
+static int sprom_read_pcmcia (osl_t * osh, uint16 addr, uint16 * data);
+static int sprom_write_pcmcia (osl_t * osh, uint16 addr, uint16 data);
+static int sprom_read_pci (osl_t * osh, uint16 * sprom, uint wordoff,
+ uint16 * buf, uint nwords, bool check_crc);
+
+static int initvars_table (osl_t * osh, char *start, char *end, char **vars,
+ uint * count);
+static int initvars_flash (sb_t * sbh, osl_t * osh, char **vp, uint len);
+
+#ifdef BCMUSBDEV
+static int get_sb_pcmcia_srom (sb_t * sbh, osl_t * osh, uint8 * pcmregs,
+ uint boff, uint16 * srom, uint bsz);
+static int set_sb_pcmcia_srom (sb_t * sbh, osl_t * osh, uint8 * pcmregs,
+ uint boff, uint16 * srom, uint bsz);
+static uint srom_size (sb_t * sbh, osl_t * osh);
+#endif /* def BCMUSBDEV */
+
+/* Initialization of varbuf structure */
+static void
+varbuf_init (varbuf_t * b, char *buf, uint size)
+{
+ b->size = size;
+ b->buf = buf;
+}
-static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count);
-static int initvars_flash(osl_t *osh, char **vp, uint len, char *devpath);
+/* append a null terminated var=value string */
+static int
+varbuf_append (varbuf_t * b, const char *fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ if (b->size < 2)
+ return 0;
+
+ va_start (ap, fmt);
+ r = vsnprintf (b->buf, b->size, fmt, ap);
+ va_end (ap);
+
+ /* C99 snprintf behavior returns r >= size on overflow,
+ * others return -1 on overflow.
+ * All return -1 on format error.
+ * We need to leave room for 2 null terminations, one for the current var
+ * string, and one for final null of the var table. So check that the
+ * strlen written, r, leaves room for 2 chars.
+ */
+ if ((r == -1) || (r > (int) (b->size - 2)))
+ {
+ b->size = 0;
+ return 0;
+ }
+
+ /* skip over this string's null termination */
+ r++;
+ b->size -= r;
+ b->buf += r;
+
+ return r;
+}
/*
* Initialize local vars from the right source for this platform.
* Return 0 on success, nonzero on error.
*/
int
-srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, uint *count)
+BCMINITFN (srom_var_init) (sb_t * sbh, uint bustype, void *curmap,
+ osl_t * osh, char **vars, uint * count)
{
- ASSERT(bustype == BUSTYPE(bustype));
- if (vars == NULL || count == NULL)
- return (0);
+ ASSERT (bustype == BUSTYPE (bustype));
+ if (vars == NULL || count == NULL)
+ return (0);
- switch (BUSTYPE(bustype)) {
- case SB_BUS:
- case JTAG_BUS:
- return initvars_flash_sb(sbh, vars, count);
+ *vars = NULL;
+ *count = 0;
- case PCI_BUS:
- ASSERT(curmap); /* can not be NULL */
- return initvars_srom_pci(sbh, curmap, vars, count);
+ switch (BUSTYPE (bustype))
+ {
+ case SB_BUS:
+ case JTAG_BUS:
+ return initvars_srom_sb (sbh, osh, curmap, vars, count);
- case PCMCIA_BUS:
- return initvars_cis_pcmcia(sbh, osh, vars, count);
+ case PCI_BUS:
+ ASSERT (curmap); /* can not be NULL */
+ return initvars_srom_pci (sbh, curmap, vars, count);
+ case PCMCIA_BUS:
+ return initvars_cis_pcmcia (sbh, osh, vars, count);
- default:
- ASSERT(0);
- }
- return (-1);
+
+ default:
+ ASSERT (0);
+ }
+ return (-1);
}
/* support only 16-bit word read from srom */
int
-srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
+srom_read (sb_t * sbh, uint bustype, void *curmap, osl_t * osh,
+ uint byteoff, uint nbytes, uint16 * buf)
{
- void *srom;
- uint i, off, nw;
-
- ASSERT(bustype == BUSTYPE(bustype));
-
- /* check input - 16-bit access only */
- if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
- return 1;
-
- off = byteoff / 2;
- nw = nbytes / 2;
-
- if (BUSTYPE(bustype) == PCI_BUS) {
- if (!curmap)
- return 1;
- srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET;
- if (sprom_read_pci(osh, srom, off, buf, nw, FALSE))
- return 1;
- } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
- for (i = 0; i < nw; i++) {
- if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i)))
- return 1;
- }
- } else {
- return 1;
+ void *srom;
+ uint i, off, nw;
+
+ ASSERT (bustype == BUSTYPE (bustype));
+
+ /* check input - 16-bit access only */
+ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
+ return 1;
+
+ off = byteoff / 2;
+ nw = nbytes / 2;
+
+ if (BUSTYPE (bustype) == PCI_BUS)
+ {
+ if (!curmap)
+ return 1;
+ srom = (uchar *) curmap + PCI_BAR0_SPROM_OFFSET;
+ if (sprom_read_pci (osh, srom, off, buf, nw, FALSE))
+ return 1;
+ }
+ else if (BUSTYPE (bustype) == PCMCIA_BUS)
+ {
+ for (i = 0; i < nw; i++)
+ {
+ if (sprom_read_pcmcia
+ (osh, (uint16) (off + i), (uint16 *) (buf + i)))
+ return 1;
}
+ }
+ else if (BUSTYPE (bustype) == SB_BUS)
+ {
+#ifdef BCMUSBDEV
+ if (SPROMBUS == PCMCIA_BUS)
+ {
+ uint origidx;
+ void *regs;
+ int rc;
+ bool wasup;
+
+ origidx = sb_coreidx (sbh);
+ regs = sb_setcore (sbh, SB_PCMCIA, 0);
+ ASSERT (regs != NULL);
+
+ if (!(wasup = sb_iscoreup (sbh)))
+ sb_core_reset (sbh, 0, 0);
+
+ rc = get_sb_pcmcia_srom (sbh, osh, regs, byteoff, buf, nbytes);
+
+ if (!wasup)
+ sb_core_disable (sbh, 0);
+
+ sb_setcoreidx (sbh, origidx);
+ return rc;
+ }
+#endif /* def BCMUSBDEV */
- return 0;
+ return 1;
+ }
+ else
+ {
+ return 1;
+ }
+
+ return 0;
}
/* support only 16-bit word write into srom */
int
-srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
+srom_write (sb_t * sbh, uint bustype, void *curmap, osl_t * osh,
+ uint byteoff, uint nbytes, uint16 * buf)
{
- uint16 *srom;
- uint i, nw, crc_range;
- uint16 image[SPROM_SIZE];
- uint8 crc;
- volatile uint32 val32;
-
- ASSERT(bustype == BUSTYPE(bustype));
-
- /* check input - 16-bit access only */
- if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
- return 1;
-
- /* Are we writing the whole thing at once? */
- if ((byteoff == 0) &&
- ((nbytes == SPROM_SIZE) ||
- (nbytes == (SPROM_CRC_RANGE * 2)) ||
- (nbytes == (SROM4_WORDS * 2)))) {
- crc_range = nbytes;
- bcopy((void*)buf, (void*)image, nbytes);
- nw = nbytes / 2;
- } else {
- if ((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS))
- crc_range = SPROM_SIZE;
- else
- crc_range = SPROM_CRC_RANGE * 2; /* Tentative */
-
- nw = crc_range / 2;
- /* read first 64 words from srom */
- if (srom_read(bustype, curmap, osh, 0, crc_range, image))
- return 1;
- if (image[SROM4_SIGN] == SROM4_SIGNATURE) {
- crc_range = SROM4_WORDS;
- nw = crc_range / 2;
- if (srom_read(bustype, curmap, osh, 0, crc_range, image))
- return 1;
- }
- /* make changes */
- bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes);
+ uint16 *srom;
+ uint i, nw, crc_range;
+ uint16 image[SPROM_SIZE];
+ uint8 crc;
+ volatile uint32 val32;
+
+ ASSERT (bustype == BUSTYPE (bustype));
+
+ /* check input - 16-bit access only */
+ if ((byteoff & 1) || (nbytes & 1))
+ return 1;
+
+ if (byteoff == 0x55aa)
+ {
+ /* Erase request */
+ crc_range = 0;
+ memset ((void *) image, 0xff, nbytes);
+ nw = nbytes / 2;
+ }
+ else if ((byteoff == 0) &&
+ ((nbytes == SPROM_SIZE * 2) ||
+ (nbytes == (SPROM_CRC_RANGE * 2)) ||
+ (nbytes == (SROM4_WORDS * 2))))
+ {
+ /* Are we writing the whole thing at once? */
+ crc_range = nbytes;
+ bcopy ((void *) buf, (void *) image, nbytes);
+ nw = nbytes / 2;
+ }
+ else
+ {
+ if ((byteoff + nbytes) > (SPROM_SIZE * 2))
+ return 1;
+
+ if (BUSTYPE (bustype) == PCMCIA_BUS)
+ {
+ crc_range = SPROM_SIZE * 2;
+ }
+ else
+ {
+ crc_range = SPROM_CRC_RANGE * 2; /* Tentative */
}
- /* calculate crc */
- htol16_buf(image, crc_range);
- crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
- ltoh16_buf(image, crc_range);
- image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff);
-
- if (BUSTYPE(bustype) == PCI_BUS) {
- srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET);
- /* enable writes to the SPROM */
- val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
- val32 |= SPROM_WRITEEN;
- OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
- bcm_mdelay(WRITE_ENABLE_DELAY);
- /* write srom */
- for (i = 0; i < nw; i++) {
- W_REG(osh, &srom[i], image[i]);
- bcm_mdelay(WRITE_WORD_DELAY);
- }
- /* disable writes to the SPROM */
- OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 &
- ~SPROM_WRITEEN);
- } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
- /* enable writes to the SPROM */
- if (sprom_cmd_pcmcia(osh, SROM_WEN))
- return 1;
- bcm_mdelay(WRITE_ENABLE_DELAY);
- /* write srom */
- for (i = 0; i < nw; i++) {
- sprom_write_pcmcia(osh, (uint16)(i), image[i]);
- bcm_mdelay(WRITE_WORD_DELAY);
- }
- /* disable writes to the SPROM */
- if (sprom_cmd_pcmcia(osh, SROM_WDS))
- return 1;
- } else {
- return 1;
+ nw = crc_range / 2;
+ /* read first 64 words from srom */
+ if (srom_read (sbh, bustype, curmap, osh, 0, crc_range, image))
+ return 1;
+ if (image[SROM4_SIGN] == SROM4_SIGNATURE)
+ {
+ nw = SROM4_WORDS;
+ crc_range = nw * 2;
+ if (srom_read (sbh, bustype, curmap, osh, 0, crc_range, image))
+ return 1;
+ }
+ /* make changes */
+ bcopy ((void *) buf, (void *) &image[byteoff / 2], nbytes);
+ }
+
+ if (crc_range)
+ {
+ /* calculate crc */
+ htol16_buf (image, crc_range);
+ crc = ~hndcrc8 ((uint8 *) image, crc_range - 1, 0xff);
+ ltoh16_buf (image, crc_range);
+ image[nw - 1] = (crc << 8) | (image[nw - 1] & 0xff);
+ }
+
+ if (BUSTYPE (bustype) == PCI_BUS)
+ {
+ srom = (uint16 *) ((uchar *) curmap + PCI_BAR0_SPROM_OFFSET);
+ /* enable writes to the SPROM */
+ val32 = OSL_PCI_READ_CONFIG (osh, PCI_SPROM_CONTROL, sizeof (uint32));
+ val32 |= SPROM_WRITEEN;
+ OSL_PCI_WRITE_CONFIG (osh, PCI_SPROM_CONTROL, sizeof (uint32), val32);
+ bcm_mdelay (WRITE_ENABLE_DELAY);
+ /* write srom */
+ for (i = 0; i < nw; i++)
+ {
+ W_REG (osh, &srom[i], image[i]);
+ bcm_mdelay (WRITE_WORD_DELAY);
+ }
+ /* disable writes to the SPROM */
+ OSL_PCI_WRITE_CONFIG (osh, PCI_SPROM_CONTROL, sizeof (uint32), val32 &
+ ~SPROM_WRITEEN);
+ }
+ else if (BUSTYPE (bustype) == PCMCIA_BUS)
+ {
+ /* enable writes to the SPROM */
+ if (sprom_cmd_pcmcia (osh, SROM_WEN))
+ return 1;
+ bcm_mdelay (WRITE_ENABLE_DELAY);
+ /* write srom */
+ for (i = 0; i < nw; i++)
+ {
+ sprom_write_pcmcia (osh, (uint16) (i), image[i]);
+ bcm_mdelay (WRITE_WORD_DELAY);
}
+ /* disable writes to the SPROM */
+ if (sprom_cmd_pcmcia (osh, SROM_WDS))
+ return 1;
+ }
+ else if (BUSTYPE (bustype) == SB_BUS)
+ {
+#ifdef BCMUSBDEV
+ if (SPROMBUS == PCMCIA_BUS)
+ {
+ uint origidx;
+ void *regs;
+ int rc;
+ bool wasup;
+
+ origidx = sb_coreidx (sbh);
+ regs = sb_setcore (sbh, SB_PCMCIA, 0);
+ ASSERT (regs != NULL);
+
+ if (!(wasup = sb_iscoreup (sbh)))
+ sb_core_reset (sbh, 0, 0);
+
+ rc = set_sb_pcmcia_srom (sbh, osh, regs, byteoff, buf, nbytes);
+
+ if (!wasup)
+ sb_core_disable (sbh, 0);
+
+ sb_setcoreidx (sbh, origidx);
+ return rc;
+ }
+#endif /* def BCMUSBDEV */
+ return 1;
+ }
+ else
+ {
+ return 1;
+ }
+
+ bcm_mdelay (WRITE_ENABLE_DELAY);
+ return 0;
+}
+
+#ifdef BCMUSBDEV
+#define SB_PCMCIA_READ(osh, regs, fcr) \
+ R_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2)
+#define SB_PCMCIA_WRITE(osh, regs, fcr, v) \
+ W_REG(osh, (volatile uint8 *)(regs) + 0x600 + (fcr) - 0x700 / 2, v)
+
+/* set PCMCIA srom command register */
+static int
+srom_cmd_sb_pcmcia (osl_t * osh, uint8 * pcmregs, uint8 cmd)
+{
+ uint8 status = 0;
+ uint wait_cnt = 0;
+
+ /* write srom command register */
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_CS, cmd);
- bcm_mdelay(WRITE_ENABLE_DELAY);
+ /* wait status */
+ while (++wait_cnt < 1000000)
+ {
+ status = SB_PCMCIA_READ (osh, pcmregs, SROM_CS);
+ if (status & SROM_DONE)
return 0;
+ OSL_DELAY (1);
+ }
+
+ BS_ERROR (("sr_cmd: Give up after %d tries, stat = 0x%x\n", wait_cnt,
+ status));
+ return 1;
}
+/* read a word from the PCMCIA srom over SB */
+static int
+srom_read_sb_pcmcia (osl_t * osh, uint8 * pcmregs, uint16 addr, uint16 * data)
+{
+ uint8 addr_l, addr_h, data_l, data_h;
+
+ addr_l = (uint8) ((addr * 2) & 0xff);
+ addr_h = (uint8) (((addr * 2) >> 8) & 0xff);
+
+ /* set address */
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_ADDRH, addr_h);
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_ADDRL, addr_l);
+ /* do read */
+ if (srom_cmd_sb_pcmcia (osh, pcmregs, SROM_READ))
+ return 1;
+
+ /* read data */
+ data_h = SB_PCMCIA_READ (osh, pcmregs, SROM_DATAH);
+ data_l = SB_PCMCIA_READ (osh, pcmregs, SROM_DATAL);
+ *data = ((uint16) data_h << 8) | data_l;
+
+ return 0;
+}
+
+/* write a word to the PCMCIA srom over SB */
static int
-srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count)
+srom_write_sb_pcmcia (osl_t * osh, uint8 * pcmregs, uint16 addr, uint16 data)
{
- char eabuf[32];
- char *vp, *base;
- uint8 *cis, tup, tlen, sromrev = 1;
- int i, j;
- uint varsize;
- bool ag_init = FALSE;
- uint32 w32;
-
- ASSERT(vars);
- ASSERT(count);
-
- base = vp = MALLOC(osh, VARS_MAX);
- ASSERT(vp);
- if (!vp)
- return -2;
-
- while (ciscnt--) {
- cis = *pcis++;
- i = 0;
- do {
- tup = cis[i++];
- tlen = cis[i++];
- if ((i + tlen) >= CIS_SIZE)
- break;
-
- switch (tup) {
- case CISTPL_MANFID:
- vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
- vp++;
- vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
- vp++;
- break;
-
- case CISTPL_FUNCE:
- switch (cis[i]) {
- case LAN_NID:
- ASSERT(cis[i + 1] == 6);
- bcm_ether_ntoa((struct ether_addr *)&cis[i + 2], eabuf);
- vp += sprintf(vp, "il0macaddr=%s", eabuf);
- vp++;
- break;
- case 1: /* SDIO Extended Data */
- vp += sprintf(vp, "sdmaxblk=%d",
- (cis[i + 13] << 8) | cis[i + 12]);
- vp++;
- break;
- }
- break;
-
- case CISTPL_CFTABLE:
- vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
- vp++;
- break;
-
- case CISTPL_BRCM_HNBU:
- switch (cis[i]) {
- case HNBU_SROMREV:
- sromrev = cis[i + 1];
- break;
-
- case HNBU_CHIPID:
- vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) +
- cis[i + 1]);
- vp++;
- vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) +
- cis[i + 3]);
- vp++;
- if (tlen == 7) {
- vp += sprintf(vp, "chiprev=%d",
- (cis[i + 6] << 8) + cis[i + 5]);
- vp++;
- }
- break;
-
- case HNBU_BOARDREV:
- vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
- vp++;
- break;
-
- case HNBU_AA:
- vp += sprintf(vp, "aa2g=%d", cis[i + 1]);
- vp++;
- break;
-
- case HNBU_AG:
- vp += sprintf(vp, "ag0=%d", cis[i + 1]);
- vp++;
- ag_init = TRUE;
- break;
-
- case HNBU_CC:
- ASSERT(sromrev == 1);
- vp += sprintf(vp, "cc=%d", cis[i + 1]);
- vp++;
- break;
-
- case HNBU_PAPARMS:
- if (tlen == 2) {
- ASSERT(sromrev == 1);
- vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]);
- vp++;
- } else if (tlen >= 9) {
- if (tlen == 10) {
- ASSERT(sromrev == 2);
- vp += sprintf(vp, "opo=%d", cis[i + 9]);
- vp++;
- } else
- ASSERT(tlen == 9);
-
- for (j = 0; j < 3; j++) {
- vp += sprintf(vp, "pa0b%d=%d", j,
- (cis[i + (j * 2) + 2] << 8) +
- cis[i + (j * 2) + 1]);
- vp++;
- }
- vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
- vp++;
- vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]);
- vp++;
- } else
- ASSERT(tlen >= 9);
- break;
-
- case HNBU_OEM:
- ASSERT(sromrev == 1);
- vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
- cis[i + 1], cis[i + 2],
- cis[i + 3], cis[i + 4],
- cis[i + 5], cis[i + 6],
- cis[i + 7], cis[i + 8]);
- vp++;
- break;
-
- case HNBU_BOARDFLAGS:
- w32 = (cis[i + 2] << 8) + cis[i + 1];
- if (tlen == 5)
- w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16);
- vp += sprintf(vp, "boardflags=0x%x", w32);
- vp++;
- break;
-
- case HNBU_LEDS:
- if (cis[i + 1] != 0xff) {
- vp += sprintf(vp, "ledbh0=%d", cis[i + 1]);
- vp++;
- }
- if (cis[i + 2] != 0xff) {
- vp += sprintf(vp, "ledbh1=%d", cis[i + 2]);
- vp++;
- }
- if (cis[i + 3] != 0xff) {
- vp += sprintf(vp, "ledbh2=%d", cis[i + 3]);
- vp++;
- }
- if (cis[i + 4] != 0xff) {
- vp += sprintf(vp, "ledbh3=%d", cis[i + 4]);
- vp++;
- }
- break;
-
- case HNBU_CCODE:
- {
- char str[3];
- ASSERT(sromrev > 1);
- str[0] = cis[i + 1];
- str[1] = cis[i + 2];
- str[2] = 0;
- vp += sprintf(vp, "ccode=%s", str);
- vp++;
- vp += sprintf(vp, "cctl=0x%x", cis[i + 3]);
- vp++;
- break;
- }
-
- case HNBU_CCKPO:
- ASSERT(sromrev > 2);
- vp += sprintf(vp, "cckpo=0x%x",
- (cis[i + 2] << 8) | cis[i + 1]);
- vp++;
- break;
-
- case HNBU_OFDMPO:
- ASSERT(sromrev > 2);
- vp += sprintf(vp, "ofdmpo=0x%x",
- (cis[i + 4] << 24) |
- (cis[i + 3] << 16) |
- (cis[i + 2] << 8) |
- cis[i + 1]);
- vp++;
- break;
- }
- break;
+ uint8 addr_l, addr_h, data_l, data_h;
+ int rc;
- }
- i += tlen;
- } while (tup != 0xff);
+ addr_l = (uint8) ((addr * 2) & 0xff);
+ addr_h = (uint8) (((addr * 2) >> 8) & 0xff);
+
+ /* set address */
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_ADDRH, addr_h);
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_ADDRL, addr_l);
+
+ data_l = (uint8) (data & 0xff);
+ data_h = (uint8) ((data >> 8) & 0xff);
+
+ /* write data */
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_DATAH, data_h);
+ SB_PCMCIA_WRITE (osh, pcmregs, SROM_DATAL, data_l);
+
+ /* do write */
+ rc = srom_cmd_sb_pcmcia (osh, pcmregs, SROM_WRITE);
+ OSL_DELAY (20000);
+ return rc;
+}
+
+/*
+ * Read the srom for the pcmcia-srom over sb case.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+get_sb_pcmcia_srom (sb_t * sbh, osl_t * osh, uint8 * pcmregs,
+ uint boff, uint16 * srom, uint bsz)
+{
+ uint i, nw, woff, wsz;
+ int err = 0;
+
+ /* read must be at word boundary */
+ ASSERT ((boff & 1) == 0 && (bsz & 1) == 0);
+
+ /* read sprom size and validate the parms */
+ if ((nw = srom_size (sbh, osh)) == 0)
+ {
+ BS_ERROR (("get_sb_pcmcia_srom: sprom size unknown\n"));
+ err = -1;
+ goto out;
+ }
+ if (boff + bsz > 2 * nw)
+ {
+ BS_ERROR (("get_sb_pcmcia_srom: sprom size exceeded\n"));
+ err = -2;
+ goto out;
+ }
+
+ /* read in sprom contents */
+ for (woff = boff / 2, wsz = bsz / 2, i = 0;
+ woff < nw && i < wsz; woff++, i++)
+ {
+ if (srom_read_sb_pcmcia (osh, pcmregs, (uint16) woff, &srom[i]))
+ {
+ BS_ERROR (("get_sb_pcmcia_srom: sprom read failed\n"));
+ err = -3;
+ goto out;
}
+ }
- /* Set the srom version */
- vp += sprintf(vp, "sromrev=%d", sromrev);
- vp++;
+out:
+ return err;
+}
- /* if there is no antenna gain field, set default */
- if (ag_init == FALSE) {
- ASSERT(sromrev == 1);
- vp += sprintf(vp, "ag0=%d", 0xff);
- vp++;
+/*
+ * Write the srom for the pcmcia-srom over sb case.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+set_sb_pcmcia_srom (sb_t * sbh, osl_t * osh, uint8 * pcmregs,
+ uint boff, uint16 * srom, uint bsz)
+{
+ uint i, nw, woff, wsz;
+ uint16 word;
+ uint8 crc;
+ int err = 0;
+
+ /* write must be at word boundary */
+ ASSERT ((boff & 1) == 0 && (bsz & 1) == 0);
+
+ /* read sprom size and validate the parms */
+ if ((nw = srom_size (sbh, osh)) == 0)
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom size unknown\n"));
+ err = -1;
+ goto out;
+ }
+ if (boff + bsz > 2 * nw)
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom size exceeded\n"));
+ err = -2;
+ goto out;
+ }
+
+ /* enable write */
+ if (srom_cmd_sb_pcmcia (osh, pcmregs, SROM_WEN))
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom wen failed\n"));
+ err = -3;
+ goto out;
+ }
+
+ /* write buffer to sprom */
+ for (woff = boff / 2, wsz = bsz / 2, i = 0;
+ woff < nw && i < wsz; woff++, i++)
+ {
+ if (srom_write_sb_pcmcia (osh, pcmregs, (uint16) woff, srom[i]))
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom write failed\n"));
+ err = -4;
+ goto out;
+ }
+ }
+
+ /* fix crc */
+ crc = 0xff;
+ for (woff = 0; woff < nw; woff++)
+ {
+ if (srom_read_sb_pcmcia (osh, pcmregs, (uint16) woff, &word))
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom fix crc read failed\n"));
+ err = -5;
+ goto out;
}
+ word = htol16 (word);
+ crc = hndcrc8 ((uint8 *) & word, woff != nw - 1 ? 2 : 1, crc);
+ }
+ word = (~crc << 8) + (ltoh16 (word) & 0xff);
+ if (srom_write_sb_pcmcia (osh, pcmregs, (uint16) (woff - 1), word))
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom fix crc write failed\n"));
+ err = -6;
+ goto out;
+ }
+
+ /* disable write */
+ if (srom_cmd_sb_pcmcia (osh, pcmregs, SROM_WDS))
+ {
+ BS_ERROR (("set_sb_pcmcia_srom: sprom wds failed\n"));
+ err = -7;
+ goto out;
+ }
+
+out:
+ return err;
+}
+#endif /* def BCMUSBDEV */
- /* final nullbyte terminator */
- *vp++ = '\0';
- varsize = (uint)(vp - base);
-
- ASSERT((vp - base) < VARS_MAX);
-
- if (varsize == VARS_MAX) {
- *vars = base;
- } else {
- vp = MALLOC(osh, varsize);
- ASSERT(vp);
- if (vp)
- bcopy(base, vp, varsize);
- MFREE(osh, base, VARS_MAX);
- *vars = vp;
- if (!vp) {
- *count = 0;
- return -2;
+int
+srom_parsecis (osl_t * osh, uint8 * pcis[], uint ciscnt, char **vars,
+ uint * count)
+{
+ char eabuf[32];
+ char *base;
+ varbuf_t b;
+ uint8 *cis, tup, tlen, sromrev = 1;
+ int i, j;
+ uint varsize;
+ bool ag_init = FALSE;
+ uint32 w32;
+ uint funcid;
+ uint cisnum;
+ int32 boardnum = -1;
+
+ ASSERT (vars);
+ ASSERT (count);
+
+ base = MALLOC (osh, MAXSZ_NVRAM_VARS);
+ ASSERT (base);
+ if (!base)
+ return -2;
+
+ varbuf_init (&b, base, MAXSZ_NVRAM_VARS);
+
+ eabuf[0] = '\0';
+ for (cisnum = 0; cisnum < ciscnt; cisnum++)
+ {
+ cis = *pcis++;
+ i = 0;
+ funcid = 0;
+ do
+ {
+ tup = cis[i++];
+ tlen = cis[i++];
+ if ((i + tlen) >= CIS_SIZE)
+ break;
+
+ switch (tup)
+ {
+ case CISTPL_VERS_1:
+ /* assume the strings are good if the version field checks out */
+ if (((cis[i + 1] << 8) + cis[i]) >= 0x0008)
+ {
+ varbuf_append (&b, "manf=%s", &cis[i + 2]);
+ varbuf_append (&b, "productname=%s",
+ &cis[i + 3 + strlen ((char *) &cis[i + 2])]);
+ break;
}
+
+ case CISTPL_MANFID:
+ varbuf_append (&b, "manfid=0x%x", (cis[i + 1] << 8) + cis[i]);
+ varbuf_append (&b, "prodid=0x%x",
+ (cis[i + 3] << 8) + cis[i + 2]);
+ break;
+
+ case CISTPL_FUNCID:
+ funcid = cis[i];
+ break;
+
+ case CISTPL_FUNCE:
+ switch (funcid)
+ {
+ default:
+ /* set macaddr if HNBU_MACADDR not seen yet */
+ if (eabuf[0] == '\0' && cis[i] == LAN_NID)
+ {
+ ASSERT (cis[i + 1] == ETHER_ADDR_LEN);
+ bcm_ether_ntoa ((struct ether_addr *) &cis[i + 2],
+ eabuf);
+ }
+ /* set boardnum if HNBU_BOARDNUM not seen yet */
+ if (boardnum == -1)
+ boardnum = (cis[i + 6] << 8) + cis[i + 7];
+ break;
+ }
+ break;
+
+ case CISTPL_CFTABLE:
+ varbuf_append (&b, "regwindowsz=%d",
+ (cis[i + 7] << 8) | cis[i + 6]);
+ break;
+
+ case CISTPL_BRCM_HNBU:
+ switch (cis[i])
+ {
+ case HNBU_SROMREV:
+ sromrev = cis[i + 1];
+ varbuf_append (&b, "sromrev=%d", sromrev);
+ break;
+
+ case HNBU_CHIPID:
+ varbuf_append (&b, "vendid=0x%x", (cis[i + 2] << 8) +
+ cis[i + 1]);
+ varbuf_append (&b, "devid=0x%x", (cis[i + 4] << 8) +
+ cis[i + 3]);
+ if (tlen >= 7)
+ {
+ varbuf_append (&b, "chiprev=%d",
+ (cis[i + 6] << 8) + cis[i + 5]);
+ }
+ if (tlen >= 9)
+ {
+ varbuf_append (&b, "subvendid=0x%x",
+ (cis[i + 8] << 8) + cis[i + 7]);
+ }
+ if (tlen >= 11)
+ {
+ varbuf_append (&b, "subdevid=0x%x",
+ (cis[i + 10] << 8) + cis[i + 9]);
+ /* subdevid doubles for boardtype */
+ varbuf_append (&b, "boardtype=0x%x",
+ (cis[i + 10] << 8) + cis[i + 9]);
+ }
+ break;
+
+ case HNBU_BOARDREV:
+ varbuf_append (&b, "boardrev=0x%x", cis[i + 1]);
+ break;
+
+ case HNBU_AA:
+ varbuf_append (&b, "aa2g=%d", cis[i + 1]);
+ break;
+
+ case HNBU_AG:
+ varbuf_append (&b, "ag0=%d", cis[i + 1]);
+ ag_init = TRUE;
+ break;
+
+ case HNBU_ANT5G:
+ varbuf_append (&b, "aa5g=%d", cis[i + 1]);
+ varbuf_append (&b, "ag1=%d", cis[i + 2]);
+ break;
+
+ case HNBU_CC:
+ ASSERT (sromrev == 1);
+ varbuf_append (&b, "cc=%d", cis[i + 1]);
+ break;
+
+ case HNBU_PAPARMS:
+ if (tlen == 2)
+ {
+ ASSERT (sromrev == 1);
+ varbuf_append (&b, "pa0maxpwr=%d", cis[i + 1]);
+ }
+ else if (tlen >= 9)
+ {
+ if (tlen == 10)
+ {
+ ASSERT (sromrev >= 2);
+ varbuf_append (&b, "opo=%d", cis[i + 9]);
+ }
+ else
+ ASSERT (tlen == 9);
+
+ for (j = 0; j < 3; j++)
+ {
+ varbuf_append (&b, "pa0b%d=%d", j,
+ (cis[i + (j * 2) + 2] << 8) +
+ cis[i + (j * 2) + 1]);
+ }
+ varbuf_append (&b, "pa0itssit=%d", cis[i + 7]);
+ varbuf_append (&b, "pa0maxpwr=%d", cis[i + 8]);
+ }
+ else
+ ASSERT (tlen >= 9);
+ break;
+
+ case HNBU_PAPARMS5G:
+ ASSERT ((sromrev == 2) || (sromrev == 3));
+ for (j = 0; j < 3; j++)
+ {
+ varbuf_append (&b, "pa1b%d=%d", j,
+ (cis[i + (j * 2) + 2] << 8) +
+ cis[i + (j * 2) + 1]);
+ }
+ for (j = 3; j < 6; j++)
+ {
+ varbuf_append (&b, "pa1lob%d=%d", j - 3,
+ (cis[i + (j * 2) + 2] << 8) +
+ cis[i + (j * 2) + 1]);
+ }
+ for (j = 6; j < 9; j++)
+ {
+ varbuf_append (&b, "pa1hib%d=%d", j - 6,
+ (cis[i + (j * 2) + 2] << 8) +
+ cis[i + (j * 2) + 1]);
+ }
+ varbuf_append (&b, "pa1itssit=%d", cis[i + 19]);
+ varbuf_append (&b, "pa1maxpwr=%d", cis[i + 20]);
+ varbuf_append (&b, "pa1lomaxpwr=%d", cis[i + 21]);
+ varbuf_append (&b, "pa1himaxpwr=%d", cis[i + 22]);
+ break;
+
+ case HNBU_OEM:
+ ASSERT (sromrev == 1);
+ varbuf_append (&b, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
+ cis[i + 1], cis[i + 2],
+ cis[i + 3], cis[i + 4],
+ cis[i + 5], cis[i + 6],
+ cis[i + 7], cis[i + 8]);
+ break;
+
+ case HNBU_BOARDFLAGS:
+ w32 = (cis[i + 2] << 8) + cis[i + 1];
+ if (tlen == 5)
+ w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16);
+ varbuf_append (&b, "boardflags=0x%x", w32);
+ break;
+
+ case HNBU_LEDS:
+ if (cis[i + 1] != 0xff)
+ {
+ varbuf_append (&b, "ledbh0=%d", cis[i + 1]);
+ }
+ if (cis[i + 2] != 0xff)
+ {
+ varbuf_append (&b, "ledbh1=%d", cis[i + 2]);
+ }
+ if (cis[i + 3] != 0xff)
+ {
+ varbuf_append (&b, "ledbh2=%d", cis[i + 3]);
+ }
+ if (cis[i + 4] != 0xff)
+ {
+ varbuf_append (&b, "ledbh3=%d", cis[i + 4]);
+ }
+ break;
+
+ case HNBU_CCODE:
+ ASSERT (sromrev > 1);
+ if ((cis[i + 1] == 0) || (cis[i + 2] == 0))
+ varbuf_append (&b, "ccode=");
+ else
+ varbuf_append (&b, "ccode=%c%c", cis[i + 1], cis[i + 2]);
+ varbuf_append (&b, "cctl=0x%x", cis[i + 3]);
+ break;
+
+ case HNBU_CCKPO:
+ ASSERT (sromrev > 2);
+ varbuf_append (&b, "cckpo=0x%x",
+ (cis[i + 2] << 8) | cis[i + 1]);
+ break;
+
+ case HNBU_OFDMPO:
+ ASSERT (sromrev > 2);
+ varbuf_append (&b, "ofdmpo=0x%x",
+ (cis[i + 4] << 24) |
+ (cis[i + 3] << 16) |
+ (cis[i + 2] << 8) | cis[i + 1]);
+ break;
+
+ case HNBU_RDLID:
+ varbuf_append (&b, "rdlid=0x%x",
+ (cis[i + 2] << 8) | cis[i + 1]);
+ break;
+
+ case HNBU_RDLRNDIS:
+ varbuf_append (&b, "rdlrndis=%d", cis[i + 1]);
+ break;
+
+ case HNBU_RDLRWU:
+ varbuf_append (&b, "rdlrwu=%d", cis[i + 1]);
+ break;
+
+ case HNBU_RDLSN:
+ varbuf_append (&b, "rdlsn=%d",
+ (cis[i + 2] << 8) | cis[i + 1]);
+ break;
+
+ case HNBU_XTALFREQ:
+ varbuf_append (&b, "xtalfreq=%d",
+ (cis[i + 4] << 24) |
+ (cis[i + 3] << 16) |
+ (cis[i + 2] << 8) | cis[i + 1]);
+ break;
+
+ case HNBU_RSSISMBXA2G:
+ ASSERT (sromrev == 3);
+ varbuf_append (&b, "rssismf2g=%d", cis[i + 1] & 0xf);
+ varbuf_append (&b, "rssismc2g=%d", (cis[i + 1] >> 4) & 0xf);
+ varbuf_append (&b, "rssisav2g=%d", cis[i + 2] & 0x7);
+ varbuf_append (&b, "bxa2g=%d", (cis[i + 2] >> 3) & 0x3);
+ break;
+
+ case HNBU_RSSISMBXA5G:
+ ASSERT (sromrev == 3);
+ varbuf_append (&b, "rssismf5g=%d", cis[i + 1] & 0xf);
+ varbuf_append (&b, "rssismc5g=%d", (cis[i + 1] >> 4) & 0xf);
+ varbuf_append (&b, "rssisav5g=%d", cis[i + 2] & 0x7);
+ varbuf_append (&b, "bxa5g=%d", (cis[i + 2] >> 3) & 0x3);
+ break;
+
+ case HNBU_TRI2G:
+ ASSERT (sromrev == 3);
+ varbuf_append (&b, "tri2g=%d", cis[i + 1]);
+ break;
+
+ case HNBU_TRI5G:
+ ASSERT (sromrev == 3);
+ varbuf_append (&b, "tri5gl=%d", cis[i + 1]);
+ varbuf_append (&b, "tri5g=%d", cis[i + 2]);
+ varbuf_append (&b, "tri5gh=%d", cis[i + 3]);
+ break;
+
+ case HNBU_RXPO2G:
+ ASSERT (sromrev == 3);
+ varbuf_append (&b, "rxpo2g=%d", cis[i + 1]);
+ break;
+
+ case HNBU_RXPO5G:
+ ASSERT (sromrev == 3);
+ varbuf_append (&b, "rxpo5g=%d", cis[i + 1]);
+ break;
+
+ case HNBU_BOARDNUM:
+ boardnum = (cis[i + 2] << 8) + cis[i + 1];
+ break;
+
+ case HNBU_MACADDR:
+ bcm_ether_ntoa ((struct ether_addr *) &cis[i + 1], eabuf);
+ break;
+
+ case HNBU_BOARDTYPE:
+ varbuf_append (&b, "boardtype=0x%x",
+ (cis[i + 2] << 8) + cis[i + 1]);
+ break;
+
+#if defined(BCMCCISSR3)
+ case HNBU_SROM3SWRGN:
+ {
+ uint16 srom[35];
+ uint8 srev = cis[i + 1 + 70];
+ ASSERT (srev == 3);
+ /* make tuple value 16-bit aligned and parse it */
+ bcopy (&cis[i + 1], srom, sizeof (srom));
+ _initvars_srom_pci (srev, srom, SROM3_SWRGN_OFF, &b);
+ /* create extra variables */
+ varbuf_append (&b, "vendid=0x%x",
+ (cis[i + 1 + 73] << 8) + cis[i + 1 + 72]);
+ varbuf_append (&b, "devid=0x%x",
+ (cis[i + 1 + 75] << 8) + cis[i + 1 + 74]);
+ varbuf_append (&b, "xtalfreq=%d",
+ (cis[i + 1 + 77] << 8) + cis[i + 1 + 76]);
+ /* 2.4G antenna gain is included in SROM */
+ ag_init = TRUE;
+ /* Ethernet MAC address is included in SROM */
+ eabuf[0] = 0;
+ boardnum = -1;
+ break;
+ }
+#endif
+ }
+ break;
+ }
+ i += tlen;
}
- *count = varsize;
+ while (tup != CISTPL_END);
+ }
+
+ if (boardnum != -1)
+ {
+ varbuf_append (&b, "boardnum=%d", boardnum);
+ }
+
+ if (eabuf[0])
+ {
+ varbuf_append (&b, "macaddr=%s", eabuf);
+ }
+
+ /* if there is no antenna gain field, set default */
+ if (ag_init == FALSE)
+ {
+ varbuf_append (&b, "ag0=%d", 0xff);
+ }
+
+ /* final nullbyte terminator */
+ ASSERT (b.size >= 1);
+ *b.buf++ = '\0';
+ varsize = (uint) (b.buf - base);
+ ASSERT (varsize < MAXSZ_NVRAM_VARS);
+ if (varsize < MAXSZ_NVRAM_VARS)
+ {
+ char *new_buf;
+ new_buf = (char *) MALLOC (osh, varsize);
+ ASSERT (new_buf);
+ if (new_buf)
+ {
+ bcopy (base, new_buf, varsize);
+ MFREE (osh, base, MAXSZ_NVRAM_VARS);
+ base = new_buf;
+ }
+ }
+
+ *vars = base;
+ *count = varsize;
- return (0);
+ return (0);
}
/* set PCMCIA sprom command register */
static int
-sprom_cmd_pcmcia(osl_t *osh, uint8 cmd)
+sprom_cmd_pcmcia (osl_t * osh, uint8 cmd)
{
- uint8 status = 0;
- uint wait_cnt = 1000;
+ uint8 status = 0;
+ uint wait_cnt = 1000;
- /* write sprom command register */
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1);
+ /* write sprom command register */
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_CS, &cmd, 1);
- /* wait status */
- while (wait_cnt--) {
- OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1);
- if (status & SROM_DONE)
- return 0;
- }
+ /* wait status */
+ while (wait_cnt--)
+ {
+ OSL_PCMCIA_READ_ATTR (osh, SROM_CS, &status, 1);
+ if (status & SROM_DONE)
+ return 0;
+ }
- return 1;
+ return 1;
}
/* read a word from the PCMCIA srom */
static int
-sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data)
+sprom_read_pcmcia (osl_t * osh, uint16 addr, uint16 * data)
{
- uint8 addr_l, addr_h, data_l, data_h;
+ uint8 addr_l, addr_h, data_l, data_h;
- addr_l = (uint8)((addr * 2) & 0xff);
- addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
+ addr_l = (uint8) ((addr * 2) & 0xff);
+ addr_h = (uint8) (((addr * 2) >> 8) & 0xff);
- /* set address */
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
+ /* set address */
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_ADDRH, &addr_h, 1);
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_ADDRL, &addr_l, 1);
- /* do read */
- if (sprom_cmd_pcmcia(osh, SROM_READ))
- return 1;
+ /* do read */
+ if (sprom_cmd_pcmcia (osh, SROM_READ))
+ return 1;
- /* read data */
- data_h = data_l = 0;
- OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1);
- OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1);
+ /* read data */
+ data_h = data_l = 0;
+ OSL_PCMCIA_READ_ATTR (osh, SROM_DATAH, &data_h, 1);
+ OSL_PCMCIA_READ_ATTR (osh, SROM_DATAL, &data_l, 1);
- *data = (data_h << 8) | data_l;
- return 0;
+ *data = (data_h << 8) | data_l;
+ return 0;
}
/* write a word to the PCMCIA srom */
static int
-sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data)
+sprom_write_pcmcia (osl_t * osh, uint16 addr, uint16 data)
{
- uint8 addr_l, addr_h, data_l, data_h;
+ uint8 addr_l, addr_h, data_l, data_h;
- addr_l = (uint8)((addr * 2) & 0xff);
- addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
- data_l = (uint8)(data & 0xff);
- data_h = (uint8)((data >> 8) & 0xff);
+ addr_l = (uint8) ((addr * 2) & 0xff);
+ addr_h = (uint8) (((addr * 2) >> 8) & 0xff);
+ data_l = (uint8) (data & 0xff);
+ data_h = (uint8) ((data >> 8) & 0xff);
- /* set address */
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
+ /* set address */
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_ADDRH, &addr_h, 1);
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_ADDRL, &addr_l, 1);
- /* write data */
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1);
- OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1);
+ /* write data */
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_DATAH, &data_h, 1);
+ OSL_PCMCIA_WRITE_ATTR (osh, SROM_DATAL, &data_l, 1);
- /* do write */
- return sprom_cmd_pcmcia(osh, SROM_WRITE);
+ /* do write */
+ return sprom_cmd_pcmcia (osh, SROM_WRITE);
}
/*
@@ -511,25 +1050,43 @@ sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data)
* Return 0 on success, nonzero on error.
*/
static int
-sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc)
+sprom_read_pci (osl_t * osh, uint16 * sprom, uint wordoff, uint16 * buf,
+ uint nwords, bool check_crc)
{
- int err = 0;
- uint i;
-
- /* read the sprom */
- for (i = 0; i < nwords; i++)
- buf[i] = R_REG(osh, &sprom[wordoff + i]);
-
- if (check_crc) {
- /* fixup the endianness so crc8 will pass */
- htol16_buf(buf, nwords * 2);
- if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE)
- err = 1;
- /* now correct the endianness of the byte array */
- ltoh16_buf(buf, nwords * 2);
+ int err = 0;
+ uint i;
+
+ /* read the sprom */
+ for (i = 0; i < nwords; i++)
+ {
+#ifdef BCMQT
+ buf[i] = R_REG (osh, &sprom[wordoff + i]);
+#endif
+ buf[i] = R_REG (osh, &sprom[wordoff + i]);
+ }
+
+ if (check_crc)
+ {
+ if (buf[0] == 0xffff)
+ {
+ /* The hardware thinks that an srom that starts with 0xffff
+ * is blank, regardless of the rest of the content, so declare
+ * it bad.
+ */
+ BS_ERROR (("%s: buf[0] = 0x%x, returning bad-crc\n", __FUNCTION__,
+ buf[0]));
+ return 1;
}
- return err;
+ /* fixup the endianness so crc8 will pass */
+ htol16_buf (buf, nwords * 2);
+ if (hndcrc8 ((uint8 *) buf, nwords * 2, 0xff) != 0x9f)
+ err = 1;
+ /* now correct the endianness of the byte array */
+ ltoh16_buf (buf, nwords * 2);
+ }
+
+ return err;
}
/*
@@ -537,26 +1094,29 @@ sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords
* Return 0 on success, nonzero on error.
*/
static int
-initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count)
+BCMINITFN (initvars_table) (osl_t * osh, char *start, char *end, char **vars,
+ uint * count)
{
- int c = (int)(end - start);
-
- /* do it only when there is more than just the null string */
- if (c > 1) {
- char *vp = MALLOC(osh, c);
- ASSERT(vp);
- if (!vp)
- return BCME_NOMEM;
- bcopy(start, vp, c);
- *vars = vp;
- *count = c;
- }
- else {
- *vars = NULL;
- *count = 0;
- }
-
- return 0;
+ int c = (int) (end - start);
+
+ /* do it only when there is more than just the null string */
+ if (c > 1)
+ {
+ char *vp = MALLOC (osh, c);
+ ASSERT (vp);
+ if (!vp)
+ return BCME_NOMEM;
+ bcopy (start, vp, c);
+ *vars = vp;
+ *count = c;
+ }
+ else
+ {
+ *vars = NULL;
+ *count = 0;
+ }
+
+ return 0;
}
/*
@@ -565,617 +1125,763 @@ initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count)
* Return 0 on success, nonzero on error.
*/
static int
-initvars_flash(osl_t *osh, char **base, uint len, char *devpath)
+initvars_flash (sb_t * sbh, osl_t * osh, char **base, uint len)
{
- char *vp = *base;
- char *flash;
- int err;
- char *s;
- uint l, dl, copy_len;
-
- /* allocate memory and read in flash */
- if (!(flash = MALLOC(osh, NVRAM_SPACE)))
- return BCME_NOMEM;
- if ((err = nvram_getall(flash, NVRAM_SPACE)))
- goto exit;
-
- /* grab vars with the <devpath> prefix in name */
- dl = strlen(devpath);
- for (s = flash; s && *s; s += l + 1) {
- l = strlen(s);
-
- /* skip non-matching variable */
- if (strncmp(s, devpath, dl))
- continue;
-
- /* is there enough room to copy? */
- copy_len = l - dl + 1;
- if (len < copy_len) {
- err = BCME_BUFTOOSHORT;
- goto exit;
- }
-
- /* no prefix, just the name=value */
- strcpy(vp, &s[dl]);
- vp += copy_len;
- len -= copy_len;
+ char *vp = *base;
+ char *flash;
+ int err;
+ char *s;
+ uint l, dl, copy_len;
+ char devpath[SB_DEVPATH_BUFSZ];
+
+ /* allocate memory and read in flash */
+ if (!(flash = MALLOC (osh, NVRAM_SPACE)))
+ return BCME_NOMEM;
+ if ((err = nvram_getall (flash, NVRAM_SPACE)))
+ goto exit;
+
+ sb_devpath (sbh, devpath, sizeof (devpath));
+
+ /* grab vars with the <devpath> prefix in name */
+ dl = strlen (devpath);
+ for (s = flash; s && *s; s += l + 1)
+ {
+ l = strlen (s);
+
+ /* skip non-matching variable */
+ if (strncmp (s, devpath, dl))
+ continue;
+
+ /* is there enough room to copy? */
+ copy_len = l - dl + 1;
+ if (len < copy_len)
+ {
+ err = BCME_BUFTOOSHORT;
+ goto exit;
}
- /* add null string as terminator */
- if (len < 1) {
- err = BCME_BUFTOOSHORT;
- goto exit;
- }
- *vp++ = '\0';
+ /* no prefix, just the name=value */
+ strncpy (vp, &s[dl], copy_len);
+ vp += copy_len;
+ len -= copy_len;
+ }
+
+ /* add null string as terminator */
+ if (len < 1)
+ {
+ err = BCME_BUFTOOSHORT;
+ goto exit;
+ }
+ *vp++ = '\0';
- *base = vp;
+ *base = vp;
-exit: MFREE(osh, flash, NVRAM_SPACE);
- return err;
+exit:MFREE (osh, flash, NVRAM_SPACE);
+ return err;
}
+#if !defined(BCMUSBDEV) && !defined(BCMSDIODEV)
/*
* Initialize nonvolatile variable table from flash.
* Return 0 on success, nonzero on error.
*/
static int
-initvars_flash_sb(void *sbh, char **vars, uint *count)
+initvars_flash_sb (sb_t * sbh, char **vars, uint * count)
{
- osl_t *osh = sb_osh(sbh);
- char devpath[SB_DEVPATH_BUFSZ];
- char *vp, *base;
- int err;
+ osl_t *osh = sb_osh (sbh);
+ char *vp, *base;
+ int err;
- ASSERT(vars);
- ASSERT(count);
+ ASSERT (vars);
+ ASSERT (count);
- if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
- return err;
+ base = vp = MALLOC (osh, MAXSZ_NVRAM_VARS);
+ ASSERT (vp);
+ if (!vp)
+ return BCME_NOMEM;
- base = vp = MALLOC(osh, VARS_MAX);
- ASSERT(vp);
- if (!vp)
- return BCME_NOMEM;
+ if ((err = initvars_flash (sbh, osh, &vp, MAXSZ_NVRAM_VARS)) == 0)
+ err = initvars_table (osh, base, vp, vars, count);
- if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
- goto err;
+ MFREE (osh, base, MAXSZ_NVRAM_VARS);
- err = initvars_table(osh, base, vp, vars, count);
-
-err: MFREE(osh, base, VARS_MAX);
- return err;
+ return err;
}
+#endif /* !BCMUSBDEV && !BCMSDIODEV */
#ifdef WLTEST
char mfgsromvars[256];
char *defaultsromvars = "il0macaddr=00:11:22:33:44:51\0"
- "et0macaddr=00:11:22:33:44:52\0"
- "et1macaddr=00:11:22:33:44:53\0"
- "boardtype=0xffff\0"
- "boardrev=0x10\0"
- "boardflags=8\0"
- "sromrev=2\0"
- "aa2g=3";
-#define MFGSROM_DEFVARSLEN 147 /* default srom len */
+ "et0macaddr=00:11:22:33:44:52\0"
+ "et1macaddr=00:11:22:33:44:53\0"
+ "boardtype=0xffff\0"
+ "boardrev=0x10\0" "boardflags=8\0" "sromrev=2\0" "aa2g=3\0" "\0";
+#define MFGSROM_DEFVARSLEN 149 /* default srom len */
#endif /* WL_TEST */
/*
* Initialize nonvolatile variable table from sprom.
* Return 0 on success, nonzero on error.
*/
-static int
-initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count)
-{
- uint16 w, *b;
- uint8 sromrev = 0;
- struct ether_addr ea;
- char eabuf[32];
- uint32 w32;
- int woff, i;
- char *vp, *base;
- osl_t *osh = sb_osh(sbh);
- bool flash = FALSE;
- char name[SB_DEVPATH_BUFSZ+16], *value;
- char devpath[SB_DEVPATH_BUFSZ];
- int err;
-
- /*
- * Apply CRC over SROM content regardless SROM is present or not,
- * and use variable <devpath>sromrev's existance in flash to decide
- * if we should return an error when CRC fails or read SROM variables
- * from flash.
- */
- b = MALLOC(osh, SROM_MAX);
- ASSERT(b);
- if (!b)
- return -2;
-
- err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,
- 64, TRUE);
- if (b[SROM4_SIGN] == SROM4_SIGNATURE) {
- /* sromrev >= 4, read more */
- err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, SROM4_WORDS, TRUE);
- sromrev = b[SROM4_WORDS - 1] & 0xff;
- } else if (err == 0) {
- /* srom is good and is rev < 4 */
- /* top word of sprom contains version and crc8 */
- sromrev = b[63] & 0xff;
- /* bcm4401 sroms misprogrammed */
- if (sromrev == 0x10)
- sromrev = 1;
- }
-
- if (err) {
-#ifdef WLTEST
- BS_ERROR(("SROM Crc Error, so see if we could use a default\n"));
- w32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
- if (w32 & SPROM_OTPIN_USE) {
- BS_ERROR(("srom crc failed with OTP, use default vars....\n"));
- vp = base = mfgsromvars;
- if (sb_chip(sbh) == BCM4311_CHIP_ID) {
- BS_ERROR(("setting the devid to be 4311\n"));
- vp += sprintf(vp, "devid=0x4311");
- vp++;
- }
- bcopy(defaultsromvars, vp, MFGSROM_DEFVARSLEN);
- vp += MFGSROM_DEFVARSLEN;
- goto varsdone;
- } else {
- BS_ERROR(("srom crc failed with SPROM....\n"));
-#endif /* WLTEST */
- if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
- return err;
- sprintf(name, "%ssromrev", devpath);
- if (!(value = getvar(NULL, name)))
- return (-1);
- sromrev = (uint8)bcm_strtoul(value, NULL, 0);
- flash = TRUE;
-#ifdef WLTEST
- }
-#endif /* WLTEST */
- }
- /* srom version check */
- if (sromrev > 4)
- return (-2);
-
- ASSERT(vars);
- ASSERT(count);
-
- base = vp = MALLOC(osh, VARS_MAX);
- ASSERT(vp);
- if (!vp)
- return -2;
-
- /* read variables from flash */
- if (flash) {
- if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
- goto err;
- goto varsdone;
- }
-
- vp += sprintf(vp, "sromrev=%d", sromrev);
- vp++;
-
- if (sromrev >= 4) {
- uint path, pathbase;
- const uint pathbases[MAX_PATH] = {SROM4_PATH0, SROM4_PATH1,
- SROM4_PATH2, SROM4_PATH3};
-
- vp += sprintf(vp, "boardrev=%d", b[SROM4_BREV]);
- vp++;
-
- vp += sprintf(vp, "boardflags=%d", (b[SROM4_BFL1] << 16) | b[SROM4_BFL0]);
- vp++;
-
- vp += sprintf(vp, "boardflags2=%d", (b[SROM4_BFL3] << 16) | b[SROM4_BFL2]);
- vp++;
-
- /* The macaddr */
- ea.octet[0] = (b[SROM4_MACHI] >> 8) & 0xff;
- ea.octet[1] = b[SROM4_MACHI] & 0xff;
- ea.octet[2] = (b[SROM4_MACMID] >> 8) & 0xff;
- ea.octet[3] = b[SROM4_MACMID] & 0xff;
- ea.octet[4] = (b[SROM4_MACLO] >> 8) & 0xff;
- ea.octet[5] = b[SROM4_MACLO] & 0xff;
- bcm_ether_ntoa(&ea, eabuf);
- vp += sprintf(vp, "macaddr=%s", eabuf);
- vp++;
-
- w = b[SROM4_CCODE];
- if (w == 0)
- vp += sprintf(vp, "ccode=");
- else
- vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
- vp++;
- vp += sprintf(vp, "regrev=%d", b[SROM4_REGREV]);
- vp++;
-
- w = b[SROM4_LEDBH10];
- if ((w != 0) && (w != 0xffff)) {
- /* ledbh0 */
- vp += sprintf(vp, "ledbh0=%d", (w & 0xff));
- vp++;
-
- /* ledbh1 */
- vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff);
- vp++;
- }
- w = b[SROM4_LEDBH32];
- if ((w != 0) && (w != 0xffff)) {
- /* ledbh2 */
- vp += sprintf(vp, "ledbh2=%d", w & 0xff);
- vp++;
-
- /* ledbh3 */
- vp += sprintf(vp, "ledbh3=%d", (w >> 8) & 0xff);
- vp++;
- }
- /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
- if (w != 0xffff) {
- w = b[SROM4_LEDDC];
- w32 = ((uint32)((unsigned char)(w >> 8) & 0xff) << 24) | /* oncount */
- ((uint32)((unsigned char)(w & 0xff)) << 8); /* offcount */
- vp += sprintf(vp, "leddc=%d", w32);
- vp++;
- }
-
- w = b[SROM4_AA];
- vp += sprintf(vp, "aa2g=%d", w & SROM4_AA2G_MASK);
- vp++;
- vp += sprintf(vp, "aa5g=%d", w >> SROM4_AA5G_SHIFT);
- vp++;
-
- w = b[SROM4_AG10];
- vp += sprintf(vp, "ag0=%d", w & 0xff);
- vp++;
- vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
- vp++;
- w = b[SROM4_AG32];
- vp += sprintf(vp, "ag2=%d", w & 0xff);
- vp++;
- vp += sprintf(vp, "ag3=%d", (w >> 8) & 0xff);
- vp++;
-
- /* Fixed power indices when power control is disabled */
- for (i = 0; i < 2; i++) {
- w = b[SROM4_TXPID2G + i];
- vp += sprintf(vp, "txpid2ga%d=%d", 2 * i, w & 0xff);
- vp++;
- vp += sprintf(vp, "txpid2ga%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
- vp++;
- w = b[SROM4_TXPID5G + i];
- vp += sprintf(vp, "txpid5ga%d=%d", 2 * i, w & 0xff);
- vp++;
- vp += sprintf(vp, "txpid5ga%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
- vp++;
- w = b[SROM4_TXPID5GL + i];
- vp += sprintf(vp, "txpid5gla%d=%d", 2 * i, w & 0xff);
- vp++;
- vp += sprintf(vp, "txpid5gla%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
- vp++;
- w = b[SROM4_TXPID5GH + i];
- vp += sprintf(vp, "txpid5gha%d=%d", 2 * i, w & 0xff);
- vp++;
- vp += sprintf(vp, "txpid5gha%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
- vp++;
- }
+typedef struct
+{
+ const char *name;
+ uint32 revmask;
+ uint32 flags;
+ uint16 off;
+ uint16 mask;
+} sromvar_t;
+
+#define SRFL_MORE 1 /* value continues as described by the next entry */
+#define SRFL_NOFFS 2 /* value bits can't be all one's */
+#define SRFL_PRHEX 4 /* value is in hexdecimal format */
+#define SRFL_PRSIGN 8 /* value is in signed decimal format */
+#define SRFL_CCODE 0x10 /* value is in country code format */
+#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
+#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
+
+/* Assumptions:
+ * - Ethernet address spins across 3 consective words
+ *
+ * Table rules:
+ * - Add multiple entries next to each other if a value spins across multiple words
+ * (even multiple fields in the same word) with each entry except the last having
+ * it's SRFL_MORE bit set.
+ * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
+ * bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
+ * - The last entry's name field must be NULL to indicate the end of the table. Other
+ * entries must have non-NULL name.
+ */
- /* Per path variables */
- for (path = 0; path < MAX_PATH; path++) {
- pathbase = pathbases[path];
- w = b[pathbase + SROM4_2G_ITT_MAXP];
- vp += sprintf(vp, "itt2ga%d=%d", path, w >> B2G_ITT_SHIFT);
- vp++;
- vp += sprintf(vp, "maxp2ga%d=%d", path, w & B2G_MAXP_MASK);
- vp++;
-
- for (i = 0; i < 4; i++) {
- vp += sprintf(vp, "pa2gw%da%d=%d", i, path,
- b[pathbase + SROM4_2G_PA + i]);
- vp++;
- }
+static const sromvar_t pci_sromvars[] = {
+ {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
+ {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
+ {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
+ {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
+ {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+ {"", 0, 0, SROM_BFL2, 0xffff},
+ {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+ {"", 0, 0, SROM3_BFL2, 0xffff},
+ {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
+ {"", 0, 0, SROM4_BFL1, 0xffff},
+ {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
+ {"", 0, 0, SROM5_BFL1, 0xffff},
+ {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
+ {"", 0, 0, SROM8_BFL1, 0xffff},
+ {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
+ {"", 0, 0, SROM4_BFL3, 0xffff},
+ {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
+ {"", 0, 0, SROM5_BFL3, 0xffff},
+ {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
+ {"", 0, 0, SROM8_BFL3, 0xffff},
+ {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
+ {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
+ {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
+ {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
+ {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
+ {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
+ {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
+ {"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
+ {"regrev", 0x00000010, 0, SROM4_REGREV, 0xff},
+ {"regrev", 0x000000e0, 0, SROM5_REGREV, 0xff},
+ {"regrev", 0xffffff00, 0, SROM8_REGREV, 0xff},
+ {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff},
+ {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
+ {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff},
+ {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
+ {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff},
+ {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
+ {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff},
+ {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
+ {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff},
+ {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
+ {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff},
+ {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
+ {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff},
+ {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
+ {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff},
+ {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
+ {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
+ {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
+ {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
+ {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0xff},
+ {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff},
+ {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
+ {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
+ {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
+ {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
+ {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff},
+ {"opo", 0x0000000c, 0, SROM_OPO, 0xff},
+ {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0xff},
+ {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
+ {"aa2g", 0x000000f0, 0, SROM4_AA, 0xff},
+ {"aa2g", 0xffffff00, 0, SROM8_AA, 0xff},
+ {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
+ {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
+ {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
+ {"ag0", 0x0000000e, 0, SROM_AG10, 0xff},
+ {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
+ {"ag0", 0x000000f0, 0, SROM4_AG10, 0xff},
+ {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
+ {"ag2", 0x000000f0, 0, SROM4_AG32, 0xff},
+ {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
+ {"ag0", 0xffffff00, 0, SROM8_AG10, 0xff},
+ {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
+ {"ag2", 0xffffff00, 0, SROM8_AG32, 0xff},
+ {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
+ {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
+ {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
+ {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
+ {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
+ {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
+ {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
+ {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
+ {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
+ {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
+ {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
+ {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
+ {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
+ {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff},
+ {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
+ {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
+ {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
+ {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
+ {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
+ {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
+ {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
+ {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
+ {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
+ {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
+ {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff},
+ {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
+ {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff},
+ {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
+ {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
+ {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
+ {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
+ {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
+ {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
+ {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
+ {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
+ {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
+ {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
+ {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
+ {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
+ {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
+ {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
+ {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
+ {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
+ {"tri2g", 0x00000008, 0, SROM_TRI52G, 0xff},
+ {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
+ {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0xff},
+ {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
+ {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0xff},
+ {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
+ {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0xff},
+ {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
+ {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff},
+ {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
+ {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff},
+ {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
+ {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
+ {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
+ {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
+ {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
+ {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
+ {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
+ {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0xff},
+ {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
+ {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff},
+ {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
+ {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0xff},
+ {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
+ {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff},
+ {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
+ {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0xff},
+ {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
+ {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff},
+ {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
+ {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0xff},
+ {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
+ {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff},
+ {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
+ {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
+ {"cck2gpo", 0xffffff00, 0, SROM8_2G_CCKPO, 0xffff},
+ {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
+ {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
+ {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
+ {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
+ {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
+ {"ofdm2gpo", 0xffffff00, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
+ {"ofdm5gpo", 0xffffff00, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
+ {"ofdm5glpo", 0xffffff00, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
+ {"ofdm5ghpo", 0xffffff00, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
+ {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
+ {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
+ {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
+ {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
+ {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
+ {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
+ {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
+ {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
+ {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
+ {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
+ {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
+ {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
+ {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
+ {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
+ {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
+ {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
+ {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
+ {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
+ {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
+ {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
+ {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
+ {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
+ {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
+ {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
+ {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
+ {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
+ {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
+ {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
+ {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
+ {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
+ {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
+ {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
+ {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
+ {"mcs2gpo0", 0xffffff00, 0, SROM8_2G_MCSPO, 0xffff},
+ {"mcs2gpo1", 0xffffff00, 0, SROM8_2G_MCSPO + 1, 0xffff},
+ {"mcs2gpo2", 0xffffff00, 0, SROM8_2G_MCSPO + 2, 0xffff},
+ {"mcs2gpo3", 0xffffff00, 0, SROM8_2G_MCSPO + 3, 0xffff},
+ {"mcs2gpo4", 0xffffff00, 0, SROM8_2G_MCSPO + 4, 0xffff},
+ {"mcs2gpo5", 0xffffff00, 0, SROM8_2G_MCSPO + 5, 0xffff},
+ {"mcs2gpo6", 0xffffff00, 0, SROM8_2G_MCSPO + 6, 0xffff},
+ {"mcs2gpo7", 0xffffff00, 0, SROM8_2G_MCSPO + 7, 0xffff},
+ {"mcs5gpo0", 0xffffff00, 0, SROM8_5G_MCSPO, 0xffff},
+ {"mcs5gpo1", 0xffffff00, 0, SROM8_5G_MCSPO + 1, 0xffff},
+ {"mcs5gpo2", 0xffffff00, 0, SROM8_5G_MCSPO + 2, 0xffff},
+ {"mcs5gpo3", 0xffffff00, 0, SROM8_5G_MCSPO + 3, 0xffff},
+ {"mcs5gpo4", 0xffffff00, 0, SROM8_5G_MCSPO + 4, 0xffff},
+ {"mcs5gpo5", 0xffffff00, 0, SROM8_5G_MCSPO + 5, 0xffff},
+ {"mcs5gpo6", 0xffffff00, 0, SROM8_5G_MCSPO + 6, 0xffff},
+ {"mcs5gpo7", 0xffffff00, 0, SROM8_5G_MCSPO + 7, 0xffff},
+ {"mcs5glpo0", 0xffffff00, 0, SROM8_5GL_MCSPO, 0xffff},
+ {"mcs5glpo1", 0xffffff00, 0, SROM8_5GL_MCSPO + 1, 0xffff},
+ {"mcs5glpo2", 0xffffff00, 0, SROM8_5GL_MCSPO + 2, 0xffff},
+ {"mcs5glpo3", 0xffffff00, 0, SROM8_5GL_MCSPO + 3, 0xffff},
+ {"mcs5glpo4", 0xffffff00, 0, SROM8_5GL_MCSPO + 4, 0xffff},
+ {"mcs5glpo5", 0xffffff00, 0, SROM8_5GL_MCSPO + 5, 0xffff},
+ {"mcs5glpo6", 0xffffff00, 0, SROM8_5GL_MCSPO + 6, 0xffff},
+ {"mcs5glpo7", 0xffffff00, 0, SROM8_5GL_MCSPO + 7, 0xffff},
+ {"mcs5ghpo0", 0xffffff00, 0, SROM8_5GH_MCSPO, 0xffff},
+ {"mcs5ghpo1", 0xffffff00, 0, SROM8_5GH_MCSPO + 1, 0xffff},
+ {"mcs5ghpo2", 0xffffff00, 0, SROM8_5GH_MCSPO + 2, 0xffff},
+ {"mcs5ghpo3", 0xffffff00, 0, SROM8_5GH_MCSPO + 3, 0xffff},
+ {"mcs5ghpo4", 0xffffff00, 0, SROM8_5GH_MCSPO + 4, 0xffff},
+ {"mcs5ghpo5", 0xffffff00, 0, SROM8_5GH_MCSPO + 5, 0xffff},
+ {"mcs5ghpo6", 0xffffff00, 0, SROM8_5GH_MCSPO + 6, 0xffff},
+ {"mcs5ghpo7", 0xffffff00, 0, SROM8_5GH_MCSPO + 7, 0xffff},
+ {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
+ {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
+ {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
+ {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
+ {"cddpo", 0xffffff00, 0, SROM8_CDDPO, 0xffff},
+ {"stbcpo", 0xffffff00, 0, SROM8_STBCPO, 0xffff},
+ {"bw40po", 0xffffff00, 0, SROM8_BW40PO, 0xffff},
+ {"bwduppo", 0xffffff00, 0, SROM8_BWDUPPO, 0xffff},
+ {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
+ {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
+ {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
+ {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
+ {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
+ {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
+ {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
+ {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
+ {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
+ {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
+ {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
+ {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
+ {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
+ {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
+ {NULL, 0, 0, 0, 0}
+};
+
+static const sromvar_t perpath_pci_sromvars[] = {
+ {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff},
+ {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
+ {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
+ {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
+ {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
+ {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
+ {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
+ {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff},
+ {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff},
+ {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
+ {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
+ {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
+ {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
+ {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
+ {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
+ {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
+ {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
+ {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
+ {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
+ {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
+ {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
+ {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
+ {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff},
+ {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
+ {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
+ {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
+ {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
+ {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
+ {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff},
+ {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff},
+ {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
+ {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
+ {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
+ {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
+ {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
+ {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
+ {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
+ {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
+ {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
+ {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
+ {NULL, 0, 0, 0, 0}
+};
+
+/* Parse SROM and create name=value pairs. 'srom' points to
+ * the SROM word array. 'off' specifies the offset of the
+ * first word 'srom' points to, which should be either 0 or
+ * SROM3_SWRG_OFF (full SROM or software region).
+ */
- w = b[pathbase + SROM4_5G_ITT_MAXP];
- vp += sprintf(vp, "itt5ga%d=%d", path, w >> B5G_ITT_SHIFT);
- vp++;
- vp += sprintf(vp, "maxp5ga%d=%d", path, w & B5G_MAXP_MASK);
- vp++;
-
- w = b[pathbase + SROM4_5GLH_MAXP];
- vp += sprintf(vp, "maxp5lga%d=%d", path, w >> B5GL_MAXP_SHIFT);
- vp++;
- vp += sprintf(vp, "maxp5gha%d=%d", path, w & B5GH_MAXP_MASK);
- vp++;
-
- for (i = 0; i < 4; i++) {
- vp += sprintf(vp, "pa5gw%da%d=%d", i, path,
- b[pathbase + SROM4_5G_PA + i]);
- vp++;
- vp += sprintf(vp, "pa5glw%da%d=%d", i, path,
- b[pathbase + SROM4_5GL_PA + i]);
- vp++;
- vp += sprintf(vp, "pa5hgw%da%d=%d", i, path,
- b[pathbase + SROM4_5GH_PA + i]);
- vp++;
- }
- }
+static uint
+mask_shift (uint16 mask)
+{
+ uint i;
+ for (i = 0; i < (sizeof (mask) << 3); i++)
+ {
+ if (mask & (1 << i))
+ return i;
+ }
+ ASSERT (mask);
+ return 0;
+}
- vp += sprintf(vp, "cck2gpo=%d", b[SROM4_2G_CCKPO]);
- vp++;
-
- w32 = ((uint32)b[SROM4_2G_OFDMPO + 1] << 16) | b[SROM4_2G_OFDMPO];
- vp += sprintf(vp, "ofdm2gpo=%d", w32);
- vp++;
-
- w32 = ((uint32)b[SROM4_5G_OFDMPO + 1] << 16) | b[SROM4_5G_OFDMPO];
- vp += sprintf(vp, "ofdm5gpo=%d", w32);
- vp++;
-
- w32 = ((uint32)b[SROM4_5GL_OFDMPO + 1] << 16) | b[SROM4_5GL_OFDMPO];
- vp += sprintf(vp, "ofdm5glpo=%d", w32);
- vp++;
-
- w32 = ((uint32)b[SROM4_5GH_OFDMPO + 1] << 16) | b[SROM4_5GH_OFDMPO];
- vp += sprintf(vp, "ofdm5ghpo=%d", w32);
- vp++;
-
- for (i = 0; i < 8; i++) {
- vp += sprintf(vp, "mcs2gpo%d=%d", i, b[SROM4_2G_MCSPO]);
- vp++;
- vp += sprintf(vp, "mcs5gpo%d=%d", i, b[SROM4_5G_MCSPO]);
- vp++;
- vp += sprintf(vp, "mcs5glpo%d=%d", i, b[SROM4_5GL_MCSPO]);
- vp++;
- vp += sprintf(vp, "mcs5ghpo%d=%d", i, b[SROM4_5GH_MCSPO]);
- vp++;
- }
+static uint
+mask_width (uint16 mask)
+{
+ int i;
+ for (i = (sizeof (mask) << 3) - 1; i >= 0; i--)
+ {
+ if (mask & (1 << i))
+ return (uint) (i - mask_shift (mask) + 1);
+ }
+ ASSERT (mask);
+ return 0;
+}
- vp += sprintf(vp, "ccdpo%d=%d", i, b[SROM4_CCDPO]);
- vp++;
- vp += sprintf(vp, "stbcpo%d=%d", i, b[SROM4_STBCPO]);
- vp++;
- vp += sprintf(vp, "bw40po%d=%d", i, b[SROM4_BW40PO]);
- vp++;
- vp += sprintf(vp, "bwduppo%d=%d", i, b[SROM4_BWDUPPO]);
- vp++;
+#ifdef BCMDBG_ASSERT
+static bool
+mask_valid (uint16 mask)
+{
+ uint shift = mask_shift (mask);
+ uint width = mask_width (mask);
+ return mask == ((~0 << shift) & ~(~0 << (shift + width)));
+}
+#endif
- goto done;
+static void
+_initvars_srom_pci (uint8 sromrev, uint16 * srom, uint off, varbuf_t * b)
+{
+ uint16 w;
+ uint32 val;
+ const sromvar_t *srv;
+ uint width;
+ uint flags;
+ uint32 sr = (1 << sromrev);
+
+ varbuf_append (b, "sromrev=%d", sromrev);
+
+ for (srv = pci_sromvars; srv->name != NULL; srv++)
+ {
+ const char *name;
+
+ if ((srv->revmask & sr) == 0)
+ continue;
+
+ if (srv->off < off)
+ continue;
+
+ flags = srv->flags;
+ name = srv->name;
+
+ if (flags & SRFL_ETHADDR)
+ {
+ char eabuf[ETHER_ADDR_STR_LEN];
+ struct ether_addr ea;
+
+ ea.octet[0] = (srom[srv->off - off] >> 8) & 0xff;
+ ea.octet[1] = srom[srv->off - off] & 0xff;
+ ea.octet[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
+ ea.octet[3] = srom[srv->off + 1 - off] & 0xff;
+ ea.octet[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
+ ea.octet[5] = srom[srv->off + 2 - off] & 0xff;
+ bcm_ether_ntoa (&ea, eabuf);
+
+ varbuf_append (b, "%s=%s", name, eabuf);
}
- if (sromrev >= 3) {
- /* New section takes over the 3th hardware function space */
-
- /* Words 22+23 are 11a (mid) ofdm power offsets */
- w32 = ((uint32)b[23] << 16) | b[22];
- vp += sprintf(vp, "ofdmapo=%d", w32);
- vp++;
-
- /* Words 24+25 are 11a (low) ofdm power offsets */
- w32 = ((uint32)b[25] << 16) | b[24];
- vp += sprintf(vp, "ofdmalpo=%d", w32);
- vp++;
-
- /* Words 26+27 are 11a (high) ofdm power offsets */
- w32 = ((uint32)b[27] << 16) | b[26];
- vp += sprintf(vp, "ofdmahpo=%d", w32);
- vp++;
-
- /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
- w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xff) << 24) | /* oncount */
- ((uint32)((unsigned char)(b[21] & 0xff)) << 8); /* offcount */
- vp += sprintf(vp, "leddc=%d", w32);
-
- vp++;
+ else
+ {
+ ASSERT (mask_valid (srv->mask));
+ ASSERT (mask_width (srv->mask));
+
+ w = srom[srv->off - off];
+ val = (w & srv->mask) >> mask_shift (srv->mask);
+ width = mask_width (srv->mask);
+
+ while (srv->flags & SRFL_MORE)
+ {
+ srv++;
+ ASSERT (srv->name);
+
+ if (srv->off == 0 || srv->off < off)
+ continue;
+
+ ASSERT (mask_valid (srv->mask));
+ ASSERT (mask_width (srv->mask));
+
+ w = srom[srv->off - off];
+ val += ((w & srv->mask) >> mask_shift (srv->mask)) << width;
+ width += mask_width (srv->mask);
+ }
+
+ if ((flags & SRFL_NOFFS) && ((int) val == (1 << width) - 1))
+ continue;
+
+ if (flags & SRFL_CCODE)
+ {
+ if (val == 0)
+ varbuf_append (b, "ccode=");
+ else
+ varbuf_append (b, "ccode=%c%c", (val >> 8), (val & 0xff));
+ }
+ /* LED Powersave duty cycle has to be scaled:
+ *(oncount >> 24) (offcount >> 8)
+ */
+ else if (flags & SRFL_LEDDC)
+ {
+ uint32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */
+ (((val & 0xff)) << 8); /* offcount */
+ varbuf_append (b, "leddc=%d", w32);
+ }
+ else if (flags & SRFL_PRHEX)
+ varbuf_append (b, "%s=0x%x", name, val);
+ else if ((flags & SRFL_PRSIGN) && (val & (1 << (width - 1))))
+ varbuf_append (b, "%s=%d", name, (int) (val | (~0 << width)));
+ else
+ varbuf_append (b, "%s=%u", name, val);
}
+ }
- if (sromrev >= 2) {
- /* New section takes over the 4th hardware function space */
-
- /* Word 29 is max power 11a high/low */
- w = b[29];
- vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff);
- vp++;
- vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff);
- vp++;
-
- /* Words 30-32 set the 11alow pa settings,
- * 33-35 are the 11ahigh ones.
- */
- for (i = 0; i < 3; i++) {
- vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]);
- vp++;
- vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]);
- vp++;
- }
- w = b[59];
- if (w == 0)
- vp += sprintf(vp, "ccode=");
- else
- vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
- vp++;
+ if (sromrev >= 4)
+ {
+ /* Do per-path variables */
+ uint p, pb, psz;
+ if (sromrev >= 8)
+ {
+ pb = SROM8_PATH0;
+ psz = SROM8_PATH1 - SROM8_PATH0;
}
-
- /* parameter section of sprom starts at byte offset 72 */
- woff = 72/2;
-
- /* first 6 bytes are il0macaddr */
- ea.octet[0] = (b[woff] >> 8) & 0xff;
- ea.octet[1] = b[woff] & 0xff;
- ea.octet[2] = (b[woff+1] >> 8) & 0xff;
- ea.octet[3] = b[woff+1] & 0xff;
- ea.octet[4] = (b[woff+2] >> 8) & 0xff;
- ea.octet[5] = b[woff+2] & 0xff;
- woff += 3;
- bcm_ether_ntoa(&ea, eabuf);
- vp += sprintf(vp, "il0macaddr=%s", eabuf);
- vp++;
-
- /* next 6 bytes are et0macaddr */
- ea.octet[0] = (b[woff] >> 8) & 0xff;
- ea.octet[1] = b[woff] & 0xff;
- ea.octet[2] = (b[woff+1] >> 8) & 0xff;
- ea.octet[3] = b[woff+1] & 0xff;
- ea.octet[4] = (b[woff+2] >> 8) & 0xff;
- ea.octet[5] = b[woff+2] & 0xff;
- woff += 3;
- bcm_ether_ntoa(&ea, eabuf);
- vp += sprintf(vp, "et0macaddr=%s", eabuf);
- vp++;
-
- /* next 6 bytes are et1macaddr */
- ea.octet[0] = (b[woff] >> 8) & 0xff;
- ea.octet[1] = b[woff] & 0xff;
- ea.octet[2] = (b[woff+1] >> 8) & 0xff;
- ea.octet[3] = b[woff+1] & 0xff;
- ea.octet[4] = (b[woff+2] >> 8) & 0xff;
- ea.octet[5] = b[woff+2] & 0xff;
- woff += 3;
- bcm_ether_ntoa(&ea, eabuf);
- vp += sprintf(vp, "et1macaddr=%s", eabuf);
- vp++;
-
- /*
- * Enet phy settings one or two singles or a dual
- * Bits 4-0 : MII address for enet0 (0x1f for not there)
- * Bits 9-5 : MII address for enet1 (0x1f for not there)
- * Bit 14 : Mdio for enet0
- * Bit 15 : Mdio for enet1
- */
- w = b[woff];
- vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f));
- vp++;
- vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f));
- vp++;
- vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1));
- vp++;
- vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1));
- vp++;
-
- /* Word 46 has board rev, antennas 0/1 & Country code/control */
- w = b[46];
- vp += sprintf(vp, "boardrev=%d", w & 0xff);
- vp++;
-
- if (sromrev > 1)
- vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf);
- else
- vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf);
- vp++;
-
- vp += sprintf(vp, "aa2g=%d", (w >> 12) & 0x3);
- vp++;
-
- vp += sprintf(vp, "aa5g=%d", (w >> 14) & 0x3);
- vp++;
-
- /* Words 47-49 set the (wl) pa settings */
- woff = 47;
-
- for (i = 0; i < 3; i++) {
- vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]);
- vp++;
- vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]);
- vp++;
+ else
+ {
+ pb = SROM4_PATH0;
+ psz = SROM4_PATH1 - SROM4_PATH0;
}
- /*
- * Words 50-51 set the customer-configured wl led behavior.
- * 8 bits/gpio pin. High bit: activehi=0, activelo=1;
- * LED behavior values defined in wlioctl.h .
- */
- w = b[50];
- if ((w != 0) && (w != 0xffff)) {
- /* ledbh0 */
- vp += sprintf(vp, "ledbh0=%d", (w & 0xff));
- vp++;
-
- /* ledbh1 */
- vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff);
- vp++;
- }
- w = b[51];
- if ((w != 0) && (w != 0xffff)) {
- /* ledbh2 */
- vp += sprintf(vp, "ledbh2=%d", w & 0xff);
- vp++;
-
- /* ledbh */
- vp += sprintf(vp, "ledbh3=%d", (w >> 8) & 0xff);
- vp++;
+ for (p = 0; p < MAX_PATH; p++)
+ {
+ for (srv = perpath_pci_sromvars; srv->name != NULL; srv++)
+ {
+ if ((srv->revmask & sr) == 0)
+ continue;
+
+ if (pb + srv->off < off)
+ continue;
+
+ w = srom[pb + srv->off - off];
+ ASSERT (mask_valid (srv->mask));
+ val = (w & srv->mask) >> mask_shift (srv->mask);
+ width = mask_width (srv->mask);
+
+ /* Cheating: no per-path var is more than 1 word */
+
+ if ((srv->flags & SRFL_NOFFS)
+ && ((int) val == (1 << width) - 1))
+ continue;
+
+ if (srv->flags & SRFL_PRHEX)
+ varbuf_append (b, "%s%d=0x%x", srv->name, p, val);
+ else
+ varbuf_append (b, "%s%d=%d", srv->name, p, val);
+ }
+ pb += psz;
}
+ }
+}
- /* Word 52 is max power 0/1 */
- w = b[52];
- vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff);
- vp++;
- vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff);
- vp++;
-
- /* Word 56 is idle tssi target 0/1 */
- w = b[56];
- vp += sprintf(vp, "pa0itssit=%d", w & 0xff);
- vp++;
- vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff);
- vp++;
-
- /* Word 57 is boardflags, if not programmed make it zero */
- w32 = (uint32)b[57];
- if (w32 == 0xffff) w32 = 0;
- if (sromrev > 1) {
- /* Word 28 is the high bits of boardflags */
- w32 |= (uint32)b[28] << 16;
+static int
+initvars_srom_pci (sb_t * sbh, void *curmap, char **vars, uint * count)
+{
+ uint16 *srom;
+ uint8 sromrev = 0;
+ uint32 sr;
+ varbuf_t b;
+ char *vp, *base = NULL;
+ osl_t *osh = sb_osh (sbh);
+ bool flash = FALSE;
+ char *value;
+ int err;
+
+ /*
+ * Apply CRC over SROM content regardless SROM is present or not,
+ * and use variable <devpath>sromrev's existance in flash to decide
+ * if we should return an error when CRC fails or read SROM variables
+ * from flash.
+ */
+ srom = MALLOC (osh, SROM_MAX);
+ ASSERT (srom);
+ if (!srom)
+ return -2;
+
+ err =
+ sprom_read_pci (osh, (void *) ((int8 *) curmap + PCI_BAR0_SPROM_OFFSET),
+ 0, srom, SROM_WORDS, TRUE);
+
+ if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
+ ((sbh->buscoretype == SB_PCIE) && (sbh->buscorerev >= 6)))
+ {
+ /* sromrev >= 4, read more */
+ err =
+ sprom_read_pci (osh,
+ (void *) ((int8 *) curmap + PCI_BAR0_SPROM_OFFSET), 0,
+ srom, SROM4_WORDS, TRUE);
+ sromrev = srom[SROM4_CRCREV] & 0xff;
+ }
+ else if (err == 0)
+ {
+ /* srom is good and is rev < 4 */
+ /* top word of sprom contains version and crc8 */
+ sromrev = srom[SROM_CRCREV] & 0xff;
+ /* bcm4401 sroms misprogrammed */
+ if (sromrev == 0x10)
+ sromrev = 1;
+ }
+
+ if (err)
+ {
+#ifdef WLTEST
+ uint32 val;
+
+ BS_ERROR (("SROM Crc Error, so see if we could use a default\n"));
+ val = OSL_PCI_READ_CONFIG (osh, PCI_SPROM_CONTROL, sizeof (uint32));
+ if (val & SPROM_OTPIN_USE)
+ {
+ BS_ERROR (("srom crc failed with OTP, use default vars....\n"));
+ vp = base = mfgsromvars;
+ if (sb_chip (sbh) == BCM4311_CHIP_ID)
+ {
+ const char *devid = "devid=0x4311";
+ const size_t devid_strlen = strlen (devid);
+ BS_ERROR (("setting the devid to be 4311\n"));
+ bcopy (devid, vp, devid_strlen + 1);
+ vp += devid_strlen + 1;
+ }
+ bcopy (defaultsromvars, vp, MFGSROM_DEFVARSLEN);
+ vp += MFGSROM_DEFVARSLEN;
+ goto varsdone;
}
- vp += sprintf(vp, "boardflags=%d", w32);
- vp++;
-
- /* Word 58 is antenna gain 0/1 */
- w = b[58];
- vp += sprintf(vp, "ag0=%d", w & 0xff);
- vp++;
-
- vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
- vp++;
-
- if (sromrev == 1) {
- /* set the oem string */
- vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
- ((b[59] >> 8) & 0xff), (b[59] & 0xff),
- ((b[60] >> 8) & 0xff), (b[60] & 0xff),
- ((b[61] >> 8) & 0xff), (b[61] & 0xff),
- ((b[62] >> 8) & 0xff), (b[62] & 0xff));
- vp++;
- } else if (sromrev == 2) {
- /* Word 60 OFDM tx power offset from CCK level */
- /* OFDM Power Offset - opo */
- vp += sprintf(vp, "opo=%d", b[60] & 0xff);
- vp++;
- } else {
- /* Word 60: cck power offsets */
- vp += sprintf(vp, "cckpo=%d", b[60]);
- vp++;
-
- /* Words 61+62: 11g ofdm power offsets */
- w32 = ((uint32)b[62] << 16) | b[61];
- vp += sprintf(vp, "ofdmgpo=%d", w32);
- vp++;
+ else
+ {
+#endif /* WLTEST */
+ BS_ERROR (("srom crc failed with SPROM....\n"));
+ if (!(value = sb_getdevpathvar (sbh, "sromrev")))
+ {
+ err = -1;
+ goto errout;
+ }
+ sromrev = (uint8) simple_strtoul (value, NULL, 0);
+ flash = TRUE;
+#ifdef WLTEST
}
-
- /* final nullbyte terminator */
-done: *vp++ = '\0';
-
- ASSERT((vp - base) <= VARS_MAX);
+#endif /* WLTEST */
+ }
+
+ /* Bitmask for the sromrev */
+ sr = 1 << sromrev;
+
+ /* srom version check
+ * Current valid versions: 1, 2, 3, 4, 5, 8
+ */
+ if ((sr & 0x13e) == 0)
+ {
+ err = -2;
+ goto errout;
+ }
+
+ ASSERT (vars);
+ ASSERT (count);
+
+ base = vp = MALLOC (osh, MAXSZ_NVRAM_VARS);
+ ASSERT (vp);
+ if (!vp)
+ {
+ err = -2;
+ goto errout;
+ }
+
+ /* read variables from flash */
+ if (flash)
+ {
+ if ((err = initvars_flash (sbh, osh, &vp, MAXSZ_NVRAM_VARS)))
+ goto errout;
+ goto varsdone;
+ }
+
+ varbuf_init (&b, base, MAXSZ_NVRAM_VARS);
+
+ /* parse SROM into name=value pairs. */
+ _initvars_srom_pci (sromrev, srom, 0, &b);
+
+ /* final nullbyte terminator */
+ ASSERT (b.size >= 1);
+ vp = b.buf;
+ *vp++ = '\0';
+
+ ASSERT ((vp - base) <= MAXSZ_NVRAM_VARS);
varsdone:
- err = initvars_table(osh, base, vp, vars, count);
+ err = initvars_table (osh, base, vp, vars, count);
-err:
+errout:
#ifdef WLTEST
- if (base != mfgsromvars)
+ if (base && (base != mfgsromvars))
+#else
+ if (base)
#endif
- MFREE(osh, base, VARS_MAX);
- MFREE(osh, b, SROM_MAX);
- return err;
+ MFREE (osh, base, MAXSZ_NVRAM_VARS);
+
+ MFREE (osh, srom, SROM_MAX);
+ return err;
}
/*
@@ -1183,31 +1889,217 @@ err:
* Return 0 on success, nonzero on error.
*/
static int
-initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, uint *count)
+initvars_cis_pcmcia (sb_t * sbh, osl_t * osh, char **vars, uint * count)
{
- uint8 *cis = NULL;
- int rc;
- uint data_sz;
+ uint8 *cis = NULL;
+ int rc;
+ uint data_sz;
+
+ data_sz = (sb_pcmciarev (sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE;
+
+ if ((cis = MALLOC (osh, data_sz)) == NULL)
+ return (-2);
+
+ if (sb_pcmciarev (sbh) == 1)
+ {
+ if (srom_read
+ (sbh, PCMCIA_BUS, (void *) NULL, osh, 0, data_sz, (uint16 *) cis))
+ {
+ MFREE (osh, cis, data_sz);
+ return (-1);
+ }
+ /* fix up endianess for 16-bit data vs 8-bit parsing */
+ htol16_buf ((uint16 *) cis, data_sz);
+ }
+ else
+ OSL_PCMCIA_READ_ATTR (osh, 0, cis, data_sz);
+
+ rc = srom_parsecis (osh, &cis, 1, vars, count);
- data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE;
+ MFREE (osh, cis, data_sz);
- if ((cis = MALLOC(osh, data_sz)) == NULL)
- return (-2);
+ return (rc);
+}
+
+
+static int
+BCMINITFN (initvars_srom_sb) (sb_t * sbh, osl_t * osh, void *curmap,
+ char **vars, uint * varsz)
+{
+#if defined(BCMSDIODEV)
+ /* CIS is read and supplied by the host */
+ return BCME_OK;
+#elif defined(BCMUSBDEV)
+ static bool srvars = FALSE; /* Use OTP/SPROM as global variables */
+
+ int sel = 0; /* where to read the srom. 0 - nowhere, 1 - otp, 2 - sprom */
+ uint sz = 0; /* srom size in bytes */
+ void *oh = NULL;
+ int rc = BCME_OK;
+
+ /* Bail out if we've dealt with OTP/SPROM before! */
+ if (srvars)
+ return 0;
+
+#if defined(BCM4328)
+ if (sbh->chip == BCM4328_CHIP_ID)
+ {
+ /* Access the SPROM if it is present */
+ if ((sz = srom_size (sbh, osh)) != 0)
+ {
+ sz <<= 1;
+ sel = 2;
+ }
+ }
+#endif
+#if defined(BCM4325)
+ if (sbh->chip == BCM4325_CHIP_ID)
+ {
+ uint32 cst = sbh->chipst & CST4325_SPROM_OTP_SEL_MASK;
+
+ /* Access OTP if it is present, powered on, and programmed */
+ if ((oh = otp_init (sbh)) != NULL && (otp_status (oh) & OTPS_GUP_SW))
+ {
+ sz = otp_size (oh);
+ sel = 1;
+ }
+ /* Access the SPROM if it is present and allow to be accessed */
+ else if ((cst == CST4325_OTP_PWRDN || cst == CST4325_SPROM_SEL) &&
+ (sz = srom_size (sbh, osh)) != 0)
+ {
+ sz <<= 1;
+ sel = 2;
+ }
+ }
+#endif /* BCM4325 */
+
+ /* Read CIS in OTP/SPROM */
+ if (sel != 0)
+ {
+ uint16 *srom;
+ uint8 *body = NULL;
+
+ ASSERT (sz);
+
+ /* Allocate memory */
+ if ((srom = (uint16 *) MALLOC (osh, sz)) == NULL)
+ return BCME_NOMEM;
+
+ /* Read CIS */
+ switch (sel)
+ {
+ case 1:
+ rc = otp_read_region (oh, OTP_SW_RGN, srom, sz);
+ body = (uint8 *) srom;
+ break;
+ case 2:
+ rc = srom_read (sbh, SB_BUS, curmap, osh, 0, sz, srom);
+ /* sprom has 8 byte h/w header */
+ body = (uint8 *) srom + SBSDIO_SPROM_CIS_OFFSET;
+ break;
+ default:
+ /* impossible to come here */
+ ASSERT (0);
+ break;
+ }
- if (sb_pcmciarev(sbh) == 1) {
- if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) {
- MFREE(osh, cis, data_sz);
- return (-1);
+ /* Parse CIS */
+ if (rc == BCME_OK)
+ {
+ uint i, tpls = 0xffffffff;
+ /* # sdiod fns + common + extra */
+ uint8 *cis[SBSDIO_NUM_FUNCTION + 2];
+ uint ciss = 0;
+
+ /* each word is in host endian */
+ htol16_buf ((uint8 *) srom, sz);
+
+ ASSERT (body);
+
+ /* count cis tuple chains */
+ for (i = 0; i < sz && ciss < ARRAYSIZE (cis) && tpls != 0; i++)
+ {
+ cis[ciss++] = &body[i];
+ for (tpls = 0; i < sz - 1; tpls++)
+ {
+ if (body[i++] == CISTPL_END)
+ break;
+ i += body[i] + 1;
}
- /* fix up endianess for 16-bit data vs 8-bit parsing */
- ltoh16_buf((uint16 *)cis, data_sz);
- } else
- OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz);
+ }
- rc = srom_parsecis(osh, &cis, 1, vars, count);
+ /* call parser routine only when there are tuple chains */
+ if (ciss > 1)
+ rc = srom_parsecis (osh, cis, ciss, vars, varsz);
+ }
+
+ /* Clean up */
+ MFREE (osh, srom, sz);
- MFREE(osh, cis, data_sz);
+ /* Make SROM variables global */
+ if (rc == BCME_OK)
+ {
+ rc = nvram_append ((void *) sbh, *vars, *varsz);
+ srvars = TRUE;
- return (rc);
+ /* Tell the caller there is no individual SROM variables */
+ *vars = NULL;
+ *varsz = 0;
+ }
+ }
+
+ return rc;
+#else /* !BCMUSBDEV && !BCMSDIODEV */
+ /* Search flash nvram section for srom variables */
+ return initvars_flash_sb (sbh, vars, varsz);
+#endif /* !BCMUSBDEV && !BCMSDIODEV */
}
+#ifdef BCMUSBDEV
+/* Return sprom size in 16-bit words */
+static uint
+srom_size (sb_t * sbh, osl_t * osh)
+{
+ uint size = 0;
+ if (SPROMBUS == PCMCIA_BUS)
+ {
+ uint32 origidx;
+ sdpcmd_regs_t *pcmregs;
+ bool wasup;
+
+ origidx = sb_coreidx (sbh);
+ pcmregs = sb_setcore (sbh, SB_PCMCIA, 0);
+ ASSERT (pcmregs);
+
+ if (!(wasup = sb_iscoreup (sbh)))
+ sb_core_reset (sbh, 0, 0);
+
+ /* not worry about earlier core revs */
+ if (sb_corerev (sbh) < 8)
+ goto done;
+
+ /* SPROM is accessible only in PCMCIA mode unless there is SDIO clock */
+ if (!(R_REG (osh, &pcmregs->corestatus) & CS_PCMCIAMODE))
+ goto done;
+
+ switch (SB_PCMCIA_READ (osh, pcmregs, SROM_INFO) & SRI_SZ_MASK)
+ {
+ case 1:
+ size = 256; /* SROM_INFO == 1 means 4kbit */
+ break;
+ case 2:
+ size = 1024; /* SROM_INFO == 2 means 16kbit */
+ break;
+ default:
+ break;
+ }
+
+ done:
+ if (!wasup)
+ sb_core_disable (sbh, 0);
+
+ sb_setcoreidx (sbh, origidx);
+ }
+ return size;
+}
+#endif /* def BCMUSBDEV */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmutils.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmutils.c
deleted file mode 100644
index c7b0b3d3c8..0000000000
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/bcmutils.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Misc useful OS-independent routines.
- *
- * Copyright 2006, Broadcom Corporation
- * All Rights Reserved.
- *
- * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
- * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
- * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $
- */
-
-#include <typedefs.h>
-#include <bcmdefs.h>
-#include <stdarg.h>
-#include <bcmutils.h>
-#include <osl.h>
-#include <sbutils.h>
-#include <bcmnvram.h>
-#include <bcmendian.h>
-#include <bcmdevs.h>
-
-unsigned char bcm_ctype[] = {
- _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */
- _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C,
- _BCM_C, /* 8-15 */
- _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */
- _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */
- _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */
- _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */
- _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */
- _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */
- _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
- _BCM_U|_BCM_X, _BCM_U, /* 64-71 */
- _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */
- _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */
- _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
- _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
- _BCM_L|_BCM_X, _BCM_L, /* 96-103 */
- _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
- _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
- _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
- _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
- _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */
- _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
- _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */
- _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
- _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */
- _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
- _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */
- _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
- _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */
- _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
- _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
-};
-
-
-ulong
-bcm_strtoul(char *cp, char **endp, uint base)
-{
- ulong result, value;
- bool minus;
-
- minus = FALSE;
-
- while (bcm_isspace(*cp))
- cp++;
-
- if (cp[0] == '+')
- cp++;
- else if (cp[0] == '-') {
- minus = TRUE;
- cp++;
- }
-
- if (base == 0) {
- if (cp[0] == '0') {
- if ((cp[1] == 'x') || (cp[1] == 'X')) {
- base = 16;
- cp = &cp[2];
- } else {
- base = 8;
- cp = &cp[1];
- }
- } else
- base = 10;
- } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
- cp = &cp[2];
- }
-
- result = 0;
-
- while (bcm_isxdigit(*cp) &&
- (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
-
- if (minus)
- result = (ulong)(result * -1);
-
- if (endp)
- *endp = (char *)cp;
-
- return (result);
-}
-
-uchar
-bcm_toupper(uchar c)
-{
- if (bcm_islower(c))
- c -= 'a'-'A';
- return (c);
-}
-
-char*
-bcm_ether_ntoa(struct ether_addr *ea, char *buf)
-{
- sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
- ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff,
- ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff);
- return (buf);
-}
-
-
-/*
- * Search the name=value vars for a specific one and return its value.
- * Returns NULL if not found.
- */
-char*
-getvar(char *vars, char *name)
-{
- char *s;
- int len;
-
- len = strlen(name);
-
- /* first look in vars[] */
- for (s = vars; s && *s;) {
- /* CSTYLED */
- if ((memcmp(s, name, len) == 0) && (s[len] == '='))
- return (&s[len+1]);
-
- while (*s++)
- ;
- }
-
- /* then query nvram */
- return (nvram_get(name));
-}
-
-/*
- * Search the vars for a specific one and return its value as
- * an integer. Returns 0 if not found.
- */
-int
-getintvar(char *vars, char *name)
-{
- char *val;
-
- if ((val = getvar(vars, name)) == NULL)
- return (0);
-
- return (bcm_strtoul(val, NULL, 0));
-}
-
-
-/*******************************************************************************
- * crc8
- *
- * Computes a crc8 over the input data using the polynomial:
- *
- * x^8 + x^7 +x^6 + x^4 + x^2 + 1
- *
- * The caller provides the initial value (either CRC8_INIT_VALUE
- * or the previous returned value) to allow for processing of
- * discontiguous blocks of data. When generating the CRC the
- * caller is responsible for complementing the final return value
- * and inserting it into the byte stream. When checking, a final
- * return value of CRC8_GOOD_VALUE indicates a valid CRC.
- *
- * Reference: Dallas Semiconductor Application Note 27
- * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
- * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
- * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
- *
- * ****************************************************************************
- */
-
-static uint8 crc8_table[256] = {
- 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
- 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
- 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
- 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
- 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
- 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
- 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
- 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
- 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
- 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
- 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
- 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
- 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
- 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
- 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
- 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
- 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
- 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
- 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
- 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
- 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
- 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
- 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
- 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
- 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
- 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
- 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
- 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
- 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
- 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
- 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
- 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
-};
-
-#define CRC_INNER_LOOP(n, c, x) \
- (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
-
-uint8
-hndcrc8(
- uint8 *pdata, /* pointer to array of data to process */
- uint nbytes, /* number of input data bytes to process */
- uint8 crc /* either CRC8_INIT_VALUE or previous return value */
-)
-{
- /* hard code the crc loop instead of using CRC_INNER_LOOP macro
- * to avoid the undefined and unnecessary (uint8 >> 8) operation.
- */
- while (nbytes-- > 0)
- crc = crc8_table[(crc ^ *pdata++) & 0xff];
-
- return crc;
-}
-
-
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/cfe_env.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/cfe_env.c
new file mode 100644
index 0000000000..9dd4eeeb31
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/cfe_env.c
@@ -0,0 +1,233 @@
+/*
+ * NVRAM variable manipulation (Linux kernel half)
+ *
+ * Copyright 2001-2003, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmendian.h>
+
+#define NVRAM_SIZE (0x1ff0)
+static char _nvdata[NVRAM_SIZE] __initdata;
+static char _valuestr[256] __initdata;
+
+/*
+ * TLV types. These codes are used in the "type-length-value"
+ * encoding of the items stored in the NVRAM device (flash or EEPROM)
+ *
+ * The layout of the flash/nvram is as follows:
+ *
+ * <type> <length> <data ...> <type> <length> <data ...> <type_end>
+ *
+ * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
+ * The "length" field marks the length of the data section, not
+ * including the type and length fields.
+ *
+ * Environment variables are stored as follows:
+ *
+ * <type_env> <length> <flags> <name> = <value>
+ *
+ * If bit 0 (low bit) is set, the length is an 8-bit value.
+ * If bit 0 (low bit) is clear, the length is a 16-bit value
+ *
+ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still
+ * indicates the size of the length field.
+ *
+ * Flags are from the constants below:
+ *
+ */
+#define ENV_LENGTH_16BITS 0x00 /* for low bit */
+#define ENV_LENGTH_8BITS 0x01
+
+#define ENV_TYPE_USER 0x80
+
+#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
+#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
+
+/*
+ * The actual TLV types we support
+ */
+
+#define ENV_TLV_TYPE_END 0x00
+#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
+
+/*
+ * Environment variable flags
+ */
+
+#define ENV_FLG_NORMAL 0x00 /* normal read/write */
+#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
+#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
+
+#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
+#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
+
+
+/* *********************************************************************
+ * _nvram_read(buffer,offset,length)
+ *
+ * Read data from the NVRAM device
+ *
+ * Input parameters:
+ * buffer - destination buffer
+ * offset - offset of data to read
+ * length - number of bytes to read
+ *
+ * Return value:
+ * number of bytes read, or <0 if error occured
+ ********************************************************************* */
+static int
+_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
+{
+ int i;
+ if (offset > NVRAM_SIZE)
+ return -1;
+
+ for ( i = 0; i < length; i++) {
+ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
+ }
+ return length;
+}
+
+
+static char*
+_strnchr(const char *dest,int c,size_t cnt)
+{
+ while (*dest && (cnt > 0)) {
+ if (*dest == c) return (char *) dest;
+ dest++;
+ cnt--;
+ }
+ return NULL;
+}
+
+
+
+/*
+ * Core support API: Externally visible.
+ */
+
+/*
+ * Get the value of an NVRAM variable
+ * @param name name of variable to get
+ * @return value of variable or NULL if undefined
+ */
+
+char*
+cfe_env_get(unsigned char *nv_buf, char* name)
+{
+ int size;
+ unsigned char *buffer;
+ unsigned char *ptr;
+ unsigned char *envval;
+ unsigned int reclen;
+ unsigned int rectype;
+ int offset;
+ int flg;
+
+ size = NVRAM_SIZE;
+ buffer = &_nvdata[0];
+
+ ptr = buffer;
+ offset = 0;
+
+ /* Read the record type and length */
+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
+ goto error;
+ }
+
+ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
+
+ /* Adjust pointer for TLV type */
+ rectype = *(ptr);
+ offset++;
+ size--;
+
+ /*
+ * Read the length. It can be either 1 or 2 bytes
+ * depending on the code
+ */
+ if (rectype & ENV_LENGTH_8BITS) {
+ /* Read the record type and length - 8 bits */
+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
+ goto error;
+ }
+ reclen = *(ptr);
+ size--;
+ offset++;
+ }
+ else {
+ /* Read the record type and length - 16 bits, MSB first */
+ if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
+ goto error;
+ }
+ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
+ size -= 2;
+ offset += 2;
+ }
+
+ if (reclen > size)
+ break; /* should not happen, bad NVRAM */
+
+ switch (rectype) {
+ case ENV_TLV_TYPE_ENV:
+ /* Read the TLV data */
+ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
+ goto error;
+ flg = *ptr++;
+ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
+ if (envval) {
+ *envval++ = '\0';
+ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
+ _valuestr[(reclen-1)-(envval-ptr)] = '\0';
+#if 0
+ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
+#endif
+ if(!strcmp(ptr, name)){
+ return _valuestr;
+ }
+ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
+ return _valuestr;
+ }
+ break;
+
+ default:
+ /* Unknown TLV type, skip it. */
+ break;
+ }
+
+ /*
+ * Advance to next TLV
+ */
+
+ size -= (int)reclen;
+ offset += reclen;
+
+ /* Read the next record type */
+ ptr = buffer;
+ if (_nvram_read(nv_buf, ptr,offset,1) != 1)
+ goto error;
+ }
+
+error:
+ return NULL;
+
+}
+
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/compressed/Makefile b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/compressed/Makefile
deleted file mode 100644
index 2942c8eb34..0000000000
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/compressed/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Makefile for Broadcom BCM947XX boards
-#
-# Copyright 2001-2003, Broadcom Corporation
-# All Rights Reserved.
-#
-# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
-# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
-# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
-# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
-#
-# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $
-#
-
-OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
-SYSTEM ?= $(TOPDIR)/vmlinux
-
-all: vmlinuz
-
-# Don't build dependencies, this may die if $(CC) isn't gcc
-dep:
-
-# Create a gzipped version named vmlinuz for compatibility
-vmlinuz: piggy
- gzip -c9 $< > $@
-
-piggy: $(SYSTEM)
- $(OBJCOPY) $(OBJCOPY_ARGS) $< $@
-
-mrproper: clean
-
-clean:
- rm -f vmlinuz piggy
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/export.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/export.c
index 9da9572aba..ff3e031978 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/export.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/export.c
@@ -6,8 +6,10 @@
_export(bcm947xx_sbh)
+_export(sb_alp_clock)
_export(sb_attach)
_export(sb_kattach)
+_export(sb_backplane64)
_export(sb_boardtype)
_export(sb_boardvendor)
_export(sb_btcgpiowar)
@@ -24,6 +26,7 @@ _export(sb_core_disable)
_export(sb_core_reset)
_export(sb_core_tofixup)
_export(sb_coreflags)
+_export(sb_coreflags_wo)
_export(sb_coreflagshi)
_export(sb_coreidx)
_export(sb_coreregs)
@@ -39,26 +42,30 @@ _export(sb_gpioled)
_export(sb_gpioin)
_export(sb_gpioout)
_export(sb_gpioouten)
+_export(sb_gpiopull)
_export(sb_gpiotimerval)
_export(sb_irq)
_export(sb_iscoreup)
_export(sb_pci_setup)
+_export(sb_pci_sleep)
+_export(sb_pci_down)
+_export(sb_pci_up)
_export(sb_pcirev)
_export(sb_pcmcia_init)
_export(sb_pcmciarev)
+_export(sb_pmu_paref_ldo_enable)
+_export(sb_pmu_rcal)
+_export(sb_pmu_set_ldo_voltage)
+_export(sb_deregister_intr_callback)
_export(sb_register_intr_callback)
_export(sb_setcore)
_export(sb_setcoreidx)
_export(sb_war16165)
-_export(sb_war32414_forceHT)
+_export(sb_war42780_clkreq)
_export(sb_osh)
-
+
_export(getvar)
_export(getintvar)
-_export(bcm_strtoul)
-_export(bcm_ctype)
-_export(bcm_toupper)
-_export(bcm_ether_ntoa)
_export(nvram_get)
_export(nvram_getall)
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/gpio.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/gpio.c
index c31f58bac6..37b41e1ec3 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/gpio.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/gpio.c
@@ -20,7 +20,6 @@
#include <typedefs.h>
#include <osl.h>
-#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
@@ -122,7 +121,7 @@ gpio_init(void)
{
int i;
- if (!(gpio_sbh = sb_kattach()))
+ if (!(gpio_sbh = sb_kattach(SB_OSH)))
return -ENODEV;
sb_gpiosetcore(gpio_sbh);
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndchipc.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndchipc.c
index 6502078de1..1f1dc10efa 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndchipc.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndchipc.c
@@ -1,7 +1,7 @@
/*
- * BCM47XX support code for some chipcommon (old extif) facilities (uart)
+ * BCM47XX support code for some chipcommon facilities (uart, jtagm)
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,28 +9,52 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: hndchipc.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
-#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
#include <bcmnvram.h>
#include <sbconfig.h>
-#include <sbextif.h>
#include <sbchipc.h>
+#include <sbextif.h>
+#include <hndchipc.h>
#include <hndcpu.h>
-/*
- * Returns TRUE if an external UART exists at the given base
- * register.
+/* debug/trace */
+#define CC_ERROR(args)
+
+#ifdef BCMDBG
+#define CC_MSG(args) printf args
+#else
+#define CC_MSG(args)
+#endif /* BCMDBG */
+
+/* interested chipcommon interrupt source
+ * - GPIO
+ * - EXTIF
+ * - ECI
+ * - PMU
+ * - UART
*/
-static bool
-BCMINITFN(serial_exists)(osl_t *osh, uint8 *regs)
-{
+#define MAX_CC_INT_SOURCE 5
+
+/* chipc secondary isr info */
+typedef struct {
+ uint intmask; /* int mask */
+ cc_isr_fn isr; /* secondary isr handler */
+ void *cbdata; /* pointer to private data */
+} cc_isr_info_t;
+
+static cc_isr_info_t cc_isr_desc[MAX_CC_INT_SOURCE];
+
+/* chip common intmask */
+static uint32 cc_intmask = 0;
+
+static bool BCMINITFN(serial_exists) (osl_t * osh, uint8 * regs) {
uint8 save_mcr, status1;
save_mcr = R_REG(osh, &regs[UART_MCR]);
@@ -41,118 +65,276 @@ BCMINITFN(serial_exists)(osl_t *osh, uint8 *regs)
return (status1 == 0x90);
}
+static void __init sb_extif_serial_init(sb_t * sbh, void *regs,
+ sb_serial_init_fn add)
+{
+ osl_t *osh = sb_osh(sbh);
+ extifregs_t *eir = (extifregs_t *) regs;
+ sbconfig_t *sb;
+ ulong base;
+ uint irq;
+ int i, n;
+
+ /* Determine external UART register base */
+ sb = (sbconfig_t *) ((ulong) eir + SBCONFIGOFF);
+ base = EXTIF_CFGIF_BASE(sb_base(R_REG(osh, &sb->sbadmatch1)));
+
+ /* Determine IRQ */
+ irq = sb_irq(sbh);
+
+ /* Disable GPIO interrupt initially */
+ W_REG(osh, &eir->gpiointpolarity, 0);
+ W_REG(osh, &eir->gpiointmask, 0);
+
+ /* Search for external UARTs */
+ n = 2;
+ for (i = 0; i < 2; i++) {
+ regs = (void *)REG_MAP(base + (i * 8), 8);
+ if (serial_exists(osh, regs)) {
+ /* Set GPIO 1 to be the external UART IRQ */
+ W_REG(osh, &eir->gpiointmask, 2);
+ /* XXXDetermine external UART clock */
+ if (add)
+ add(regs, irq, 13500000, 0);
+ }
+ }
+
+ /* Add internal UART if enabled */
+ if (R_REG(osh, &eir->corecontrol) & CC_UE)
+ if (add)
+ add((void *)&eir->uartdata, irq, sb_clock(sbh), 2);
+}
+
/*
* Initializes UART access. The callback function will be called once
* per found UART.
*/
-void
-BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base,
- uint reg_shift))
-{
+void BCMINITFN(sb_serial_init) (sb_t * sbh, sb_serial_init_fn add) {
osl_t *osh;
void *regs;
- ulong base;
+ chipcregs_t *cc;
+ uint32 rev, cap, pll, baud_base, div;
uint irq;
int i, n;
osh = sb_osh(sbh);
- if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) {
- extifregs_t *eir = (extifregs_t *) regs;
- sbconfig_t *sb;
-
- /* Determine external UART register base */
- sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
- base = EXTIF_CFGIF_BASE(sb_base(R_REG(osh, &sb->sbadmatch1)));
-
- /* Determine IRQ */
- irq = sb_irq(sbh);
-
- /* Disable GPIO interrupt initially */
- W_REG(osh, &eir->gpiointpolarity, 0);
- W_REG(osh, &eir->gpiointmask, 0);
-
- /* Search for external UARTs */
- n = 2;
- for (i = 0; i < 2; i++) {
- regs = (void *) REG_MAP(base + (i * 8), 8);
- if (serial_exists(osh, regs)) {
- /* Set GPIO 1 to be the external UART IRQ */
- W_REG(osh, &eir->gpiointmask, 2);
- /* XXXDetermine external UART clock */
- if (add)
- add(regs, irq, 13500000, 0);
- }
- }
+ regs = sb_setcore(sbh, SB_EXTIF, 0);
+ if (regs) {
+ sb_extif_serial_init(sbh, regs, add);
+ return;
+ }
- /* Add internal UART if enabled */
- if (R_REG(osh, &eir->corecontrol) & CC_UE)
- if (add)
- add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
- } else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
- chipcregs_t *cc = (chipcregs_t *) regs;
- uint32 rev, cap, pll, baud_base, div;
+ cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
+ ASSERT(cc);
- /* Determine core revision and capabilities */
- rev = sb_corerev(sbh);
- cap = R_REG(osh, &cc->capabilities);
- pll = cap & CAP_PLL_MASK;
+ /* Determine core revision and capabilities */
+ rev = sbh->ccrev;
+ cap = sbh->cccaps;
+ pll = cap & CC_CAP_PLL_MASK;
- /* Determine IRQ */
- irq = sb_irq(sbh);
+ /* Determine IRQ */
+ irq = sb_irq(sbh);
- if (pll == PLL_TYPE1) {
- /* PLL clock */
- baud_base = sb_clock_rate(pll,
- R_REG(osh, &cc->clockcontrol_n),
- R_REG(osh, &cc->clockcontrol_m2));
- div = 1;
- } else {
+ if (pll == PLL_TYPE1) {
+ /* PLL clock */
+ baud_base = sb_clock_rate(pll,
+ R_REG(osh, &cc->clockcontrol_n),
+ R_REG(osh, &cc->clockcontrol_m2));
+ div = 1;
+ } else {
+ /* 5354 chip common uart uses a constant clock
+ * frequency of 25MHz */
+ if (sb_corerev(sbh) == 20) {
+ /* Set the override bit so we don't divide it */
+ W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
+ baud_base = 25000000;
+ } else if (rev >= 11 && rev != 15) {
/* Fixed ALP clock */
- if (rev >= 11 && rev != 15) {
- baud_base = 20000000;
- div = 1;
- /* Set the override bit so we don't divide it */
- W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
- }
+ baud_base = sb_alp_clock(sbh);
+ div = 1;
+ /* Turn off UART clock before switching clock source */
+ if (rev >= 21)
+ AND_REG(osh, &cc->corecontrol, ~CC_UARTCLKEN);
+ /* Set the override bit so we don't divide it */
+ OR_REG(osh, &cc->corecontrol, CC_UARTCLKO);
+ if (rev >= 21)
+ OR_REG(osh, &cc->corecontrol, CC_UARTCLKEN);
+ } else if (rev >= 3) {
/* Internal backplane clock */
- else if (rev >= 3) {
- baud_base = sb_clock(sbh);
- div = 2; /* Minimum divisor */
- W_REG(osh, &cc->clkdiv,
- ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
- }
+ baud_base = sb_clock(sbh);
+ div = 2; /* Minimum divisor */
+ W_REG(osh, &cc->clkdiv,
+ ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
+ } else {
/* Fixed internal backplane clock */
- else {
- baud_base = 88000000;
- div = 48;
- }
+ baud_base = 88000000;
+ div = 48;
+ }
- /* Clock source depends on strapping if UartClkOverride is unset */
- if ((rev > 0) &&
- ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
- if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
- /* Internal divided backplane clock */
- baud_base /= div;
- } else {
- /* Assume external clock of 1.8432 MHz */
- baud_base = 1843200;
- }
+ /* Clock source depends on strapping if UartClkOverride is unset */
+ if ((rev > 0)
+ && ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
+ if ((cap & CC_CAP_UCLKSEL) == CC_CAP_UINTCLK) {
+ /* Internal divided backplane clock */
+ baud_base /= div;
+ } else {
+ /* Assume external clock of 1.8432 MHz */
+ baud_base = 1843200;
}
}
+ }
- /* Add internal UARTs */
- n = cap & CAP_UARTS_MASK;
- for (i = 0; i < n; i++) {
- /* Register offset changed after revision 0 */
- if (rev)
- regs = (void *)((ulong) &cc->uart0data + (i * 256));
- else
- regs = (void *)((ulong) &cc->uart0data + (i * 8));
+ /* Add internal UARTs */
+ n = cap & CC_CAP_UARTS_MASK;
+ for (i = 0; i < n; i++) {
+ /* Register offset changed after revision 0 */
+ if (rev)
+ regs = (void *)((ulong) & cc->uart0data + (i * 256));
+ else
+ regs = (void *)((ulong) & cc->uart0data + (i * 8));
- if (add)
- add(regs, irq, baud_base, 0);
+ if (add)
+ add(regs, irq, baud_base, 0);
+ }
+}
+
+#if 0
+/*
+ * Initialize jtag master and return handle for
+ * jtag_rwreg. Returns NULL on failure.
+ */
+void *sb_jtagm_init(sb_t * sbh, uint clkd, bool exttap)
+{
+ void *regs;
+
+ if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) {
+ chipcregs_t *cc = (chipcregs_t *) regs;
+ uint32 tmp;
+
+ /*
+ * Determine jtagm availability from
+ * core revision and capabilities.
+ */
+
+ /*
+ * Corerev 10 has jtagm, but the only chip
+ * with it does not have a mips, and
+ * the layout of the jtagcmd register is
+ * different. We'll only accept >= 11.
+ */
+ if (sbh->ccrev < 11)
+ return (NULL);
+
+ if ((sbh->cccaps & CC_CAP_JTAGP) == 0)
+ return (NULL);
+
+ /* Set clock divider if requested */
+ if (clkd != 0) {
+ tmp = R_REG(osh, &cc->clkdiv);
+ tmp =
+ (tmp & ~CLKD_JTAG) | ((clkd << CLKD_JTAG_SHIFT) &
+ CLKD_JTAG);
+ W_REG(osh, &cc->clkdiv, tmp);
}
+
+ /* Enable jtagm */
+ tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0);
+ W_REG(osh, &cc->jtagctrl, tmp);
}
+
+ return (regs);
+}
+
+void sb_jtagm_disable(osl_t * osh, void *h)
+{
+ chipcregs_t *cc = (chipcregs_t *) h;
+
+ W_REG(osh, &cc->jtagctrl, R_REG(osh, &cc->jtagctrl) & ~JCTRL_EN);
}
+/*
+ * Read/write a jtag register. Assumes a target with
+ * 8 bit IR and 32 bit DR.
+ */
+#define IRWIDTH 8 /* Default Instruction Register width */
+#define DRWIDTH 32 /* Default Data Register width */
+
+uint32 jtag_rwreg(osl_t * osh, void *h, uint32 ir, uint32 dr)
+{
+ chipcregs_t *cc = (chipcregs_t *) h;
+ uint32 tmp;
+
+ W_REG(osh, &cc->jtagir, ir);
+ W_REG(osh, &cc->jtagdr, dr);
+ tmp = JCMD_START | JCMD_ACC_IRDR |
+ ((IRWIDTH - 1) << JCMD_IRW_SHIFT) | (DRWIDTH - 1);
+ W_REG(osh, &cc->jtagcmd, tmp);
+ while (((tmp = R_REG(osh, &cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) {
+ /* OSL_DELAY(1); */
+ }
+
+ tmp = R_REG(osh, &cc->jtagdr);
+ return (tmp);
+}
+#endif
+
+/*
+ * Interface to register chipc secondary isr
+ */
+bool
+BCMINITFN(sb_cc_register_isr) (sb_t * sbh, cc_isr_fn isr, uint32 ccintmask,
+ void *cbdata) {
+ bool done = FALSE;
+ chipcregs_t *regs;
+ uint origidx;
+ uint i;
+
+ /* Save the current core index */
+ origidx = sb_coreidx(sbh);
+ regs = sb_setcore(sbh, SB_CC, 0);
+ ASSERT(regs);
+
+ for (i = 0; i < MAX_CC_INT_SOURCE; i++) {
+ if (cc_isr_desc[i].isr == NULL) {
+ cc_isr_desc[i].isr = isr;
+ cc_isr_desc[i].cbdata = cbdata;
+ cc_isr_desc[i].intmask = ccintmask;
+ done = TRUE;
+ break;
+ }
+ }
+
+ if (done) {
+ cc_intmask = R_REG(sb_osh(sbh), &regs->intmask);
+ cc_intmask |= ccintmask;
+ W_REG(sb_osh(sbh), &regs->intmask, cc_intmask);
+ }
+
+ /* restore original coreidx */
+ sb_setcoreidx(sbh, origidx);
+ return done;
+}
+
+/*
+ * chipc primary interrupt handler
+ */
+void sb_cc_isr(sb_t * sbh, chipcregs_t * regs)
+{
+ uint32 ccintstatus;
+ uint32 intstatus;
+ uint32 i;
+
+ /* prior to rev 21 chipc interrupt means uart and gpio */
+ if (sbh->ccrev >= 21)
+ ccintstatus = R_REG(sb_osh(sbh), &regs->intstatus) & cc_intmask;
+ else
+ ccintstatus = (CI_UART | CI_GPIO);
+
+ for (i = 0; i < MAX_CC_INT_SOURCE; i++) {
+ if ((cc_isr_desc[i].isr != NULL) &&
+ (intstatus = (cc_isr_desc[i].intmask & ccintstatus))) {
+ (cc_isr_desc[i].isr) (cc_isr_desc[i].cbdata, intstatus);
+ }
+ }
+}
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c
new file mode 100644
index 0000000000..c7d7b3be75
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c
@@ -0,0 +1,1257 @@
+/*
+ * Misc utility routines for accessing PMU corerev specific features
+ * of the SiliconBackplane-based Broadcom chips.
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <sbutils.h>
+#include <bcmdevs.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <hndpmu.h>
+
+/* debug/trace */
+#define PMU_ERROR(args)
+
+#ifdef BCMDBG
+#define PMU_MSG(args) printf args
+#else
+#define PMU_MSG(args)
+#endif /* BCMDBG */
+
+/* PMU & control */
+/* PMU rev 0 pll control for BCM4328 and BCM5354 */
+static void sb_pmu0_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
+ uint32 xtal);
+static uint32 sb_pmu0_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
+static uint32 sb_pmu0_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
+/* PMU rev 0 pll control for BCM4325 BCM4329 */
+static void sb_pmu1_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
+ uint32 xtal);
+static uint32 sb_pmu1_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
+static uint32 sb_pmu1_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc);
+
+/* Setup switcher voltage */
+void
+BCMINITFN (sb_pmu_set_switcher_voltage) (sb_t * sbh, osl_t * osh,
+ uint8 bb_voltage, uint8 rf_voltage)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ W_REG (osh, &cc->regcontrol_addr, 0x01);
+ W_REG (osh, &cc->regcontrol_data, (uint32) (bb_voltage & 0x1f) << 22);
+
+ W_REG (osh, &cc->regcontrol_addr, 0x00);
+ W_REG (osh, &cc->regcontrol_data, (uint32) (rf_voltage & 0x1f) << 14);
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
+
+void
+sb_pmu_set_ldo_voltage (sb_t * sbh, osl_t * osh, uint8 ldo, uint8 voltage)
+{
+ uint8 sr_cntl_shift, rc_shift, shift, mask;
+ uint32 addr;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ case BCM5354_CHIP_ID:
+ switch (ldo)
+ {
+ case SET_LDO_VOLTAGE_LDO1:
+ addr = 2;
+ sr_cntl_shift = 8;
+ rc_shift = 17;
+ mask = 0xf;
+ break;
+ case SET_LDO_VOLTAGE_LDO2:
+ addr = 3;
+ sr_cntl_shift = 0;
+ rc_shift = 1;
+ mask = 0xf;
+ break;
+ case SET_LDO_VOLTAGE_LDO3:
+ addr = 3;
+ sr_cntl_shift = 0;
+ rc_shift = 9;
+ mask = 0xf;
+ break;
+ case SET_LDO_VOLTAGE_PAREF:
+ addr = 3;
+ sr_cntl_shift = 0;
+ rc_shift = 17;
+ mask = 0x3f;
+ break;
+ default:
+ ASSERT (FALSE);
+ return;
+ }
+ break;
+ case BCM4312_CHIP_ID:
+ switch (ldo)
+ {
+ case SET_LDO_VOLTAGE_PAREF:
+ addr = 0;
+ sr_cntl_shift = 0;
+ rc_shift = 21;
+ mask = 0x3f;
+ break;
+ default:
+ ASSERT (FALSE);
+ return;
+ }
+ break;
+ default:
+ ASSERT (FALSE);
+ return;
+ }
+
+ shift = sr_cntl_shift + rc_shift;
+
+ sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_addr),
+ ~0, addr);
+ sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_data),
+ mask << shift, (voltage & mask) << shift);
+}
+
+void
+sb_pmu_paref_ldo_enable (sb_t * sbh, osl_t * osh, bool enable)
+{
+ uint ldo = 0;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ ldo = RES4328_PA_REF_LDO;
+ break;
+ case BCM5354_CHIP_ID:
+ ldo = RES5354_PA_REF_LDO;
+ break;
+ case BCM4312_CHIP_ID:
+ ldo = RES4312_PA_REF_LDO;
+ break;
+ default:
+ return;
+ }
+
+ sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, min_res_mask),
+ PMURES_BIT (ldo), enable ? PMURES_BIT (ldo) : 0);
+}
+
+uint16 BCMINITFN (sb_pmu_fast_pwrup_delay) (sb_t * sbh, osl_t * osh)
+{
+ uint16 delay = PMU_MAX_TRANSITION_DLY;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ delay = 7000;
+ break;
+
+ case BCM4325_CHIP_ID:
+ case BCM4312_CHIP_ID:
+#ifdef BCMQT
+ delay = 70;
+#else
+ delay = 2800;
+#endif
+ break;
+
+ default:
+ PMU_MSG (("No PMU fast power up delay specified "
+ "for chip %x rev %d, using default %d us\n",
+ sbh->chip, sbh->chiprev, delay));
+ break;
+ }
+
+ return delay;
+}
+
+uint32 BCMINITFN (sb_pmu_force_ilp) (sb_t * sbh, osl_t * osh, bool force)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 oldpmucontrol;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ oldpmucontrol = R_REG (osh, &cc->pmucontrol);
+ if (force)
+ W_REG (osh, &cc->pmucontrol, oldpmucontrol &
+ ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
+ else
+ W_REG (osh, &cc->pmucontrol, oldpmucontrol |
+ (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+
+ return oldpmucontrol;
+}
+
+/* Setup min/max resources and up/down timers */
+typedef struct
+{
+ uint8 resnum;
+ uint16 updown;
+} pmu_res_updown_t;
+
+typedef struct
+{
+ uint8 resnum;
+ int8 action; /* 0 - set, 1 - add, -1 - remove */
+ uint32 depend_mask;
+} pmu_res_depend_t;
+
+static const pmu_res_updown_t
+BCMINITDATA (bcm4328a0_res_updown)[] =
+{
+ {
+ RES4328_EXT_SWITCHER_PWM, 0x0101},
+ {
+ RES4328_BB_SWITCHER_PWM, 0x1f01},
+ {
+ RES4328_BB_SWITCHER_BURST, 0x010f},
+ {
+ RES4328_BB_EXT_SWITCHER_BURST, 0x0101},
+ {
+ RES4328_ILP_REQUEST, 0x0202},
+ {
+ RES4328_RADIO_SWITCHER_PWM, 0x0f01},
+ {
+ RES4328_RADIO_SWITCHER_BURST, 0x0f01},
+ {
+ RES4328_ROM_SWITCH, 0x0101},
+ {
+ RES4328_PA_REF_LDO, 0x0f01},
+ {
+ RES4328_RADIO_LDO, 0x0f01},
+ {
+ RES4328_AFE_LDO, 0x0f01},
+ {
+ RES4328_PLL_LDO, 0x0f01},
+ {
+ RES4328_BG_FILTBYP, 0x0101},
+ {
+ RES4328_TX_FILTBYP, 0x0101},
+ {
+ RES4328_RX_FILTBYP, 0x0101},
+ {
+ RES4328_XTAL_PU, 0x0101},
+ {
+ RES4328_XTAL_EN, 0xa001},
+ {
+ RES4328_BB_PLL_FILTBYP, 0x0101},
+ {
+ RES4328_RF_PLL_FILTBYP, 0x0101},
+ {
+ RES4328_BB_PLL_PU, 0x0701}
+};
+
+static const pmu_res_depend_t
+BCMINITDATA (bcm4328a0_res_depend)[] =
+{
+ /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
+ {
+ RES4328_ILP_REQUEST, 0,
+ PMURES_BIT (RES4328_EXT_SWITCHER_PWM) |
+ PMURES_BIT (RES4328_BB_SWITCHER_PWM)}
+};
+
+#ifdef BCMQT /* for power save on slow QT/small beacon interval */
+static const pmu_res_updown_t
+BCMINITDATA (bcm4325a0_res_updown_qt)[] =
+{
+ {
+ RES4325_HT_AVAIL, 0x0300},
+ {
+ RES4325_BBPLL_PWRSW_PU, 0x0101},
+ {
+ RES4325_RFPLL_PWRSW_PU, 0x0101},
+ {
+ RES4325_ALP_AVAIL, 0x0100},
+ {
+ RES4325_XTAL_PU, 0x1000},
+ {
+ RES4325_LNLDO1_PU, 0x0800},
+ {
+ RES4325_CLDO_CBUCK_PWM, 0x0101},
+ {
+ RES4325_CBUCK_PWM, 0x0803}
+};
+#else
+static const pmu_res_updown_t
+BCMINITDATA (bcm4325a0_res_updown)[] =
+{
+ {
+ RES4325_XTAL_PU, 0x1501}
+};
+#endif /* !BCMQT */
+
+static const pmu_res_depend_t
+BCMINITDATA (bcm4325a0_res_depend)[] =
+{
+ /* Adjust HT Avail resource dependencies */
+ {
+ RES4325_HT_AVAIL, 1,
+ PMURES_BIT (RES4325_RX_PWRSW_PU) | PMURES_BIT (RES4325_TX_PWRSW_PU) |
+ PMURES_BIT (RES4325_LOGEN_PWRSW_PU) | PMURES_BIT (RES4325_AFE_PWRSW_PU)}
+};
+
+void BCMINITFN (sb_pmu_res_init) (sb_t * sbh, osl_t * osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ const pmu_res_updown_t *pmu_res_updown_table = NULL;
+ int pmu_res_updown_table_sz = 0;
+ const pmu_res_depend_t *pmu_res_depend_table = NULL;
+ int pmu_res_depend_table_sz = 0;
+ uint32 min_mask = 0, max_mask = 0;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ /* Down to ILP request excluding ROM */
+ min_mask = PMURES_BIT (RES4328_EXT_SWITCHER_PWM) |
+ PMURES_BIT (RES4328_BB_SWITCHER_PWM) | PMURES_BIT (RES4328_XTAL_EN);
+#ifdef BCMROMOFFLOAD
+ /* Including ROM */
+ min_mask |= PMURES_BIT (RES4328_ROM_SWITCH);
+#endif
+ /* Allow (but don't require) PLL to turn on */
+ max_mask = 0xfffff;
+ pmu_res_updown_table = bcm4328a0_res_updown;
+ pmu_res_updown_table_sz = ARRAYSIZE (bcm4328a0_res_updown);
+ pmu_res_depend_table = bcm4328a0_res_depend;
+ pmu_res_depend_table_sz = ARRAYSIZE (bcm4328a0_res_depend);
+ break;
+ case BCM4312_CHIP_ID:
+ /* keep default
+ * min_mask = 0xcbb; max_mask = 0x7ffff;
+ * pmu_res_updown_table_sz = 0;
+ * pmu_res_depend_table_sz = 0;
+ */
+ break;
+ case BCM5354_CHIP_ID:
+ /* Allow (but don't require) PLL to turn on */
+ max_mask = 0xfffff;
+ break;
+
+ case BCM4325_CHIP_ID:
+ /* Leave OTP powered up and power it down later. */
+ min_mask =
+ PMURES_BIT (RES4325_CBUCK_BURST) | PMURES_BIT (RES4325_LNLDO2_PU);
+ if (((sbh->chipst & CST4325_PMUTOP_2B_MASK) >>
+ CST4325_PMUTOP_2B_SHIFT) == 1)
+ min_mask |= PMURES_BIT (RES4325_CLDO_CBUCK_BURST);
+ /* Allow (but don't require) PLL to turn on */
+ max_mask = 0x3fffff;
+#ifdef BCMQT
+ pmu_res_updown_table = bcm4325a0_res_updown_qt;
+ pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown_qt);
+#else
+ pmu_res_updown_table = bcm4325a0_res_updown;
+ pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown);
+ pmu_res_depend_table = bcm4325a0_res_depend;
+ pmu_res_depend_table_sz = ARRAYSIZE (bcm4325a0_res_depend);
+#endif
+ break;
+
+ default:
+ break;
+ }
+
+ /* Program up/down timers */
+ while (pmu_res_updown_table_sz--)
+ {
+ ASSERT (pmu_res_updown_table);
+ W_REG (osh, &cc->res_table_sel,
+ pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
+ W_REG (osh, &cc->res_updn_timer,
+ pmu_res_updown_table[pmu_res_updown_table_sz].updown);
+ }
+
+ /* Program resource dependencies table */
+ while (pmu_res_depend_table_sz--)
+ {
+ ASSERT (pmu_res_depend_table);
+ W_REG (osh, &cc->res_table_sel,
+ pmu_res_depend_table[pmu_res_depend_table_sz].resnum);
+ switch (pmu_res_depend_table[pmu_res_depend_table_sz].action)
+ {
+ case 0:
+ W_REG (osh, &cc->res_dep_mask,
+ pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
+ break;
+ case 1:
+ OR_REG (osh, &cc->res_dep_mask,
+ pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
+ break;
+ case -1:
+ AND_REG (osh, &cc->res_dep_mask,
+ ~pmu_res_depend_table[pmu_res_depend_table_sz].
+ depend_mask);
+ break;
+ default:
+ ASSERT (0);
+ break;
+ }
+ }
+
+ /* program min resource mask */
+ if (min_mask)
+ {
+ PMU_MSG (("Changing min_res_mask to 0x%x\n", min_mask));
+ W_REG (osh, &cc->min_res_mask, min_mask);
+ }
+ /* program max resource mask */
+ if (max_mask)
+ {
+ PMU_MSG (("Changing max_res_mask to 0x%x\n", max_mask));
+ W_REG (osh, &cc->max_res_mask, max_mask);
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
+
+/* setup pll and query clock speed */
+typedef struct
+{
+ uint16 freq;
+ uint8 xf;
+ uint8 wbint;
+ uint32 wbfrac;
+} pmu0_xtaltab0_t;
+
+/* the following table is based on 880Mhz Fvco */
+#define PMU0_PLL0_FVCO 880000 /* Fvco 880Mhz */
+static const pmu0_xtaltab0_t
+BCMINITDATA (pmu0_xtaltab0)[] =
+{
+ {
+ 12000, 1, 73, 349525},
+ {
+ 13000, 2, 67, 725937},
+ {
+ 14400, 3, 61, 116508},
+ {
+ 15360, 4, 57, 305834},
+ {
+ 16200, 5, 54, 336579},
+ {
+ 16800, 6, 52, 399457},
+ {
+ 19200, 7, 45, 873813},
+ {
+ 19800, 8, 44, 466033},
+ {
+ 20000, 9, 44, 0},
+ {
+ 25000, 10, 70, 419430},
+ {
+ 26000, 11, 67, 725937},
+ {
+ 30000, 12, 58, 699050},
+ {
+ 38400, 13, 45, 873813},
+ {
+ 40000, 14, 45, 0},
+ {
+ 0, 0, 0, 0}
+};
+
+#ifdef BCMUSBDEV
+#define PMU0_XTAL0_DEFAULT 11
+#else
+#define PMU0_XTAL0_DEFAULT 8
+#endif
+
+#ifdef BCMUSBDEV
+/*
+ * Set new backplane PLL clock frequency
+ */
+static void BCMINITFN (sb_pmu0_sbclk4328) (sb_t * sbh, int freq)
+{
+ uint32 tmp, oldmax, oldmin, origidx;
+ chipcregs_t *cc;
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ /* Set new backplane PLL clock */
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK);
+ tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT;
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
+ /* Disable PLL */
+ oldmin = R_REG (osh, &cc->min_res_mask);
+ oldmax = R_REG (osh, &cc->max_res_mask);
+ W_REG (osh, &cc->min_res_mask, oldmin & ~PMURES_BIT (RES4328_BB_PLL_PU));
+ W_REG (osh, &cc->max_res_mask, oldmax & ~PMURES_BIT (RES4328_BB_PLL_PU));
+
+ /* It takes over several hundred usec to re-enable the PLL since the
+ * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
+ *
+ * Be sure PLL is powered down first before re-enabling it.
+ */
+
+ OSL_DELAY (PLL_DELAY);
+ SPINWAIT ((R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)),
+ PLL_DELAY * 3);
+
+ if (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU))
+ {
+ /* If BB_PLL not powered down yet, new backplane PLL clock
+ * may not take effect.
+ *
+ * Still early during bootup so no serial output here.
+ */
+ PMU_ERROR (("Fatal: BB_PLL not power down yet!\n"));
+ ASSERT (!
+ (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)));
+ }
+
+ /* Enable PLL */
+ W_REG (osh, &cc->max_res_mask, oldmax);
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
+#endif /* BCMUSBDEV */
+
+/* Set up PLL registers in the PMU as per the crystal speed.
+ * Uses xtalfreq variable, or passed-in default.
+ */
+static void
+BCMINITFN (sb_pmu0_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
+ uint32 xtal)
+{
+ uint32 tmp;
+ const pmu0_xtaltab0_t *xt;
+
+ if ((sb_chip (sbh) == BCM5354_CHIP_ID) && (xtal == 0))
+ {
+ /* 5354 has xtal freq of 25MHz */
+ xtal = 25000;
+ }
+
+ /* Find the frequency in the table */
+ for (xt = pmu0_xtaltab0; xt->freq; xt++)
+ if (xt->freq == xtal)
+ break;
+ if (xt->freq == 0)
+ xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
+
+ PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf));
+
+ /* Check current PLL state */
+ tmp = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT;
+ if (tmp == xt->xf)
+ {
+ PMU_MSG (("PLL already programmed for %d.%d MHz\n",
+ (xt->freq / 1000), (xt->freq % 1000)));
+
+#ifdef BCMUSBDEV
+ if (sbh->chip == BCM4328_CHIP_ID)
+ sb_pmu0_sbclk4328 (sbh, PMU0_PLL0_PC0_DIV_ARM_88MHZ);
+#endif
+ return;
+ }
+
+ if (tmp)
+ {
+ PMU_MSG (("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
+ (xt->freq / 1000), (xt->freq % 1000),
+ (pmu0_xtaltab0[tmp - 1].freq / 1000),
+ (pmu0_xtaltab0[tmp - 1].freq % 1000)));
+ }
+ else
+ {
+ PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->freq / 1000),
+ (xt->freq % 1000)));
+ }
+
+ /* Make sure the PLL is off */
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU));
+ AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU));
+ break;
+ case BCM5354_CHIP_ID:
+ AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU));
+ AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU));
+ break;
+ default:
+ ASSERT (0);
+ }
+ SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL,
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL));
+
+ PMU_MSG (("Done masking\n"));
+
+ /* Write PDIV in pllcontrol[0] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ)
+ tmp |= PMU0_PLL0_PC0_PDIV_MASK;
+ else
+ tmp &= ~PMU0_PLL0_PC0_PDIV_MASK;
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ /* Write WILD in pllcontrol[1] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ tmp =
+ ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) |
+ (((xt->
+ wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & PMU0_PLL0_PC1_WILD_INT_MASK)
+ | ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) &
+ PMU0_PLL0_PC1_WILD_FRAC_MASK)));
+ if (xt->wbfrac == 0)
+ tmp |= PMU0_PLL0_PC1_STOP_MOD;
+ else
+ tmp &= ~PMU0_PLL0_PC1_STOP_MOD;
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ /* Write WILD in pllcontrol[2] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) |
+ ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) &
+ PMU0_PLL0_PC2_WILD_INT_MASK));
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ PMU_MSG (("Done pll\n"));
+
+ /* Write XtalFreq. Set the divisor also. */
+ tmp = R_REG (osh, &cc->pmucontrol);
+ tmp = ((tmp & ~PCTL_ILP_DIV_MASK) |
+ (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
+ PCTL_ILP_DIV_MASK));
+ tmp = ((tmp & ~PCTL_XTALFREQ_MASK) |
+ ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK));
+ W_REG (osh, &cc->pmucontrol, tmp);
+}
+
+static uint32
+BCMINITFN (sb_pmu0_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
+{
+ const pmu0_xtaltab0_t *xt;
+ uint32 xf;
+
+ /* Find the frequency in the table */
+ xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT;
+ for (xt = pmu0_xtaltab0; xt->freq; xt++)
+ if (xt->xf == xf)
+ break;
+ if (xt->freq == 0)
+ xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
+
+ return xt->freq * 1000;
+}
+
+static uint32
+BCMINITFN (sb_pmu0_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
+{
+ const pmu0_xtaltab0_t *xt;
+ uint32 xf, tmp, divarm;
+#ifdef BCMDBG
+ uint32 pdiv, wbint, wbfrac, fvco;
+#endif
+
+ if (sb_chip (sbh) == BCM5354_CHIP_ID)
+ {
+ /* 5354 gets sb clock of 120MHz from main pll */
+ return 120000000;
+ }
+
+ /* Find the xtal frequency in the table */
+ xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT;
+ for (xt = pmu0_xtaltab0; xt->freq; xt++)
+ if (xt->xf == xf)
+ break;
+ if (xt->freq == 0)
+ xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
+
+ /* Read divarm from pllcontrol[0] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT;
+
+#ifdef BCMDBG
+ /* Calculate Fvco based on xtal freq, pdiv, and wild */
+ pdiv = tmp & PMU0_PLL0_PC0_PDIV_MASK;
+
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ wbfrac =
+ (tmp & PMU0_PLL0_PC1_WILD_FRAC_MASK) >> PMU0_PLL0_PC1_WILD_FRAC_SHIFT;
+ wbint = (tmp & PMU0_PLL0_PC1_WILD_INT_MASK) >> PMU0_PLL0_PC1_WILD_INT_SHIFT;
+
+ W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ wbint +=
+ (tmp & PMU0_PLL0_PC2_WILD_INT_MASK) << PMU0_PLL0_PC2_WILD_INT_SHIFT;
+
+ fvco = (xt->freq * wbint) << 8;
+ fvco += (xt->freq * (wbfrac >> 10)) >> 2;
+ fvco += (xt->freq * (wbfrac & 0x3ff)) >> 10;
+ fvco >>= 8;
+ fvco >>= pdiv;
+ fvco /= 1000;
+ fvco *= 1000;
+
+ PMU_MSG (("sb_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n",
+ wbint, wbfrac, fvco));
+ ASSERT (fvco == PMU0_PLL0_FVCO);
+#endif /* BCMDBG */
+
+ /* Return ARM/SB clock */
+ return PMU0_PLL0_FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
+}
+
+/* PMU corerev 1 pll programming for BCM4325 */
+/* setup pll and query clock speed */
+typedef struct
+{
+ uint16 fref;
+ uint8 xf;
+ uint8 p1div;
+ uint8 p2div;
+ uint8 ndiv_int;
+ uint32 ndiv_frac;
+} pmu1_xtaltab0_t;
+
+/* the following table is based on 880Mhz Fvco */
+#define PMU1_PLL0_FVCO 880000 /* Fvco 880Mhz */
+static const pmu1_xtaltab0_t
+BCMINITDATA (pmu1_xtaltab0)[] =
+{
+ {
+ 12000, 1, 3, 22, 0x9, 0xFFFFEF},
+ {
+ 13000, 2, 1, 6, 0xb, 0x483483},
+ {
+ 14400, 3, 1, 10, 0xa, 0x1C71C7},
+ {
+ 15360, 4, 1, 5, 0xb, 0x755555},
+ {
+ 16200, 5, 1, 10, 0x5, 0x6E9E06},
+ {
+ 16800, 6, 1, 10, 0x5, 0x3Cf3Cf},
+ {
+ 19200, 7, 1, 9, 0x5, 0x17B425},
+ {
+ 19800, 8, 1, 11, 0x4, 0xA57EB},
+ {
+ 20000, 9, 1, 11, 0x4, 0x0},
+ {
+ 24000, 10, 3, 11, 0xa, 0x0},
+ {
+ 25000, 11, 5, 16, 0xb, 0x0},
+ {
+ 26000, 12, 1, 2, 0x10, 0xEC4EC4},
+ {
+ 30000, 13, 3, 8, 0xb, 0x0},
+ {
+ 38400, 14, 1, 5, 0x4, 0x955555},
+ {
+ 40000, 15, 1, 2, 0xb, 0},
+ {
+ 0, 0, 0, 0, 0, 0}
+};
+
+/* Default to 15360Khz crystal */
+#define PMU1_XTAL0_DEFAULT 3
+
+static uint32
+BCMINITFN (sb_pmu1_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
+{
+ const pmu1_xtaltab0_t *xt;
+ uint32 xf;
+
+ /* Find the frequency in the table */
+ xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT;
+ for (xt = pmu1_xtaltab0; xt->fref; xt++)
+ if (xt->xf == xf)
+ break;
+ if (xt->fref == 0)
+ xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
+
+ return xt->fref * 1000;
+}
+
+/* Set up PLL registers in the PMU as per the crystal speed.
+ * Uses xtalfreq variable, or passed-in default.
+ */
+static void
+BCMINITFN (sb_pmu1_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc,
+ uint32 xtal)
+{
+ const pmu1_xtaltab0_t *xt;
+ uint32 tmp;
+ uint32 buf_strength = 0;
+
+ /* 4312: assume default works */
+ if (sbh->chip == BCM4312_CHIP_ID)
+ return;
+
+ /* Find the frequency in the table */
+ for (xt = pmu1_xtaltab0; xt->fref; xt++)
+ if (xt->fref == xtal)
+ break;
+ if (xt->fref == 0)
+ xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
+
+ PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf));
+
+ /* Check current PLL state */
+ if (((R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT) == xt->xf)
+ {
+ PMU_MSG (("PLL already programmed for %d.%d MHz\n",
+ (xt->fref / 1000), (xt->fref % 1000)));
+ return;
+ }
+
+ PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->fref / 1000),
+ (xt->fref % 1000)));
+
+ /* Make sure the PLL is off */
+ switch (sbh->chip)
+ {
+ case BCM4325_CHIP_ID:
+ AND_REG (osh, &cc->min_res_mask,
+ ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) |
+ PMURES_BIT (RES4325_HT_AVAIL)));
+ AND_REG (osh, &cc->max_res_mask,
+ ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) |
+ PMURES_BIT (RES4325_HT_AVAIL)));
+
+ /* Change the BBPLL drive strength to 2 for all channels */
+ buf_strength = 0x222222;
+ break;
+ default:
+ ASSERT (0);
+ }
+ SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL,
+ PMU_MAX_TRANSITION_DLY);
+ ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
+
+ PMU_MSG (("Done masking\n"));
+
+ /* Write p1div and p2div to pllcontrol[0] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ tmp = R_REG (osh, &cc->pllcontrol_data) &
+ ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
+ tmp |=
+ ((xt->
+ p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | ((xt->
+ p2div
+ <<
+ PMU1_PLL0_PC0_P2DIV_SHIFT)
+ &
+ PMU1_PLL0_PC0_P2DIV_MASK);
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ tmp = R_REG (osh, &cc->pllcontrol_data) &
+ ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
+ tmp |=
+ ((xt->
+ ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK)
+ | ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK);
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ /* Write ndiv_frac to pllcontrol[3] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
+ tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
+ PMU1_PLL0_PC3_NDIV_FRAC_MASK);
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+
+ if (buf_strength)
+ {
+ PMU_MSG (("Adjusting PLL buffer drive strength: %x\n", buf_strength));
+
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+ tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
+ tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
+ W_REG (osh, &cc->pllcontrol_data, tmp);
+ }
+
+ PMU_MSG (("Done pll\n"));
+
+ /* Write XtalFreq. Set the divisor also. */
+ tmp = R_REG (osh, &cc->pmucontrol) &
+ ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
+ tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
+ PCTL_ILP_DIV_MASK) |
+ ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
+ W_REG (osh, &cc->pmucontrol, tmp);
+}
+
+
+static uint32
+BCMINITFN (sb_pmu1_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc)
+{
+ const pmu1_xtaltab0_t *xt;
+ uint32 xf, tmp, m1div;
+#ifdef BCMDBG
+ uint32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
+#endif
+
+ /* Find the xtal frequency in the table */
+ xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+ PCTL_XTALFREQ_SHIFT;
+ for (xt = pmu1_xtaltab0; xt->fref; xt++)
+ if (xt->xf == xf)
+ break;
+ if (xt->fref == 0)
+ xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
+
+ /* Read m1div from pllcontrol[1] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
+
+#ifdef BCMDBG
+ /* Read p2div/p1div from pllcontrol[0] */
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
+ p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
+
+ /* Calculate Fvco based on xtal freq and ndiv and pdiv */
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ ndiv_int =
+ (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
+
+ W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+ tmp = R_REG (osh, &cc->pllcontrol_data);
+ ndiv_frac =
+ (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
+
+ fvco = (xt->fref * ndiv_int) << 8;
+ fvco += (xt->fref * (ndiv_frac >> 12)) >> 4;
+ fvco += (xt->fref * (ndiv_frac & 0xfff)) >> 12;
+ fvco >>= 8;
+ fvco *= p2div;
+ fvco /= p1div;
+ fvco /= 1000;
+ fvco *= 1000;
+
+ PMU_MSG (("sb_pmu0_cpuclk0: ndiv_int %u ndiv_frac %u "
+ "p2div %u p1div %u fvco %u\n",
+ ndiv_int, ndiv_frac, p2div, p1div, fvco));
+ ASSERT (fvco == PMU1_PLL0_FVCO);
+#endif /* BCMDBG */
+
+ /* Return ARM/SB clock */
+ return PMU1_PLL0_FVCO / m1div * 1000;
+}
+
+void BCMINITFN (sb_pmu_pll_init) (sb_t * sbh, osl_t * osh, uint xtalfreq)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq);
+ break;
+ case BCM5354_CHIP_ID:
+ sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq);
+ break;
+ case BCM4325_CHIP_ID:
+ sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq);
+ break;
+ case BCM4312_CHIP_ID:
+ sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq);
+ break;
+ default:
+ PMU_MSG (("No PLL init done for chip %x rev %d pmurev %d\n",
+ sbh->chip, sbh->chiprev, sbh->pmurev));
+ break;
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
+
+uint32 BCMINITFN (sb_pmu_alp_clock) (sb_t * sbh, osl_t * osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 clock = ALP_CLOCK;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ clock = sb_pmu0_alpclk0 (sbh, osh, cc);
+ break;
+ case BCM5354_CHIP_ID:
+ clock = sb_pmu0_alpclk0 (sbh, osh, cc);
+ break;
+ case BCM4325_CHIP_ID:
+ clock = sb_pmu1_alpclk0 (sbh, osh, cc);
+ break;
+ case BCM4312_CHIP_ID:
+ clock = sb_pmu1_alpclk0 (sbh, osh, cc);
+ /* always 20Mhz */
+ clock = 20000 * 1000;
+ break;
+ default:
+ PMU_MSG (("No ALP clock specified "
+ "for chip %x rev %d pmurev %d, using default %d Hz\n",
+ sbh->chip, sbh->chiprev, sbh->pmurev, clock));
+ break;
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+ return clock;
+}
+
+uint BCMINITFN (sb_pmu_cpu_clock) (sb_t * sbh, osl_t * osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+ uint32 clock = HT_CLOCK;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ switch (sbh->chip)
+ {
+ case BCM4328_CHIP_ID:
+ clock = sb_pmu0_cpuclk0 (sbh, osh, cc);
+ break;
+ case BCM5354_CHIP_ID:
+ clock = sb_pmu0_cpuclk0 (sbh, osh, cc);
+ break;
+ case BCM4325_CHIP_ID:
+ clock = sb_pmu1_cpuclk0 (sbh, osh, cc);
+ break;
+ case BCM4312_CHIP_ID:
+ clock = sb_pmu1_cpuclk0 (sbh, osh, cc);
+ break;
+ default:
+ PMU_MSG (("No CPU clock specified "
+ "for chip %x rev %d pmurev %d, using default %d Hz\n",
+ sbh->chip, sbh->chiprev, sbh->pmurev, clock));
+ break;
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+ return clock;
+}
+
+void BCMINITFN (sb_pmu_init) (sb_t * sbh, osl_t * osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ if (sbh->pmurev >= 1)
+ {
+ if (sbh->chip == BCM4325_CHIP_ID && sbh->chiprev <= 1)
+ AND_REG (osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
+ else
+ OR_REG (osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT);
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
+
+void BCMINITFN (sb_pmu_otp_power) (sb_t * sbh, osl_t * osh, bool on)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ switch (sbh->chip)
+ {
+ case BCM4325_CHIP_ID:
+ if (on)
+ {
+ OR_REG (osh, &cc->min_res_mask, PMURES_BIT (RES4325_LNLDO2_PU));
+ if (sbh->boardflags & BFL_BUCKBOOST)
+ AND_REG (osh, &cc->min_res_mask,
+ ~PMURES_BIT (RES4325_BUCK_BOOST_PWM));
+ OSL_DELAY (500);
+ }
+ else
+ {
+ if (sbh->boardflags & BFL_BUCKBOOST)
+ OR_REG (osh, &cc->min_res_mask,
+ PMURES_BIT (RES4325_BUCK_BOOST_PWM));
+ AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4325_LNLDO2_PU));
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
+
+void
+sb_pmu_rcal (sb_t * sbh, osl_t * osh)
+{
+ chipcregs_t *cc;
+ uint origidx;
+
+ ASSERT (sbh->cccaps & CC_CAP_PMU);
+
+ /* Remember original core before switch to chipc */
+ origidx = sb_coreidx (sbh);
+ cc = sb_setcore (sbh, SB_CC, 0);
+ ASSERT (cc);
+
+ switch (sbh->chip)
+ {
+ case BCM4325_CHIP_ID:
+ {
+ uint8 rcal_code;
+ uint32 val;
+
+ /* Kick RCal */
+ W_REG (osh, &cc->chipcontrol_addr, 1);
+ AND_REG (osh, &cc->chipcontrol_data, ~0x04);
+ OR_REG (osh, &cc->chipcontrol_data, 0x04);
+
+ /* Wait for completion */
+ SPINWAIT (0 == (R_REG (osh, &cc->chipstatus) & 0x08),
+ 10 * 1000 * 1000);
+ ASSERT (R_REG (osh, &cc->chipstatus) & 0x08);
+
+ /* Drop the LSB to convert from 5 bit code to 4 bit code */
+ rcal_code = (uint8) (R_REG (osh, &cc->chipstatus) >> 5) & 0x0f;
+ PMU_MSG (("RCal completed, status 0x%x, code 0x%x\n",
+ R_REG (osh, &cc->chipstatus), rcal_code));
+
+ /* Write RCal code into pmu_vreg_ctrl[32:29] */
+ W_REG (osh, &cc->regcontrol_addr, 0);
+ val = R_REG (osh, &cc->regcontrol_data) & ~((uint32) 0x07 << 29);
+ val |= (uint32) (rcal_code & 0x07) << 29;
+ W_REG (osh, &cc->regcontrol_data, val);
+ W_REG (osh, &cc->regcontrol_addr, 1);
+ val = R_REG (osh, &cc->regcontrol_data) & ~(uint32) 0x01;
+ val |= (uint32) ((rcal_code >> 3) & 0x01);
+ W_REG (osh, &cc->regcontrol_data, val);
+
+ /* Write RCal code into pmu_chip_ctrl[33:30] */
+ W_REG (osh, &cc->chipcontrol_addr, 0);
+ val = R_REG (osh, &cc->chipcontrol_data) & ~((uint32) 0x03 << 30);
+ val |= (uint32) (rcal_code & 0x03) << 30;
+ W_REG (osh, &cc->chipcontrol_data, val);
+ W_REG (osh, &cc->chipcontrol_addr, 1);
+ val = R_REG (osh, &cc->chipcontrol_data) & ~(uint32) 0x03;
+ val |= (uint32) ((rcal_code >> 2) & 0x03);
+ W_REG (osh, &cc->chipcontrol_data, val);
+
+ /* Set override in pmu_chip_ctrl[29] */
+ W_REG (osh, &cc->chipcontrol_addr, 0);
+ OR_REG (osh, &cc->chipcontrol_data, (0x01 << 29));
+
+ /* Power off RCal block */
+ W_REG (osh, &cc->chipcontrol_addr, 1);
+ AND_REG (osh, &cc->chipcontrol_data, ~0x04);
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Return to original core */
+ sb_setcoreidx (sbh, origidx);
+}
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdefs.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdefs.h
index 8b5abe5d26..9cb669bd91 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdefs.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdefs.h
@@ -101,6 +101,8 @@ extern bool bcmreclaimed;
*/
#define BCMDONGLEHDRSZ 8
+/* Max. nvram variable table size */
+#define MAXSZ_NVRAM_VARS 4096
#endif /* _bcmdefs_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdevs.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdevs.h
index 2e80658da3..f03e0b6b1b 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdevs.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmdevs.h
@@ -1,22 +1,20 @@
/*
* Broadcom device-specific manifest constants.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: bcmdevs.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $
+ * $Id$
*/
#ifndef _BCMDEVS_H
#define _BCMDEVS_H
-#include "bcm4710.h"
-
-/* Known PCI vendor Id's */
+/* PCI vendor IDs */
#define VENDOR_EPIGRAM 0xfeda
#define VENDOR_BROADCOM 0x14e4
#define VENDOR_3COM 0x10b7
@@ -25,24 +23,63 @@
#define VENDOR_DELL 0x1028
#define VENDOR_HP 0x0e11
#define VENDOR_APPLE 0x106b
+#define VENDOR_SI_IMAGE 0x1095 /* Silicon Image, used by Arasan SDIO Host */
+#define VENDOR_BUFFALO 0x1154 /* Buffalo vendor id */
+#define VENDOR_TI 0x104c /* Texas Instruments */
+
+/* PCMCIA vendor IDs */
+#define VENDOR_BROADCOM_PCMCIA 0x02d0
+
+/* SDIO vendor IDs */
+#define VENDOR_BROADCOM_SDIO 0x00BF
-/* PCI Device Id's */
+/* PCI Device IDs */
#define BCM4210_DEVICE_ID 0x1072 /* never used */
-#define BCM4211_DEVICE_ID 0x4211
#define BCM4230_DEVICE_ID 0x1086 /* never used */
+#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
+#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
+#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
+#define BCM4211_DEVICE_ID 0x4211
#define BCM4231_DEVICE_ID 0x4231
-
+#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
+#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */
+#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */
+#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */
+#define BCM4328_D11DUAL_ID 0x4314 /* 4328 802.11a/g id */
+#define BCM4328_D11G_ID 0x4315 /* 4328 802.11g 2.4Ghz band id */
+#define BCM4328_D11A_ID 0x4316 /* 4328 802.11a 5Ghz band id */
+#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */
+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */
+#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */
+#define BCM4325_D11DUAL_ID 0x431b /* 4325 802.11a/g id */
+#define BCM4325_D11G_ID 0x431c /* 4325 802.11g 2.4Ghz band id */
+#define BCM4325_D11A_ID 0x431d /* 4325 802.11a 5Ghz band id */
+#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
+#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
+#define BCM4306_UART_ID 0x4322 /* 4306 uart */
+#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
+#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
+#define BCM4306_D11G_ID2 0x4325
+#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */
+#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Ghz band id */
+#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */
+#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
+#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
+#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */
+#define BCM_JTAGM_ID 0x43f1 /* BCM jtagm device id */
+#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */
+#define BCM_SDIOH_ID 0x43f3 /* BCM sdio host id */
+#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */
+#define SPIH_FPGA_ID 0x43f5 /* PCI SPI Host Controller FPGA */
+#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */
+#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
+#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
-#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
+#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
-
-#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
-#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
-
-#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
-#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
-
+#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
+#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
@@ -57,114 +94,83 @@
#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */
#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */
#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */
-
+#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */
#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */
+#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
+#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
+#define JINVANI_SDIOH_ID 0x4743 /* Jinvani SDIO Gold Host */
+#define BCM27XX_SDIOH_ID 0x2702 /* BCM27xx Standard SDIO Host */
+#define PCIXX21_FLASHMEDIA_ID 0x803b /* TI PCI xx21 Standard Host Controller */
+#define PCIXX21_SDIOH_ID 0x803c /* TI PCI xx21 Standard Host Controller */
+/* Chip IDs */
#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid returned by sb_chip() */
-#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
-
#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */
-#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
-#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
-#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
-
#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */
-#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
-#define BCM4306_D11G_ID2 0x4325
-#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
-#define BCM4306_UART_ID 0x4322 /* 4306 uart */
-#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
-#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
-
-#define BCM4309_PKG_ID 1 /* 4309 package id */
-
#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */
-#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */
-#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */
-#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */
-
-#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
-#define BCM4303_PKG_ID 2 /* 4303 package id */
-
-#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
-#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
-
#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */
-#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
-
+#define BCM4312_CHIP_ID 0x4312 /* 4312 chip common chipid */
#define BCM4318_CHIP_ID 0x4318 /* 4318 chip common chipid */
-#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */
-#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */
-#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */
-
#define BCM4321_CHIP_ID 0x4321 /* 4321 chip common chipid */
-#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */
-#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Hgz band id */
-#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */
-
-#define BCM4331_CHIP_ID 0x4331 /* 4331 chip common chipid */
-#define BCM4331_D11N2G_ID 0x4330 /* 4331 802.11n 2.4Ghz band id */
-#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */
-#define BCM4331_D11N5G_ID 0x4332 /* 4331 802.11n 5Ghz band id */
-
-#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
-#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
-#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
-
+#define BCM4328_CHIP_ID 0x4328 /* 4328 chip common chipid */
+#define BCM4325_CHIP_ID 0x4325 /* 4325 chip common chipid */
#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */
-#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
-#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
-#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
-#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
-
#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */
#define BCM5350_CHIP_ID 0x5350 /* bcm5350 chipcommon chipid */
#define BCM5352_CHIP_ID 0x5352 /* bcm5352 chipcommon chipid */
-
+#define BCM5354_CHIP_ID 0x5354 /* bcm5354 chipcommon chipid */
#define BCM4320_CHIP_ID 0x4320 /* bcm4320 chipcommon chipid */
-
-#define BCM4328_CHIP_ID 0x4328 /* bcm4328 chipcommon chipid */
-
-#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */
-#define BCM43XX_JTAGM_ID 0x43f1 /* 43xx jtagm device id */
-#define BCM43XXOLD_JTAGM_ID 0x4331 /* 43xx old jtagm device id */
-
-#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */
-#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */
-
-#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */
-
#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */
-/* PCMCIA vendor Id's */
-
-#define VENDOR_BROADCOM_PCMCIA 0x02d0
-
-/* SDIO vendor Id's */
-#define VENDOR_BROADCOM_SDIO 0x00BF
-
+/* Package IDs */
+#define BCM4303_PKG_ID 2 /* 4303 package id */
+#define BCM4309_PKG_ID 1 /* 4309 package id */
+#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
+#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
+#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
+#define BCM4328USBD11G_PKG_ID 2 /* 4328 802.11g USB package id */
+#define BCM4328USBDUAL_PKG_ID 3 /* 4328 802.11a/g USB package id */
+#define BCM4328SDIOD11G_PKG_ID 4 /* 4328 802.11g SDIO package id */
+#define BCM4328SDIODUAL_PKG_ID 5 /* 4328 802.11a/g SDIO package id */
+#define BCM5354E_PKG_ID 1 /* 5354E package id */
+#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
+#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
+#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
+#define PCIXX21_FLASHMEDIA0_ID 0x8033 /* TI PCI xx21 Standard Host Controller */
+#define PCIXX21_SDIOH0_ID 0x8034 /* TI PCI xx21 Standard Host Controller */
/* boardflags */
-#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
-#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
-#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
-#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */
-#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
-#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
-#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */
-#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
-#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
-#define BFL_FEM 0x0800 /* This board supports the Front End Module */
-#define BFL_EXTLNA 0x1000 /* This board has an external LNA */
-#define BFL_HGPA 0x2000 /* This board has a high gain PA */
-#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */
-#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */
-
+#define BFL_BTCOEXIST 0x00000001 /* This board implements Bluetooth coexistance */
+#define BFL_PACTRL 0x00000002 /* This board has gpio 9 controlling the PA */
+#define BFL_AIRLINEMODE 0x00000004 /* This board implements gpio13 radio disable indication */
+#define BFL_ADCDIV 0x00000008 /* This board has the rssi ADC divider */
+#define BFL_ENETROBO 0x00000010 /* This board has robo switch or core */
+#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */
+#define BFL_CCKHIPWR 0x00000040 /* Can do high-power CCK transmission */
+#define BFL_ENETADM 0x00000080 /* This board has ADMtek switch */
+#define BFL_ENETVLAN 0x00000100 /* This board has vlan capability */
+#define BFL_AFTERBURNER 0x00000200 /* This board supports Afterburner mode */
+#define BFL_NOPCI 0x00000400 /* This board leaves PCI floating */
+#define BFL_FEM 0x00000800 /* This board supports the Front End Module */
+#define BFL_EXTLNA 0x00001000 /* This board has an external LNA */
+#define BFL_HGPA 0x00002000 /* This board has a high gain PA */
+#define BFL_BTCMOD 0x00004000 /* This board' BTCOEXIST is in the alternate gpios */
+#define BFL_ALTIQ 0x00008000 /* Alternate I/Q settings */
+#define BFL_NOPA 0x00010000 /* This board has no PA */
+#define BFL_RSSIINV 0x00020000 /* This board's RSSI uses positive slope */
+#define BFL_PAREF 0x00040000 /* This board uses the PARef LDO */
+#define BFL_3TSWITCH 0x00080000 /* This board uses a triple throw switch shared with BT */
+#define BFL_PHASESHIFTER 0x00100000 /* This board can support phase shifter */
+#define BFL_BUCKBOOST 0x00200000 /* This board has buck/booster */
/* boardflags2 */
#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* This board has an external rxbb regulator */
-#define BFL2_SSWITCH_AVAIL 0x00000002 /* This board has a superswitch for > 2 antennas */
-#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits TX Power Control to be enabled */
+#define BFL2_DEPRECIATED_STUB 0x00000002 /* This board flag is depreciated */
+#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits enabling TX Power Control */
+#define BFL2_2X4_DIV 0x00000008 /* This board supports the 2X4 diversity switch */
+#define BFL2_5G_PWRGAIN 0x00000010 /* This board supports 5G band power gain */
+#define BFL2_PCIEWAR_OVR 0x00000020 /* This board overrides ASPM and Clkreq settings */
+#define BFL2_CAESERS_BRD 0x00000040 /* This board is Dell Caeser's brd (unused by sw) */
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */
@@ -172,6 +178,9 @@
#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
+#define BOARD_GPIO_ANT0_SEL 0x100 /* With BFL2_2X4_DIV */
+#define BOARD_GPIO_ANT1_SEL 0x200 /* With BFL2_2X4_DIV */
+
#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
@@ -184,7 +193,6 @@
#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
/* Reference Board Types */
-
#define BU4710_BOARD 0x0400
#define VSIM4710_BOARD 0x0401
#define QT4710_BOARD 0x0402
@@ -259,6 +267,7 @@
/* BCM63XX boards */
#define BCM96338_BOARD 0x6338
#define BCM96348_BOARD 0x6348
+#define BCM96358_BOARD 0x6358
/* Another mp4306 with SiGe */
#define BCM94306P_BOARD 0x044c
@@ -333,6 +342,18 @@
#define CB2_4321_BOARD 0x046d
#define MC4321_BOARD 0x046e
+/* 4328 boards */
+#define BU4328_BOARD 0x0481
+#define BCM4328SDG_BOARD 0x0482
+#define BCM4328SDAG_BOARD 0x0483
+#define BCM4328UG_BOARD 0x0484
+#define BCM4328UAG_BOARD 0x0485
+#define BCM4328PC_BOARD 0x0486
+#define BCM4328CF_BOARD 0x0487
+
+/* 4325 boards */
+#define BU4325_BOARD 0x0490
+
/* # of GPIO pins */
#define GPIO_NUMPINS 16
@@ -358,6 +379,10 @@
#define BCM2062_IDCODE 0x02062000
#define BCM2062A0_IDCODE 0x0206217f
+#define BCM2063_ID 0x2063
+#define BCM2063_IDCODE 0x02063000
+#define BCM2063A0_IDCODE 0x0206317f
+
/* parts of an idcode: */
#define IDCODE_MFG_MASK 0x00000fff
#define IDCODE_MFG_SHIFT 0
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmendian.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmendian.h
index 906129c82e..0f68451132 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmendian.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmendian.h
@@ -1,7 +1,7 @@
/*
* local version of endian.h - byte order defines
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: bcmendian.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _BCMENDIAN_H_
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmnvram.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmnvram.h
index c713b4be69..f6754b6fb3 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmnvram.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmnvram.h
@@ -1,7 +1,7 @@
/*
* NVRAM variable manipulation
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: bcmnvram.h,v 1.17 2006/03/02 12:33:44 honor Exp $
+ * $Id$
*/
#ifndef _bcmnvram_h_
@@ -35,10 +35,19 @@ struct nvram_tuple {
};
/*
- * Initialize NVRAM access. May be unnecessary or undefined on certain
- * platforms.
+ * Get default value for an NVRAM variable
+ */
+extern char *nvram_default_get(const char *name);
+
+/*
+ * Append a chunk of nvram variables to the global list
+ */
+extern int nvram_append(void *sb, char *vars, uint varsz);
+
+/*
+ * Check for reset button press for restoring factory defaults.
*/
-extern int nvram_init(void *sbh);
+extern bool nvram_reset(void *sbh);
/*
* Disable NVRAM access. May be unnecessary or undefined on certain
@@ -59,8 +68,6 @@ extern char * nvram_get(const char *name);
* as input
*/
extern int BCMINITFN(nvram_resetgpio_init)(void *sbh);
-extern int BCMINITFN(nvram_gpio_init)(const char *name, void *sbh);
-extern int BCMINITFN(nvram_gpio_set)(const char *name, void *sbh, int type);
/*
* Get the value of an NVRAM variable.
@@ -69,16 +76,6 @@ extern int BCMINITFN(nvram_gpio_set)(const char *name, void *sbh, int type);
*/
#define nvram_safe_get(name) (nvram_get(name) ? : "")
-#define nvram_safe_unset(name) ({ \
- if(nvram_get(name)) \
- nvram_unset(name); \
-})
-
-#define nvram_safe_set(name, value) ({ \
- if(!nvram_get(name) || strcmp(nvram_get(name), value)) \
- nvram_set(name, value); \
-})
-
/*
* Match an NVRAM variable.
* @param name name of variable to match
@@ -139,15 +136,24 @@ extern int nvram_commit(void);
* @param count size of buffer in bytes
* @return 0 on success and errno on failure
*/
-extern int nvram_getall(char *buf, int count);
+extern int nvram_getall(char *nvram_buf, int count);
-extern int file2nvram(char *filename, char *varname);
-extern int nvram2file(char *varname, char *filename);
+/*
+ * returns the crc value of the nvram
+ * @param nvh nvram header pointer
+ */
+extern uint8 nvram_calc_crc(struct nvram_header * nvh);
+
+extern char* getvar(char *vars, const char *name);
+extern int getintvar(char *vars, const char *name);
#endif /* _LANGUAGE_ASSEMBLY */
+/* The NVRAM version number stored as an NVRAM variable */
+#define NVRAM_SOFTWARE_VERSION "1"
+
#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
-#define NVRAM_CLEAR_MAGIC 0x0
+#define NVRAM_CLEAR_MAGIC 0x0
#define NVRAM_INVALID_MAGIC 0xFFFFFFFF
#define NVRAM_VERSION 1
#define NVRAM_HEADER_SIZE 20
@@ -156,4 +162,7 @@ extern int nvram2file(char *varname, char *filename);
#define NVRAM_MAX_VALUE_LEN 255
#define NVRAM_MAX_PARAM_LEN 64
+#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */
+#define NVRAM_CRC_VER_MASK 0xffffff00 /* for crc_ver_init */
+
#endif /* _bcmnvram_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmsrom.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmsrom.h
index 4f99e95914..1db4fbd638 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmsrom.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmsrom.h
@@ -1,7 +1,7 @@
/*
* Misc useful routines to access NIC local SROM/OTP .
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,14 +9,93 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: bcmsrom.h,v 1.1.1.13 2006/04/15 01:29:08 michael Exp $
+ * $Id$
*/
#ifndef _bcmsrom_h_
#define _bcmsrom_h_
/* Maximum srom: 4 Kilobits == 512 bytes */
-#define SROM_MAX 512
+#define SROM_MAX 512
+
+
+#define SROM_WORDS 64
+
+#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */
+
+#define SROM_SSID 2
+
+#define SROM_WL1LHMAXP 29
+
+#define SROM_WL1LPAB0 30
+#define SROM_WL1LPAB1 31
+#define SROM_WL1LPAB2 32
+
+#define SROM_WL1HPAB0 33
+#define SROM_WL1HPAB1 34
+#define SROM_WL1HPAB2 35
+
+#define SROM_MACHI_IL0 36
+#define SROM_MACMID_IL0 37
+#define SROM_MACLO_IL0 38
+#define SROM_MACHI_ET0 39
+#define SROM_MACMID_ET0 40
+#define SROM_MACLO_ET0 41
+#define SROM_MACHI_ET1 42
+#define SROM_MACMID_ET1 43
+#define SROM_MACLO_ET1 44
+#define SROM3_MACHI 37
+#define SROM3_MACMID 38
+#define SROM3_MACLO 39
+
+#define SROM_BXARSSI2G 40
+#define SROM_BXARSSI5G 41
+
+#define SROM_TRI52G 42
+#define SROM_TRI5GHL 43
+
+#define SROM_RXPO52G 45
+
+#define SROM2_ENETPHY 45
+
+#define SROM_AABREV 46
+/* Fields in AABREV */
+#define SROM_BR_MASK 0x00ff
+#define SROM_CC_MASK 0x0f00
+#define SROM_CC_SHIFT 8
+#define SROM_AA0_MASK 0x3000
+#define SROM_AA0_SHIFT 12
+#define SROM_AA1_MASK 0xc000
+#define SROM_AA1_SHIFT 14
+
+#define SROM_WL0PAB0 47
+#define SROM_WL0PAB1 48
+#define SROM_WL0PAB2 49
+
+#define SROM_LEDBH10 50
+#define SROM_LEDBH32 51
+
+#define SROM_WL10MAXP 52
+
+#define SROM_WL1PAB0 53
+#define SROM_WL1PAB1 54
+#define SROM_WL1PAB2 55
+
+#define SROM_ITT 56
+
+#define SROM_BFL 57
+#define SROM_BFL2 28
+#define SROM3_BFL2 61
+
+#define SROM_AG10 58
+
+#define SROM_CCODE 59
+
+#define SROM_OPO 60
+
+#define SROM3_LEDDC 62
+
+#define SROM_CRCREV 63
/* SROM Rev 4: Reallocate the software part of the srom to accomodate
* MIMO features. It assumes up to two PCIE functions and 440 bytes
@@ -35,18 +114,30 @@
#define SROM4_BFL1 35
#define SROM4_BFL2 36
#define SROM4_BFL3 37
+#define SROM5_BFL0 37
+#define SROM5_BFL1 38
+#define SROM5_BFL2 39
+#define SROM5_BFL3 40
#define SROM4_MACHI 38
#define SROM4_MACMID 39
#define SROM4_MACLO 40
+#define SROM5_MACHI 41
+#define SROM5_MACMID 42
+#define SROM5_MACLO 43
#define SROM4_CCODE 41
#define SROM4_REGREV 42
+#define SROM5_CCODE 34
+#define SROM5_REGREV 35
#define SROM4_LEDBH10 43
#define SROM4_LEDBH32 44
+#define SROM5_LEDBH10 59
+#define SROM5_LEDBH32 60
#define SROM4_LEDDC 45
+#define SROM5_LEDDC 45
#define SROM4_AA 46
#define SROM4_AA2G_MASK 0x00ff
@@ -62,6 +153,14 @@
#define SROM4_TXPID5GL 53
#define SROM4_TXPID5GH 55
+#define SROM4_TXRXC 61
+#define SROM4_TXCHAIN_MASK 0x000f
+#define SROM4_TXCHAIN_SHIFT 0
+#define SROM4_RXCHAIN_MASK 0x00f0
+#define SROM4_RXCHAIN_SHIFT 4
+#define SROM4_SWITCH_MASK 0xff00
+#define SROM4_SWITCH_SHIFT 8
+
/* Per-path fields */
#define MAX_PATH 4
#define SROM4_PATH0 64
@@ -95,14 +194,117 @@
#define SROM4_5G_MCSPO 173
#define SROM4_5GL_MCSPO 181
#define SROM4_5GH_MCSPO 189
-#define SROM4_CCDPO 197
+#define SROM4_CDDPO 197
#define SROM4_STBCPO 198
#define SROM4_BW40PO 199
#define SROM4_BWDUPPO 200
-extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, uint *count);
+#define SROM4_CRCREV 219
+
+
+/*SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
+ * This is acombined srom for both MIMO and SISO boards, usable in
+ * the .130 4Kilobit OTP with hardware redundancy.
+ */
+
+#define SROM8_SIGN 64
+
+#define SROM8_BREV 65
+
+#define SROM8_BFL0 66
+#define SROM8_BFL1 67
+#define SROM8_BFL2 68
+#define SROM8_BFL3 69
+
+#define SROM8_MACHI 70
+#define SROM8_MACMID 71
+#define SROM8_MACLO 72
+
+#define SROM8_CCODE 73
+#define SROM8_REGREV 74
+
+#define SROM8_LEDBH10 75
+#define SROM8_LEDBH32 76
+
+#define SROM8_LEDDC 77
+
+#define SROM8_AA 78
+
+#define SROM8_AG10 79
+#define SROM8_AG32 80
+
+#define SROM8_TXRXC 81
+
+#define SROM8_BXARSSI2G 82
+#define SROM8_BXARSSI5G 83
+#define SROM8_TRI52G 84
+#define SROM8_TRI5GHL 85
+#define SROM8_RXPO52G 86
+
+/* Per-path offsets & fields */
+#define SROM8_PATH0 96
+#define SROM8_PATH1 112
+#define SROM8_PATH2 128
+#define SROM8_PATH3 144
+
+#define SROM8_2G_ITT_MAXP 0
+#define SROM8_2G_PA 1
+#define SROM8_5G_ITT_MAXP 4
+#define SROM8_5GLH_MAXP 5
+#define SROM8_5G_PA 6
+#define SROM8_5GL_PA 9
+#define SROM8_5GH_PA 12
+
+/* All the miriad power offsets */
+#define SROM8_2G_CCKPO 160
+
+#define SROM8_2G_OFDMPO 161
+#define SROM8_5G_OFDMPO 163
+#define SROM8_5GL_OFDMPO 165
+#define SROM8_5GH_OFDMPO 167
+
+#define SROM8_2G_MCSPO 169
+#define SROM8_5G_MCSPO 177
+#define SROM8_5GL_MCSPO 185
+#define SROM8_5GH_MCSPO 193
+
+#define SROM8_CDDPO 201
+#define SROM8_STBCPO 202
+#define SROM8_BW40PO 203
+#define SROM8_BWDUPPO 204
+
+/* SISO PA parameters are in the path0 spaces */
+#define SROM8_SISO 96
+
+/* Legacy names for SISO PA paramters */
+#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
+#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
+#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
+#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
+#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
+#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
+#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
+#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
+#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
+#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
+#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
+#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
+#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
+#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
+#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
+
+#define SROM8_CRCREV 219
+
+/* Prototypes */
+extern int srom_var_init(sb_t *sbh, uint bus, void *curmap, osl_t *osh,
+ char **vars, uint *count);
+
+extern int srom_read(sb_t *sbh, uint bus, void *curmap, osl_t *osh,
+ uint byteoff, uint nbytes, uint16 *buf);
+extern int srom_write(sb_t *sbh, uint bus, void *curmap, osl_t *osh,
+ uint byteoff, uint nbytes, uint16 *buf);
-extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
-extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
+extern int srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt,
+ char **vars, uint *count);
#endif /* _bcmsrom_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmutils.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmutils.h
deleted file mode 100644
index b200f62364..0000000000
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/bcmutils.h
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Misc useful os-independent macros and functions.
- *
- * Copyright 2006, Broadcom Corporation
- * All Rights Reserved.
- *
- * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
- * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
- * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $
- */
-
-#ifndef _bcmutils_h_
-#define _bcmutils_h_
-
-/* ** driver-only section ** */
-#ifdef BCMDRIVER
-
-#define _BCM_U 0x01 /* upper */
-#define _BCM_L 0x02 /* lower */
-#define _BCM_D 0x04 /* digit */
-#define _BCM_C 0x08 /* cntrl */
-#define _BCM_P 0x10 /* punct */
-#define _BCM_S 0x20 /* white space (space/lf/tab) */
-#define _BCM_X 0x40 /* hex digit */
-#define _BCM_SP 0x80 /* hard space (0x20) */
-
-#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */
-
-extern unsigned char bcm_ctype[];
-#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
-
-#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
-#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
-#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
-#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
-#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
-#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
-#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
-#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
-#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
-#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
-#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
-
-/*
- * Spin at most 'us' microseconds while 'exp' is true.
- * Caller should explicitly test 'exp' when this completes
- * and take appropriate error action if 'exp' is still true.
- */
-#define SPINWAIT(exp, us) { \
- uint countdown = (us) + 9; \
- while ((exp) && (countdown >= 10)) {\
- OSL_DELAY(10); \
- countdown -= 10; \
- } \
-}
-
-struct ether_addr {
- uint8 octet[6];
-} __attribute__((packed));
-
-/* string */
-extern uchar bcm_toupper(uchar c);
-extern ulong bcm_strtoul(char *cp, char **endp, uint base);
-extern char *bcmstrstr(char *haystack, char *needle);
-extern char *bcmstrcat(char *dest, const char *src);
-extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
-/* ethernet address */
-extern char *bcm_ether_ntoa(struct ether_addr *ea, char *buf);
-/* variable access */
-extern char *getvar(char *vars, char *name);
-extern int getintvar(char *vars, char *name);
-extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
-#ifdef BCMPERFSTATS
-extern void bcm_perf_enable(void);
-extern void bcmstats(char *fmt);
-extern void bcmlog(char *fmt, uint a1, uint a2);
-extern void bcmdumplog(char *buf, int size);
-extern int bcmdumplogent(char *buf, uint idx);
-#else
-#define bcm_perf_enable()
-#define bcmstats(fmt)
-#define bcmlog(fmt, a1, a2)
-#define bcmdumplog(buf, size) *buf = '\0'
-#define bcmdumplogent(buf, idx) -1
-#endif /* BCMPERFSTATS */
-extern char *bcm_nvram_vars(uint *length);
-extern int bcm_nvram_cache(void *sbh);
-
-/* Support for sharing code across in-driver iovar implementations.
- * The intent is that a driver use this structure to map iovar names
- * to its (private) iovar identifiers, and the lookup function to
- * find the entry. Macros are provided to map ids and get/set actions
- * into a single number space for a switch statement.
- */
-
-/* iovar structure */
-typedef struct bcm_iovar {
- const char *name; /* name for lookup and display */
- uint16 varid; /* id for switch */
- uint16 flags; /* driver-specific flag bits */
- uint16 type; /* base type of argument */
- uint16 minlen; /* min length for buffer vars */
-} bcm_iovar_t;
-
-/* varid definitions are per-driver, may use these get/set bits */
-
-/* IOVar action bits for id mapping */
-#define IOV_GET 0 /* Get an iovar */
-#define IOV_SET 1 /* Set an iovar */
-
-/* Varid to actionid mapping */
-#define IOV_GVAL(id) ((id)*2)
-#define IOV_SVAL(id) (((id)*2)+IOV_SET)
-#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
-
-/* flags are per-driver based on driver attributes */
-
-/* Base type definitions */
-#define IOVT_VOID 0 /* no value (implictly set only) */
-#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
-#define IOVT_INT8 2 /* integer values are range-checked */
-#define IOVT_UINT8 3 /* unsigned int 8 bits */
-#define IOVT_INT16 4 /* int 16 bits */
-#define IOVT_UINT16 5 /* unsigned int 16 bits */
-#define IOVT_INT32 6 /* int 32 bits */
-#define IOVT_UINT32 7 /* unsigned int 32 bits */
-#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
-
-extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name);
-extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set);
-
-#endif /* #ifdef BCMDRIVER */
-
-/* ** driver/apps-shared section ** */
-
-#define BCME_STRLEN 64 /* Max string length for BCM errors */
-#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
-
-
-/*
- * error codes could be added but the defined ones shouldn't be changed/deleted
- * these error codes are exposed to the user code
- * when ever a new error code is added to this list
- * please update errorstring table with the related error string and
- * update osl files with os specific errorcode map
-*/
-
-#define BCME_OK 0 /* Success */
-#define BCME_ERROR -1 /* Error generic */
-#define BCME_BADARG -2 /* Bad Argument */
-#define BCME_BADOPTION -3 /* Bad option */
-#define BCME_NOTUP -4 /* Not up */
-#define BCME_NOTDOWN -5 /* Not down */
-#define BCME_NOTAP -6 /* Not AP */
-#define BCME_NOTSTA -7 /* Not STA */
-#define BCME_BADKEYIDX -8 /* BAD Key Index */
-#define BCME_RADIOOFF -9 /* Radio Off */
-#define BCME_NOTBANDLOCKED -10 /* Not band locked */
-#define BCME_NOCLK -11 /* No Clock */
-#define BCME_BADRATESET -12 /* BAD Rate valueset */
-#define BCME_BADBAND -13 /* BAD Band */
-#define BCME_BUFTOOSHORT -14 /* Buffer too short */
-#define BCME_BUFTOOLONG -15 /* Buffer too long */
-#define BCME_BUSY -16 /* Busy */
-#define BCME_NOTASSOCIATED -17 /* Not Associated */
-#define BCME_BADSSIDLEN -18 /* Bad SSID len */
-#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
-#define BCME_BADCHAN -20 /* Bad Channel */
-#define BCME_BADADDR -21 /* Bad Address */
-#define BCME_NORESOURCE -22 /* Not Enough Resources */
-#define BCME_UNSUPPORTED -23 /* Unsupported */
-#define BCME_BADLEN -24 /* Bad length */
-#define BCME_NOTREADY -25 /* Not Ready */
-#define BCME_EPERM -26 /* Not Permitted */
-#define BCME_NOMEM -27 /* No Memory */
-#define BCME_ASSOCIATED -28 /* Associated */
-#define BCME_RANGE -29 /* Not In Range */
-#define BCME_NOTFOUND -30 /* Not Found */
-#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
-#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
-#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
-#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
-#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
-#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
-#define BCME_LAST BCME_DONGLE_DOWN
-
-/* These are collection of BCME Error strings */
-#define BCMERRSTRINGTABLE { \
- "OK", \
- "Undefined error", \
- "Bad Argument", \
- "Bad Option", \
- "Not up", \
- "Not down", \
- "Not AP", \
- "Not STA", \
- "Bad Key Index", \
- "Radio Off", \
- "Not band locked", \
- "No clock", \
- "Bad Rate valueset", \
- "Bad Band", \
- "Buffer too short", \
- "Buffer too long", \
- "Busy", \
- "Not Associated", \
- "Bad SSID len", \
- "Out of Range Channel", \
- "Bad Channel", \
- "Bad Address", \
- "Not Enough Resources", \
- "Unsupported", \
- "Bad length", \
- "Not Ready", \
- "Not Permitted", \
- "No Memory", \
- "Associated", \
- "Not In Range", \
- "Not Found", \
- "WME Not Enabled", \
- "TSPEC Not Found", \
- "ACM Not Supported", \
- "Not WME Association", \
- "SDIO Bus Error", \
- "Dongle Not Accessible" \
-}
-
-#ifndef ABS
-#define ABS(a) (((a) < 0)?-(a):(a))
-#endif /* ABS */
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b))?(a):(b))
-#endif /* MIN */
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b))?(a):(b))
-#endif /* MAX */
-
-#define CEIL(x, y) (((x) + ((y)-1)) / (y))
-#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
-#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0)
-#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
-#define VALID_MASK(mask) !((mask) & ((mask) + 1))
-#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
-#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
-
-/* bit map related macros */
-#ifndef setbit
-#ifndef NBBY /* the BSD family defines NBBY */
-#define NBBY 8 /* 8 bits per byte */
-#endif /* #ifndef NBBY */
-#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
-#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
-#define isset(a, i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
-#define isclr(a, i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
-#endif /* setbit */
-
-#define NBITS(type) (sizeof(type) * 8)
-#define NBITVAL(nbits) (1 << (nbits))
-#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
-#define NBITMASK(nbits) MAXBITVAL(nbits)
-#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
-
-/* basic mux operation - can be optimized on several architectures */
-#define MUX(pred, true, false) ((pred) ? (true) : (false))
-
-/* modulo inc/dec - assumes x E [0, bound - 1] */
-#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
-#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
-
-/* modulo inc/dec, bound = 2^k */
-#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
-#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
-
-/* modulo add/sub - assumes x, y E [0, bound - 1] */
-#define MODADD(x, y, bound) \
- MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
-#define MODSUB(x, y, bound) \
- MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
-
-/* module add/sub, bound = 2^k */
-#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
-#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
-
-/* crc defines */
-#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
-#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
-#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
-#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
-#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
-#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
-
-/* bcm_format_flags() bit description structure */
-typedef struct bcm_bit_desc {
- uint32 bit;
- char* name;
-} bcm_bit_desc_t;
-
-/* tag_ID/length/value_buffer tuple */
-typedef struct bcm_tlv {
- uint8 id;
- uint8 len;
- uint8 data[1];
-} bcm_tlv_t;
-
-/* Check that bcm_tlv_t fits into the given buflen */
-#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
-
-/* buffer length for ethernet address from bcm_ether_ntoa() */
-#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
-
-/* unaligned load and store macros */
-#ifdef IL_BIGENDIAN
-static INLINE uint32
-load32_ua(uint8 *a)
-{
- return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]);
-}
-
-static INLINE void
-store32_ua(uint8 *a, uint32 v)
-{
- a[0] = (v >> 24) & 0xff;
- a[1] = (v >> 16) & 0xff;
- a[2] = (v >> 8) & 0xff;
- a[3] = v & 0xff;
-}
-
-static INLINE uint16
-load16_ua(uint8 *a)
-{
- return ((a[0] << 8) | a[1]);
-}
-
-static INLINE void
-store16_ua(uint8 *a, uint16 v)
-{
- a[0] = (v >> 8) & 0xff;
- a[1] = v & 0xff;
-}
-
-#else
-
-static INLINE uint32
-load32_ua(uint8 *a)
-{
- return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
-}
-
-static INLINE void
-store32_ua(uint8 *a, uint32 v)
-{
- a[3] = (v >> 24) & 0xff;
- a[2] = (v >> 16) & 0xff;
- a[1] = (v >> 8) & 0xff;
- a[0] = v & 0xff;
-}
-
-static INLINE uint16
-load16_ua(uint8 *a)
-{
- return ((a[1] << 8) | a[0]);
-}
-
-static INLINE void
-store16_ua(uint8 *a, uint16 v)
-{
- a[1] = (v >> 8) & 0xff;
- a[0] = v & 0xff;
-}
-
-#endif /* IL_BIGENDIAN */
-
-/* externs */
-/* crc */
-extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
-extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc);
-extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc);
-/* format/print */
-extern void printfbig(char *buf);
-
-/* IE parsing */
-extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
-extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
-extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
-
-/* bcmerror */
-extern const char *bcmerrorstr(int bcmerror);
-
-/* multi-bool data type: set of bools, mbool is true if any is set */
-typedef uint32 mbool;
-#define mboolset(mb, bit) (mb |= bit) /* set one bool */
-#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */
-#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */
-#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
-
-/* power conversion */
-extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
-extern uint8 bcm_mw_to_qdbm(uint16 mw);
-
-/* generic datastruct to help dump routines */
-struct fielddesc {
- char *nameandfmt;
- uint32 offset;
- uint32 len;
-};
-
-/* Buffer structure for collecting string-formatted data
-* using bcm_bprintf() API.
-* Use bcm_binit() to initialize before use
-*/
-struct bcmstrbuf
-{
- char *buf; /* pointer to current position in origbuf */
- uint size; /* current (residual) size in bytes */
- char *origbuf; /* unmodified pointer to orignal buffer */
- uint origsize; /* unmodified orignal buffer size in bytes */
-};
-
-extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
-extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
-
-typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset);
-extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str,
- char *buf, uint32 bufsize);
-
-extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
-extern uint bcm_bitcount(uint8 *bitmap, uint bytelength);
-
-#endif /* _bcmutils_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndchipc.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndchipc.h
new file mode 100644
index 0000000000..44423aafdf
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndchipc.h
@@ -0,0 +1,31 @@
+/*
+ * HND SiliconBackplane chipcommon support.
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _hndchipc_h_
+#define _hndchipc_h_
+
+typedef void (*sb_serial_init_fn)(void *regs, uint irq, uint baud_base, uint reg_shift);
+
+extern void sb_serial_init(sb_t *sbh, sb_serial_init_fn add);
+
+extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap);
+extern void sb_jtagm_disable(osl_t *osh, void *h);
+extern uint32 jtag_rwreg(osl_t *osh, void *h, uint32 ir, uint32 dr);
+
+typedef void (*cc_isr_fn)(void* cbdata, uint32 ccintst);
+
+extern bool sb_cc_register_isr(sb_t *sbh, cc_isr_fn isr, uint32 ccintmask, void *cbdata);
+extern void sb_cc_isr(sb_t *sbh, chipcregs_t *regs);
+
+#endif /* _hndchipc_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndcpu.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndcpu.h
index b9844b02e8..78afb5256c 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndcpu.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndcpu.h
@@ -1,7 +1,7 @@
/*
* HND SiliconBackplane MIPS/ARM cores software interface.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: hndcpu.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _hndcpu_h_
@@ -17,12 +17,14 @@
#if defined(mips)
#include <hndmips.h>
-#elif defined(__ARM_ARCH_4T__)
+#elif defined(__arm__) || defined(__thumb__) || defined(__thumb2__)
#include <hndarm.h>
#endif
extern uint sb_irq(sb_t *sbh);
extern uint32 sb_cpu_clock(sb_t *sbh);
-extern void sb_cpu_wait(void);
+extern void hnd_cpu_wait(sb_t *sbh);
+extern void hnd_cpu_jumpto(void *addr);
+extern void hnd_cpu_reset(sb_t *sbh);
#endif /* _hndcpu_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndmips.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndmips.h
index cd771cac3f..95dc68c633 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndmips.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndmips.h
@@ -1,7 +1,7 @@
/*
* HND SiliconBackplane MIPS core software interface.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: hndmips.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _hndmips_h_
@@ -22,6 +22,7 @@ extern uint32 sb_memc_get_ncdl(sb_t *sbh);
#if defined(BCMPERFSTATS)
/* enable counting - exclusive version. Only one set of counters allowed at a time */
+extern void hndmips_perf_cyclecount_enable(void);
extern void hndmips_perf_instrcount_enable(void);
extern void hndmips_perf_icachecount_enable(void);
extern void hndmips_perf_dcachecount_enable(void);
@@ -40,6 +41,6 @@ extern void hndmips_perf_icache_miss_enable(void);
extern uint32 hndmips_perf_read_instrcount(void);
extern uint32 hndmips_perf_read_cache_miss(void);
extern uint32 hndmips_perf_read_cache_hit(void);
-#endif /* defined(BCMINTERNAL) || defined (BCMPERFSTATS) */
+#endif
#endif /* _hndmips_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpci.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpci.h
index 6ae0efff48..d190ea99cd 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpci.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpci.h
@@ -1,8 +1,8 @@
/*
* HND SiliconBackplane PCI core software interface.
*
- * $Id: hndpci.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
- * Copyright 2006, Broadcom Corporation
+ * $Id$
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -25,6 +25,9 @@ extern int extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint of
extern void sbpci_ban(uint16 core);
extern int sbpci_init(sb_t *sbh);
extern int sbpci_init_pci(sb_t *sbh);
-extern void sbpci_check(sb_t *sbh);
+extern void sbpci_init_cores(sb_t *sbh);
+extern void sbpci_arb_park(sb_t *sbh, uint parkid);
+
+#define PCI_PARK_NVRAM 0xff
#endif /* _hndpci_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpmu.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpmu.h
new file mode 100644
index 0000000000..1bd68728ca
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/hndpmu.h
@@ -0,0 +1,37 @@
+/*
+ * HND SiliconBackplane PMU support.
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _hndpmu_h_
+#define _hndpmu_h_
+
+#define SET_LDO_VOLTAGE_LDO1 1
+#define SET_LDO_VOLTAGE_LDO2 2
+#define SET_LDO_VOLTAGE_LDO3 3
+#define SET_LDO_VOLTAGE_PAREF 4
+
+extern void sb_pmu_init(sb_t *sbh, osl_t *osh);
+extern void sb_pmu_pll_init(sb_t *sbh, osl_t *osh, uint32 xtalfreq);
+extern void sb_pmu_res_init(sb_t *sbh, osl_t *osh);
+extern uint32 sb_pmu_force_ilp(sb_t *sbh, osl_t *osh, bool force);
+extern uint32 sb_pmu_cpu_clock(sb_t *sbh, osl_t *osh);
+extern uint32 sb_pmu_alp_clock(sb_t *sbh, osl_t *osh);
+
+extern void sb_pmu_set_switcher_voltage(sb_t *sbh, osl_t *osh, uint8 bb_voltage, uint8 rf_voltage);
+extern void sb_pmu_set_ldo_voltage(sb_t *sbh, osl_t *osh, uint8 ldo, uint8 voltage);
+extern void sb_pmu_paref_ldo_enable(sb_t *sbh, osl_t *osh, bool enable);
+extern uint16 sb_pmu_fast_pwrup_delay(sb_t *sbh, osl_t *osh);
+extern void sb_pmu_otp_power(sb_t *sbh, osl_t *osh, bool on);
+extern void sb_pmu_rcal(sb_t *sbh, osl_t *osh);
+
+#endif /* _hndpmu_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linux_gpio.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linux_gpio.h
new file mode 100644
index 0000000000..f74e92c64f
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linux_gpio.h
@@ -0,0 +1,33 @@
+/*
+ * Linux Broadcom BCM47xx GPIO char driver
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef _linux_gpio_h_
+#define _linux_gpio_h_
+
+struct gpio_ioctl {
+ uint32 mask;
+ uint32 val;
+};
+
+#define GPIO_IOC_MAGIC 'G'
+
+/* reserve/release a gpio to the caller */
+#define GPIO_IOC_RESERVE _IOWR(GPIO_IOC_MAGIC, 1, struct gpio_ioctl)
+#define GPIO_IOC_RELEASE _IOWR(GPIO_IOC_MAGIC, 2, struct gpio_ioctl)
+/* ioctls to read/write the gpio registers */
+#define GPIO_IOC_OUT _IOWR(GPIO_IOC_MAGIC, 3, struct gpio_ioctl)
+#define GPIO_IOC_IN _IOWR(GPIO_IOC_MAGIC, 4, struct gpio_ioctl)
+#define GPIO_IOC_OUTEN _IOWR(GPIO_IOC_MAGIC, 5, struct gpio_ioctl)
+
+#endif /* _linux_gpio_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linuxver.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linuxver.h
index c6a12ae921..e1dac33c5d 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linuxver.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/linuxver.h
@@ -2,7 +2,7 @@
* Linux-specific abstractions to gain some independence from linux kernel versions.
* Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -10,14 +10,19 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: linuxver.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _linuxver_h_
#define _linuxver_h_
-#include <linux/config.h>
#include <linux/version.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+#include <linux/config.h>
+#else
+#include <linux/autoconf.h>
+#endif
+#include <linux/module.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0))
/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */
@@ -28,15 +33,6 @@
#endif
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */
-#if defined(MODULE) && defined(MODVERSIONS)
-#include <linux/modversions.h>
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
-#include <linux/moduleparam.h>
-#endif
-
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i")
#define module_param_string(_name_, _string_, _size_, _perm_) \
@@ -77,6 +73,13 @@
#endif
#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
+#define MY_INIT_WORK(_work, _func, _data) INIT_WORK(_work, _func)
+#else
+#define MY_INIT_WORK(_work, _func, _data) INIT_WORK(_work, _func, _data)
+typedef void (*work_func_t)(void *work);
+#endif /* < 2.6.20 */
+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
/* Some distributions have their own 2.6.x compatibility layers */
#ifndef IRQ_NONE
@@ -110,6 +113,12 @@ cs_error(client_handle_t handle, int func, int ret)
}
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15))
+
+typedef struct pcmcia_device dev_link_t;
+
+#endif
+
#endif /* CONFIG_PCMCIA */
#ifndef __exit
@@ -414,4 +423,11 @@ pci_restore_state(struct pci_dev *dev, u32 *buffer)
#define af_packet_priv data
#endif
+/* suspend args */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+#define DRV_SUSPEND_STATE_TYPE pm_message_t
+#else
+#define DRV_SUSPEND_STATE_TYPE uint32
+#endif
+
#endif /* _linuxver_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/mipsinc.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/mipsinc.h
index 2c87031fea..b291ea30b5 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/mipsinc.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/mipsinc.h
@@ -1,7 +1,7 @@
/*
* HND Run Time Environment for standalone MIPS programs.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: mipsinc.h,v 1.1.1.5 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _MISPINC_H
@@ -69,6 +69,7 @@
#define C0_CTEXT $4
#define C0_PGMASK $5
#define C0_WIRED $6
+#define C0_INFO $7
#define C0_BADVADDR $8
#define C0_COUNT $9
#define C0_TLBHI $10
@@ -145,6 +146,7 @@ symbol: .frame sp, 0, ra
#define C0_CTEXT 4 /* CP0: Context */
#define C0_PGMASK 5 /* CP0: TLB PageMask */
#define C0_WIRED 6 /* CP0: TLB Wired */
+#define C0_INFO 7 /* CP0: Info */
#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
#define C0_COUNT 9 /* CP0: Count */
#define C0_TLBHI 10 /* CP0: TLB EntryHi */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/osl.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/osl.h
index 9be443215c..fddd1983e8 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/osl.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/osl.h
@@ -4,26 +4,66 @@
#include <linux/delay.h>
#include <typedefs.h>
#include <linuxver.h>
-#include <bcmutils.h>
#include <pcicfg.h>
#define ASSERT(n)
+#ifndef ABS
+#define ABS(a) (((a) < 0)?-(a):(a))
+#endif /* ABS */
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b))?(a):(b))
+#endif /* MIN */
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b))?(a):(b))
+#endif /* MAX */
+
+#define CEIL(x, y) (((x) + ((y)-1)) / (y))
+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
+#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0)
+#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
+#define VALID_MASK(mask) !((mask) & ((mask) + 1))
+#ifndef OFFSETOF
+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
+#endif /* OFFSETOF */
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+/*
+ * Spin at most 'us' microseconds while 'exp' is true.
+ * Caller should explicitly test 'exp' when this completes
+ * and take appropriate error action if 'exp' is still true.
+ */
+#define SPINWAIT(exp, us) { \
+ uint countdown = (us) + 9; \
+ while ((exp) && (countdown >= 10)) {\
+ OSL_DELAY(10); \
+ countdown -= 10; \
+ } \
+}
+
+
+typedef void (*pktfree_cb_fn_t)(void *ctx, void *pkt, unsigned int status);
/* Pkttag flag should be part of public information */
typedef struct {
bool pkttag;
- uint pktalloced; /* Number of allocated packet buffers */
- void *tx_fn;
- void *tx_ctx;
+ uint pktalloced; /* Number of allocated packet buffers */
+ bool mmbus; /* Bus supports memory-mapped register accesses */
+ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */
+ void *tx_ctx; /* Context to the callback function */
} osl_pubinfo_t;
struct osl_info {
- osl_pubinfo_t pub;
- uint magic;
- void *pdev;
- uint malloced;
- uint failed;
- void *dbgmem_list;
+ osl_pubinfo_t pub;
+ uint magic;
+ void *pdev;
+ uint malloced;
+ uint failed;
+ uint bustype;
+ void *dbgmem_list;
};
typedef struct osl_info osl_t;
@@ -101,8 +141,8 @@ typedef struct osl_info osl_t;
#define MFREE(osh, addr, size) kfree((addr))
#define MALLOCED(osh) (0)
-#define osl_delay OSL_DELAY
-static inline void OSL_DELAY(uint usec)
+#define OSL_DELAY _osl_delay
+static inline void _osl_delay(uint usec)
{
uint d;
@@ -128,10 +168,10 @@ bcm_mdelay(uint ms)
#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size)
#define OSL_PCI_READ_CONFIG(osh, offset, size) \
- osl_pci_read_config((osh), (offset), (size))
+ _osl_pci_read_config((osh), (offset), (size))
static inline uint32
-osl_pci_read_config(osl_t *osh, uint offset, uint size)
+_osl_pci_read_config(osl_t *osh, uint offset, uint size)
{
uint val;
uint retry = PCI_CFG_RETRY;
@@ -146,9 +186,9 @@ osl_pci_read_config(osl_t *osh, uint offset, uint size)
}
#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
- osl_pci_write_config((osh), (offset), (size), (val))
+ _osl_pci_write_config((osh), (offset), (size), (val))
static inline void
-osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
+_osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
{
uint retry = PCI_CFG_RETRY;
@@ -156,24 +196,24 @@ osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
pci_write_config_dword(osh->pdev, offset, val);
if (offset != PCI_BAR0_WIN)
break;
- if (osl_pci_read_config(osh, offset, size) == val)
+ if (_osl_pci_read_config(osh, offset, size) == val)
break;
} while (retry--);
}
/* return bus # for the pci device pointed by osh->pdev */
-#define OSL_PCI_BUS(osh) osl_pci_bus(osh)
+#define OSL_PCI_BUS(osh) _osl_pci_bus(osh)
static inline uint
-osl_pci_bus(osl_t *osh)
+_osl_pci_bus(osl_t *osh)
{
return ((struct pci_dev *)osh->pdev)->bus->number;
}
/* return slot # for the pci device pointed by osh->pdev */
-#define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
+#define OSL_PCI_SLOT(osh) _osl_pci_slot(osh)
static inline uint
-osl_pci_slot(osl_t *osh)
+_osl_pci_slot(osl_t *osh)
{
return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
}
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/pcicfg.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/pcicfg.h
index 8bb45957a7..dd468db76c 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/pcicfg.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/pcicfg.h
@@ -1,7 +1,7 @@
/*
* pcicfg.h: PCI configuration constants and structures.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: pcicfg.h,v 1.1.1.11 2006/04/08 06:13:40 honor Exp $
+ * $Id$
*/
#ifndef _h_pcicfg_
@@ -170,6 +170,14 @@ typedef struct _pci_config_regs {
#undef PCI_CLASS_DOCK
#endif /* __NetBSD__ */
+#ifdef EFI
+#undef PCI_CLASS_BRIDGE
+#undef PCI_CLASS_OLD
+#undef PCI_CLASS_DISPLAY
+#undef PCI_CLASS_SERIAL
+#undef PCI_CLASS_SATELLITE
+#endif /* EFI */
+
/* Classes and subclasses */
typedef enum {
@@ -406,6 +414,11 @@ typedef struct _pciconfig_cap_pwrmgmt {
unsigned char data;
} pciconfig_cap_pwrmgmt;
+#define PME_CAP_PM_STATES (0x1f << 27) /* Bits 31:27 states that can generate PME */
+#define PME_CSR_OFFSET 0x4 /* 4-bytes offset */
+#define PME_CSR_PME_EN (1 << 8) /* Bit 8 Enable generating of PME */
+#define PME_CSR_PME_STAT (1 << 15) /* Bit 15 PME got asserted */
+
/* Data structure to define the PCIE capability */
typedef struct _pciconfig_cap_pcie {
unsigned char capID;
@@ -463,7 +476,7 @@ typedef struct _pcie_enhanced_caphdr {
* 8KB window, so their address is the "regular"
* address plus 4K
*/
-#define PCI_BAR0_WINSZ 8192 /* bar0 window size */
+#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */
/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbchipc.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbchipc.h
index 03c5cf19a0..c3d4c6110e 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbchipc.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbchipc.h
@@ -5,8 +5,8 @@
* jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
* gpio interface, extbus, and support for serial and parallel flashes.
*
- * $Id: sbchipc.h,v 1.1.1.14 2006/04/15 01:29:08 michael Exp $
- * Copyright 2006, Broadcom Corporation
+ * $Id$
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -19,7 +19,6 @@
#ifndef _SBCHIPC_H
#define _SBCHIPC_H
-
#ifndef _LANGUAGE_ASSEMBLY
/* cpp contortions to concatenate w/arg prescan */
@@ -29,6 +28,7 @@
#define PAD _XSTR(__LINE__)
#endif /* PAD */
+
typedef volatile struct {
uint32 chipid; /* 0x0 */
uint32 capabilities;
@@ -62,20 +62,26 @@ typedef volatile struct {
/* Silicon backplane configuration broadcast control */
uint32 broadcastaddress; /* 0x50 */
uint32 broadcastdata;
- uint32 PAD[2];
/* gpio - cleared only by power-on-reset */
+ uint32 gpiopullup; /* 0x58, corerev >= 20 */
+ uint32 gpiopulldown; /* 0x5c, corerev >= 20 */
uint32 gpioin; /* 0x60 */
uint32 gpioout;
uint32 gpioouten;
uint32 gpiocontrol;
uint32 gpiointpolarity;
uint32 gpiointmask;
- uint32 PAD[2];
+
+ /* GPIO events corerev >= 11 */
+ uint32 gpioevent;
+ uint32 gpioeventintmask;
/* Watchdog timer */
uint32 watchdog; /* 0x80 */
- uint32 PAD[1];
+
+ /* GPIO events corerev >= 11 */
+ uint32 gpioeventintpolarity;
/* GPIO based LED powersave registers corerev >= 16 */
uint32 gpiotimerval; /* 0x88 */
@@ -114,10 +120,31 @@ typedef volatile struct {
uint32 prog_waitcount;
uint32 flash_config;
uint32 flash_waitcount;
- uint32 PAD[44];
-
- /* Clock control and hardware workarounds */
- uint32 clk_ctl_st;
+ uint32 PAD[4];
+
+ /* Enhanced Coexistance Interface (ECI) registers (corerev >= 21) */
+ uint32 eci_output; /* 0x140 */
+ uint32 eci_control;
+ uint32 eci_inputlo;
+ uint32 eci_inputmi;
+ uint32 eci_inputhi;
+ uint32 eci_inputintpolaritylo;
+ uint32 eci_inputintpolaritymi;
+ uint32 eci_inputintpolarityhi;
+ uint32 eci_intmasklo;
+ uint32 eci_intmaskmi;
+ uint32 eci_intmaskhi;
+ uint32 eci_eventlo;
+ uint32 eci_eventmi;
+ uint32 eci_eventhi;
+ uint32 eci_eventmasklo;
+ uint32 eci_eventmaskmi;
+ uint32 eci_eventmaskhi;
+ uint32 PAD[23];
+
+
+ /* Clock control and hardware workarounds (corerev >= 20) */
+ uint32 clk_ctl_st; /* 0x1e0 */
uint32 hw_war;
uint32 PAD[70];
@@ -140,12 +167,47 @@ typedef volatile struct {
uint8 uart1lsr;
uint8 uart1msr;
uint8 uart1scratch;
+ uint32 PAD[126];
+
+ /* PMU registers (corerev >= 20) */
+ uint32 pmucontrol; /* 0x600 */
+ uint32 pmucapabilities;
+ uint32 pmustatus;
+ uint32 res_state;
+ uint32 res_pending;
+ uint32 pmutimer;
+ uint32 min_res_mask;
+ uint32 max_res_mask;
+ uint32 res_table_sel;
+ uint32 res_dep_mask;
+ uint32 res_updn_timer;
+ uint32 res_timer;
+ uint32 clkstretch;
+ uint32 pmuwatchdog;
+ uint32 PAD[2];
+ uint32 res_req_timer_sel;
+ uint32 res_req_timer;
+ uint32 res_req_mask;
+ uint32 PAD;
+ uint32 chipcontrol_addr;
+ uint32 chipcontrol_data;
+ uint32 regcontrol_addr;
+ uint32 regcontrol_data;
+ uint32 pllcontrol_addr;
+ uint32 pllcontrol_data;
+ uint32 PAD[102];
+ uint16 otp[512];
} chipcregs_t;
#endif /* _LANGUAGE_ASSEMBLY */
+/* corecontrol */
+#define CC_UE (1 << 0) /* uart enable */
+
#define CC_CHIPID 0
#define CC_CAPABILITIES 4
+#define CC_OTPST 0x10
+#define CC_CHIPST 0x2c
#define CC_JTAGCMD 0x30
#define CC_JTAGIR 0x34
#define CC_JTAGDR 0x38
@@ -158,7 +220,18 @@ typedef volatile struct {
#define CC_CLKC_M3 0xa0
#define CC_CLKDIV 0xa4
#define CC_SYS_CLK_CTL 0xc0
-#define CC_OTP 0x800
+#define CC_CLK_CTL_ST SB_CLK_CTL_ST
+#define PMU_CTL 0x600
+#define PMU_CAP 0x604
+#define PMU_ST 0x608
+#define PMU_TIMER 0x614
+#define PMU_MIN_RES_MASK 0x618
+#define PMU_MAX_RES_MASK 0x61c
+#define PMU_REG_CONTROL_ADDR 0x658
+#define PMU_REG_CONTROL_DATA 0x65C
+#define PMU_PLL_CONTROL_ADDR 0x660
+#define PMU_PLL_CONTROL_DATA 0x664
+#define CC_OTP 0x800 /* OTP address space */
/* chipid */
#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
@@ -170,24 +243,26 @@ typedef volatile struct {
#define CID_CC_SHIFT 24
/* capabilities */
-#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */
-#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
-#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */
-#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
-#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */
-#define CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
-#define CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
-#define CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
-#define CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
-#define CAP_FLASH_MASK 0x00000700 /* Type of flash */
-#define CAP_PLL_MASK 0x00038000 /* Type of PLL */
-#define CAP_PWR_CTL 0x00040000 /* Power control */
-#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
-#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
-#define CAP_OTPSIZE_BASE 5 /* OTP Size base */
-#define CAP_JTAGP 0x00400000 /* JTAG Master Present */
-#define CAP_ROM 0x00800000 /* Internal boot rom active */
-#define CAP_BKPLN64 0x08000000 /* 64-bit backplane */
+#define CC_CAP_UARTS_MASK 0x00000003 /* Number of uarts */
+#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
+#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */
+#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
+#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */
+#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
+#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
+#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
+#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
+#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */
+#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */
+#define CC_CAP_PWR_CTL 0x00040000 /* Power control */
+#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
+#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
+#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */
+#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */
+#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */
+#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */
+#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */
+#define CC_CAP_ECI 0x20000000 /* ECI Present, rev >= 21 */
/* PLL type */
#define PLL_NONE 0x00000000
@@ -199,39 +274,72 @@ typedef volatile struct {
#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */
#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */
+/* ALP clock on pre-PMU chips */
+#define ALP_CLOCK 20000000
+
+/* HT clock */
+#define HT_CLOCK 80000000
+
+/* watchdog clock */
+#define WATCHDOG_CLOCK_5354 32000 /* Hz */
+
/* corecontrol */
#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */
#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
+#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */
/* chipcontrol */
#define CHIPCTRL_4321A0_DEFAULT 0x3a4
#define CHIPCTRL_4321A1_DEFAULT 0x0a4
-/* Fields in the otpstatus register */
-#define OTPS_PROGFAIL 0x80000000
-#define OTPS_PROTECT 0x00000007
-#define OTPS_HW_PROTECT 0x00000001
-#define OTPS_SW_PROTECT 0x00000002
-#define OTPS_CID_PROTECT 0x00000004
-
-/* Fields in the otpcontrol register */
-#define OTPC_RECWAIT 0xff000000
-#define OTPC_PROGWAIT 0x00ffff00
-#define OTPC_PRW_SHIFT 8
-#define OTPC_MAXFAIL 0x00000038
-#define OTPC_VSEL 0x00000006
-#define OTPC_SELVL 0x00000001
-
-/* Fields in otpprog */
-#define OTPP_COL_MASK 0x000000ff
-#define OTPP_ROW_MASK 0x0000ff00
-#define OTPP_ROW_SHIFT 8
-#define OTPP_READERR 0x10000000
-#define OTPP_VALUE 0x20000000
-#define OTPP_VALUE_SHIFT 29
-#define OTPP_READ 0x40000000
-#define OTPP_START 0x80000000
-#define OTPP_BUSY 0x80000000
+/* Fields in the otpstatus register in rev >= 21 */
+#define OTPS_OL_MASK 0x000000ff
+#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */
+#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */
+#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */
+#define OTPS_OL_GU 0x00000008 /* general use region is locked */
+#define OTPS_GUP_MASK 0x00000f00
+#define OTPS_GUP_SHIFT 8
+#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */
+#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */
+#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */
+#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */
+#define OTPS_READY 0x00001000
+#define OTPS_RV(x) (1 << (16 + (x)))
+
+/* Fields in the otpcontrol register in rev >= 21 */
+#define OTPC_PROGSEL 0x00000001
+#define OTPC_PCOUNT_MASK 0x0000000e
+#define OTPC_PCOUNT_SHIFT 1
+#define OTPC_VSEL_MASK 0x000000f0
+#define OTPC_VSEL_SHIFT 4
+#define OTPC_TMM_MASK 0x00000700
+#define OTPC_TMM_SHIFT 8
+#define OTPC_ODM 0x00000800
+#define OTPC_PROGEN 0x80000000
+
+/* Fields in otpprog in rev >= 21 */
+#define OTPP_COL_MASK 0x000000ff
+#define OTPP_COL_SHIFT 0
+#define OTPP_ROW_MASK 0x0000ff00
+#define OTPP_ROW_SHIFT 8
+#define OTPP_OC_MASK 0x0f000000
+#define OTPP_OC_SHIFT 24
+#define OTPP_READERR 0x10000000
+#define OTPP_VALUE_MASK 0x20000000
+#define OTPP_VALUE_SHIFT 29
+#define OTPP_START_BUSY 0x80000000
+
+/* Opcodes for OTPP_OC field */
+#define OTPPOC_READ 0
+#define OTPPOC_BIT_PROG 1
+#define OTPPOC_VERIFY 3
+#define OTPPOC_INIT 4
+#define OTPPOC_SET 5
+#define OTPPOC_RESET 6
+#define OTPPOC_OCST 7
+#define OTPPOC_ROW_LOCK 8
+#define OTPPOC_PRESCN_TEST 9
/* jtagcmd */
#define JCMD_START 0x80000000
@@ -272,7 +380,12 @@ typedef volatile struct {
/* intstatus/intmask */
#define CI_GPIO 0x00000001 /* gpio intr */
-#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */
+#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */
+#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */
+#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */
+#define CI_ECI 0x00000010 /* eci intr (corerev >= 21) */
+#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */
+#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */
#define CI_WDRESET 0x80000000 /* watchdog reset occurred */
/* slow_clk_ctl */
@@ -306,6 +419,43 @@ typedef volatile struct {
#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
#define SYCC_CD_SHIFT 16
+/* pcmcia_iowait */
+#define PI_W0_MASK 0x0000003f /* waitcount0 */
+#define PI_W1_MASK 0x00001f00 /* waitcount1 */
+#define PI_W1_SHIFT 8
+#define PI_W2_MASK 0x001f0000 /* waitcount2 */
+#define PI_W2_SHIFT 16
+#define PI_W3_MASK 0x1f000000 /* waitcount3 */
+#define PI_W3_SHIFT 24
+
+/* prog_waitcount */
+#define PW_W0_MASK 0x0000001f /* waitcount0 */
+#define PW_W1_MASK 0x00001f00 /* waitcount1 */
+#define PW_W1_SHIFT 8
+#define PW_W2_MASK 0x001f0000 /* waitcount2 */
+#define PW_W2_SHIFT 16
+#define PW_W3_MASK 0x1f000000 /* waitcount3 */
+#define PW_W3_SHIFT 24
+
+#define PW_W0 0x0000000c
+#define PW_W1 0x00000a00
+#define PW_W2 0x00020000
+#define PW_W3 0x01000000
+
+/* watchdog */
+#define WATCHDOG_CLOCK 48000000 /* Hz */
+
+/* Fields in pmucontrol */
+#define PCTL_ILP_DIV_MASK 0xffff0000
+#define PCTL_ILP_DIV_SHIFT 16
+#define PCTL_NOILP_ON_WAIT 0x00000200
+#define PCTL_HT_REQ_EN 0x00000100
+#define PCTL_ALP_REQ_EN 0x00000080
+#define PCTL_XTALFREQ_MASK 0x0000007c
+#define PCTL_XTALFREQ_SHIFT 2
+#define PCTL_ILP_DIV_EN 0x00000002
+#define PCTL_LPO_SEL 0x00000001
+
/* gpiotimerval */
#define GPIO_ONTIME_SHIFT 16
@@ -377,9 +527,10 @@ typedef volatile struct {
#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */
#define CC_CFG_EM_IDE 0x0006 /* IDE */
#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
-#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */
-#define CC_CFG_CE 0x0080 /* Sync: Clock enable */
-#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */
+#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */
+#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */
+#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */
+#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */
/* ExtBus address space */
#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */
@@ -396,6 +547,7 @@ typedef volatile struct {
/* Start/busy bit in flashcontrol */
#define SFLASH_OPCODE 0x000000ff
#define SFLASH_ACTION 0x00000700
+#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */
#define SFLASH_START 0x80000000
#define SFLASH_BUSY SFLASH_START
@@ -419,6 +571,7 @@ typedef volatile struct {
#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */
#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */
#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */
+#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */
/* Status register bits for ST flashes */
#define SFLASH_ST_WIP 0x01 /* Write In Progress */
@@ -456,31 +609,6 @@ typedef volatile struct {
#define SFLASH_AT_ID_MASK 0x38
#define SFLASH_AT_ID_SHIFT 3
-/* OTP regions */
-#define OTP_HW_REGION OTPS_HW_PROTECT
-#define OTP_SW_REGION OTPS_SW_PROTECT
-#define OTP_CID_REGION OTPS_CID_PROTECT
-
-/* OTP regions (Byte offsets from otp size) */
-#define OTP_SWLIM_OFF (-8)
-#define OTP_CIDBASE_OFF 0
-#define OTP_CIDLIM_OFF 8
-
-/* Predefined OTP words (Word offset from otp size) */
-#define OTP_BOUNDARY_OFF (-4)
-#define OTP_HWSIGN_OFF (-3)
-#define OTP_SWSIGN_OFF (-2)
-#define OTP_CIDSIGN_OFF (-1)
-
-#define OTP_CID_OFF 0
-#define OTP_PKG_OFF 1
-#define OTP_FID_OFF 2
-#define OTP_RSV_OFF 3
-#define OTP_LIM_OFF 4
-
-#define OTP_SIGNATURE 0x578a
-#define OTP_MAGIC 0x4e56
-
/*
* These are the UART port assignments, expressed as offsets from the base
* register. These assignments should hold for any serial port based on
@@ -507,10 +635,223 @@ typedef volatile struct {
#define UART_LSR_RXRDY 0x01 /* Receiver ready */
#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */
+/* Interrupt Identity Register (IIR) bits */
+#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */
+#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */
+#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */
+#define UART_IIR_NOINT 0x1 /* No interrupt pending */
+#define UART_IIR_THRE 0x2 /* THR empty */
+#define UART_IIR_RCVD_DATA 0x4 /* Received data available */
+#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */
+#define UART_IIR_CHAR_TIME 0xc /* Character time */
+
/* Interrupt Enable Register (IER) bits */
#define UART_IER_EDSSI 8 /* enable modem status interrupt */
#define UART_IER_ELSI 4 /* enable receiver line status interrupt */
#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */
#define UART_IER_ERBFI 1 /* enable data available interrupt */
+/* pmustatus */
+#define PST_INTPEND 0x0040
+#define PST_SBCLKST 0x0030
+#define PST_ALPAVAIL 0x0008
+#define PST_HTAVAIL 0x0004
+#define PST_RESINIT 0x0003
+
+/* pmucapabilities */
+#define PCAP_REV_MASK 0x000000ff
+
+/* PMU Resource Request Timer registers */
+/* This is based on PmuRev0 */
+#define PRRT_TIME_MASK 0x03ff
+#define PRRT_INTEN 0x0400
+#define PRRT_REQ_ACTIVE 0x0800
+#define PRRT_ALP_REQ 0x1000
+#define PRRT_HT_REQ 0x2000
+
+/* PMU resource bit position */
+#define PMURES_BIT(bit) (1 << (bit))
+
+/* PMU corerev and chip specific PLL controls.
+ * PMU<rev>_PLL<num>_XXXX where <rev> is PMU corerev and <num> is an arbitary number
+ * to differentiate different PLLs controlled by the same PMU rev.
+ */
+/* pllcontrol registers */
+/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */
+#define PMU0_PLL0_PLLCTL0 0
+#define PMU0_PLL0_PC0_PDIV_MASK 1
+#define PMU0_PLL0_PC0_PDIV_FREQ 25000
+#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038
+#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3
+#define PMU0_PLL0_PC0_DIV_ARM_BASE 8
+
+/* PC0_DIV_ARM for PLLOUT_ARM */
+#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0
+#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1
+#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2
+#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */
+#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4
+#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5
+#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6
+#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7
+
+/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */
+#define PMU0_PLL0_PLLCTL1 1
+#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000
+#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28
+#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00
+#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8
+#define PMU0_PLL0_PC1_STOP_MOD 0x00000040
+
+/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */
+#define PMU0_PLL0_PLLCTL2 2
+#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf
+#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4
+
+/* Chip specific PMU resources. */
+#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */
+#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */
+#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */
+#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */
+#define RES4328_ILP_REQUEST 4 /* 0x00010 */
+#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */
+#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */
+#define RES4328_ROM_SWITCH 7 /* 0x00080 */
+#define RES4328_PA_REF_LDO 8 /* 0x00100 */
+#define RES4328_RADIO_LDO 9 /* 0x00200 */
+#define RES4328_AFE_LDO 10 /* 0x00400 */
+#define RES4328_PLL_LDO 11 /* 0x00800 */
+#define RES4328_BG_FILTBYP 12 /* 0x01000 */
+#define RES4328_TX_FILTBYP 13 /* 0x02000 */
+#define RES4328_RX_FILTBYP 14 /* 0x04000 */
+#define RES4328_XTAL_PU 15 /* 0x08000 */
+#define RES4328_XTAL_EN 16 /* 0x10000 */
+#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */
+#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */
+#define RES4328_BB_PLL_PU 19 /* 0x80000 */
+
+#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */
+#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */
+#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */
+#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */
+#define RES5354_ILP_REQUEST 4 /* 0x00010 */
+#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */
+#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */
+#define RES5354_ROM_SWITCH 7 /* 0x00080 */
+#define RES5354_PA_REF_LDO 8 /* 0x00100 */
+#define RES5354_RADIO_LDO 9 /* 0x00200 */
+#define RES5354_AFE_LDO 10 /* 0x00400 */
+#define RES5354_PLL_LDO 11 /* 0x00800 */
+#define RES5354_BG_FILTBYP 12 /* 0x01000 */
+#define RES5354_TX_FILTBYP 13 /* 0x02000 */
+#define RES5354_RX_FILTBYP 14 /* 0x04000 */
+#define RES5354_XTAL_PU 15 /* 0x08000 */
+#define RES5354_XTAL_EN 16 /* 0x10000 */
+#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */
+#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */
+#define RES5354_BB_PLL_PU 19 /* 0x80000 */
+
+/* pllcontrol registers */
+/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypsss_sdmod */
+#define PMU1_PLL0_PLLCTL0 0
+#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000
+#define PMU1_PLL0_PC0_P1DIV_SHIFT 20
+#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000
+#define PMU1_PLL0_PC0_P2DIV_SHIFT 24
+
+/* m<x>div */
+#define PMU1_PLL0_PLLCTL1 1
+#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff
+#define PMU1_PLL0_PC1_M1DIV_SHIFT 0
+#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00
+#define PMU1_PLL0_PC1_M2DIV_SHIFT 8
+#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000
+#define PMU1_PLL0_PC1_M3DIV_SHIFT 16
+#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000
+#define PMU1_PLL0_PC1_M4DIV_SHIFT 24
+
+/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+#define PMU1_PLL0_PLLCTL2 2
+#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff
+#define PMU1_PLL0_PC2_M5DIV_SHIFT 0
+#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00
+#define PMU1_PLL0_PC2_M6DIV_SHIFT 8
+#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000
+#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17
+#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000
+#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20
+
+/* ndiv_frac */
+#define PMU1_PLL0_PLLCTL3 3
+#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff
+#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0
+
+/* pll_ctrl */
+#define PMU1_PLL0_PLLCTL4 4
+
+/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+#define PMU1_PLL0_PLLCTL5 5
+#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00
+#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8
+
+#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */
+#define RES4325_CBUCK_BURST 1 /* 0x00000002 */
+#define RES4325_CBUCK_PWM 2 /* 0x00000004 */
+#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */
+#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */
+#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */
+#define RES4325_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4325_ABUCK_BURST 7 /* 0x00000080 */
+#define RES4325_ABUCK_PWM 8 /* 0x00000100 */
+#define RES4325_LNLDO1_PU 9 /* 0x00000200 */
+#define RES4325_LNLDO2_PU 10 /* 0x00000400 */
+#define RES4325_LNLDO3_PU 11 /* 0x00000800 */
+#define RES4325_LNLDO4_PU 12 /* 0x00001000 */
+#define RES4325_XTAL_PU 13 /* 0x00002000 */
+#define RES4325_ALP_AVAIL 14 /* 0x00004000 */
+#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */
+#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */
+#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */
+#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */
+#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */
+#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */
+#define RES4325_HT_AVAIL 21 /* 0x00200000 */
+
+/* Chip specific ChipStatus register bits */
+#define CST4325_SPROM_OTP_SEL_MASK 0x00000003
+#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
+#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
+#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */
+#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */
+#define CST4325_SDIO_USB_MODE_MASK 0x00000004
+#define CST4325_SDIO_USB_MODE_SHIFT 2
+#define CST4325_RCAL_VALID_MASK 0x00000008
+#define CST4325_RCAL_VALID_SHIFT 3
+#define CST4325_RCAL_VALUE_MASK 0x000001f0
+#define CST4325_RCAL_VALUE_SHIFT 4
+#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */
+#define CST4325_PMUTOP_2B_SHIFT 9
+
+#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */
+#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */
+#define RES4312_PA_REF_LDO 2 /* 0x00000004 */
+#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */
+#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */
+#define RES4312_RADIO_LDO 5 /* 0x00000020 */
+#define RES4312_ILP_REQUEST 6 /* 0x00000040 */
+#define RES4312_BG_FILTBYP 7 /* 0x00000080 */
+#define RES4312_TX_FILTBYP 8 /* 0x00000100 */
+#define RES4312_RX_FILTBYP 9 /* 0x00000200 */
+#define RES4312_XTAL_PU 10 /* 0x00000400 */
+#define RES4312_ALP_AVAIL 11 /* 0x00000800 */
+#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */
+#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */
+#define RES4312_HT_AVAIL 14 /* 0x00004000 */
+
+/*
+* Maximum delay for the PMU state transition.
+* This is an upper bound intended for spinwaits etc.
+*/
+#define PMU_MAX_TRANSITION_DLY 15000
+
#endif /* _SBCHIPC_H */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbconfig.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbconfig.h
index 7a44e5fbaa..f609f3c2eb 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbconfig.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbconfig.h
@@ -1,7 +1,7 @@
/*
* Broadcom SiliconBackplane hardware register definitions.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,11 +9,12 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbconfig.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _SBCONFIG_H
#define _SBCONFIG_H
+#include "linuxver.h"
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
@@ -36,13 +37,13 @@
#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */
#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */
-
#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */
+#define SB_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */
#define SB_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */
#define SB_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */
-
-#define SB_ROM 0x20000000 /* ARM ROM */
-#define SB_SRAM2 0x80000000 /* ARM SRAM Region 2 */
+#define SB_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */
+#define SB_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */
+#define SB_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */
#define SB_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */
#define SB_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */
@@ -196,7 +197,7 @@ typedef volatile struct _sbconfig {
#define SBTMH_INT 0x2 /* interrupt */
#define SBTMH_BUSY 0x4 /* busy */
#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */
-#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */
+#define SBTMH_FL_MASK 0x0fff0000 /* core-specific flags */
#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */
#define SBTMH_GCR 0x20000000 /* gated clock request */
#define SBTMH_BISTF 0x40000000 /* bist failed */
@@ -323,7 +324,6 @@ typedef volatile struct _sbconfig {
#define SB_ILINE100 0x80a /* iline100 core */
#define SB_IPSEC 0x80b /* ipsec core */
#define SB_PCMCIA 0x80d /* pcmcia core */
-#define SB_SDIOD SB_PCMCIA /* pcmcia core has sdio device */
#define SB_SOCRAM 0x80e /* internal memory core */
#define SB_MEMC 0x80f /* memc sdram core */
#define SB_EXTIF 0x811 /* external interface core */
@@ -342,11 +342,32 @@ typedef volatile struct _sbconfig {
#define SB_MIMO 0x821 /* MIMO phy core */
#define SB_SRAMC 0x822 /* SRAM controller core */
#define SB_MINIMAC 0x823 /* MINI MAC/phy core */
-#define SB_ARM11 0x824 /* ARM 1176 core */
-#define SB_ARM7 0x825 /* ARM 7tdmi core */
+#define SB_ARM7S 0x825 /* ARM7tdmi-s core */
+#define SB_SDIOD 0x829 /* SDIO device core */
+#define SB_ARMCM3 0x82a /* ARM Cortex M3 core */
+#define SB_OCP 0x830 /* OCP2OCP bridge core */
+#define SB_SC 0x831 /* shared common core */
+#define SB_AHB 0x832 /* OCP2AHB bridge core */
#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */
+/* Not an enumeration space register, but common to all cores to
+ * communicate w/PMU regarding Silicon Backplane clocking.
+ */
+#define SB_CLK_CTL_ST 0x1e0 /* clock control and status */
+
+/* clk_ctl_st register */
+#define CCS_FORCEALP 0x00000001 /* force ALP request */
+#define CCS_FORCEHT 0x00000002 /* force HT request */
+#define CCS_FORCEILP 0x00000004 /* force ILP request */
+#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
+#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
+#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
+#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
+#define CCS_HTAVAIL 0x00020000 /* HT is available */
+#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */
+#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */
+
/* Not really related to Silicon Backplane, but a couple of software
* conventions for the use the flash space:
*/
@@ -359,11 +380,11 @@ typedef volatile struct _sbconfig {
#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */
#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
#define BISZ_TXTST_IDX 1 /* 1: text start */
-#define BISZ_TXTEND_IDX 2 /* 2: text start */
-#define BISZ_DATAST_IDX 3 /* 3: text start */
-#define BISZ_DATAEND_IDX 4 /* 4: text start */
-#define BISZ_BSSST_IDX 5 /* 5: text start */
-#define BISZ_BSSEND_IDX 6 /* 6: text start */
+#define BISZ_TXTEND_IDX 2 /* 2: text end */
+#define BISZ_DATAST_IDX 3 /* 3: data start */
+#define BISZ_DATAEND_IDX 4 /* 4: data end */
+#define BISZ_BSSST_IDX 5 /* 5: bss start */
+#define BISZ_BSSEND_IDX 6 /* 6: bss end */
#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */
#endif /* _SBCONFIG_H */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbextif.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbextif.h
index 7c3f2a0d6c..078d7b2344 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbextif.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbextif.h
@@ -161,15 +161,6 @@ typedef volatile struct {
#define PA_W3_MASK 0x1f000000 /* waitcount3 */
#define PA_W3_SHIFT 24
-/* pcmcia_iowait */
-#define PI_W0_MASK 0x3f /* waitcount0 */
-#define PI_W1_MASK 0x1f00 /* waitcount1 */
-#define PI_W1_SHIFT 8
-#define PI_W2_MASK 0x1f0000 /* waitcount2 */
-#define PI_W2_SHIFT 16
-#define PI_W3_MASK 0x1f000000 /* waitcount3 */
-#define PI_W3_SHIFT 24
-
/* prog_waitcount */
#define PW_W0_MASK 0x0000001f /* waitcount0 */
#define PW_W1_MASK 0x00001f00 /* waitcount1 */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbhndmips.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbhndmips.h
index 93f5ace8b8..3fc442ee2b 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbhndmips.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbhndmips.h
@@ -7,7 +7,7 @@
* interface. The core revision is stored in the SB ID register in SB
* configuration space.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -15,7 +15,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbhndmips.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _sbhndmips_h_
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbmemc.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbmemc.h
index 74af8e1693..f20cdf77f2 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbmemc.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbmemc.h
@@ -1,7 +1,7 @@
/*
* BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbmemc.h,v 1.6 2006/03/02 12:33:44 honor Exp $
+ * $Id$
*/
#ifndef _SBMEMC_H
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpci.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpci.h
index 761e5b4513..f35ed910e3 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpci.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpci.h
@@ -1,7 +1,7 @@
/*
* HND SiliconBackplane PCI core hardware definitions.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbpci.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _sbpci_h_
@@ -68,8 +68,11 @@ typedef struct sbpciregs {
#define PCI_PARKID_EXT0 0 /* External master 0 */
#define PCI_PARKID_EXT1 1 /* External master 1 */
#define PCI_PARKID_EXT2 2 /* External master 2 */
-#define PCI_PARKID_INT 3 /* Internal master */
-#define PCI_PARKID_LAST 4 /* Last active master */
+#define PCI_PARKID_EXT3 3 /* External master 3 (rev >= 11) */
+#define PCI_PARKID_INT 3 /* Internal master (rev < 11) */
+#define PCI11_PARKID_INT 4 /* Internal master (rev >= 11) */
+#define PCI_PARKID_LAST 4 /* Last active master (rev < 11) */
+#define PCI11_PARKID_LAST 5 /* Last active master (rev >= 11) */
/* Interrupt status/mask */
#define PCI_INTA 0x01 /* PCI INTA# is asserted */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcie.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcie.h
index 58990c9774..9819c0c41a 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcie.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcie.h
@@ -1,7 +1,7 @@
/*
* BCM43XX SiliconBackplane PCIE core hardware definitions.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbpcie.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _SBPCIE_H
@@ -38,11 +38,17 @@
#define PCIE_BAR0_PCIECORE_OFFSET 0x2000
#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000
+/* different register spaces to access thr'u pcie indirect access */
+#define PCIE_CONFIGREGS 1 /* Access to config space */
+#define PCIE_PCIEREGS 2 /* Access to pcie registers */
+
/* SB side: PCIE core and host control registers */
typedef struct sbpcieregs {
uint32 PAD[3];
uint32 biststatus; /* bist Status: 0x00C */
- uint32 PAD[6];
+ uint32 gpiosel; /* PCIE gpio sel: 0x010 */
+ uint32 gpioouten; /* PCIE gpio outen: 0x14 */
+ uint32 PAD[4];
uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
uint32 PAD[54];
uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
@@ -58,11 +64,12 @@ typedef struct sbpcieregs {
uint32 mdiocontrol; /* controls the mdio access: 0x128 */
uint32 mdiodata; /* Data to the mdio access: 0x12c */
- /* pcie protocol phy/dllp/tlp register access mechanism */
- uint32 pcieaddr; /* address of the internal registeru: 0x130 */
- uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */
+ /* pcie protocol phy/dllp/tlp register indirect access mechanism */
+ uint32 pcieindaddr; /* indirect access to the internal register: 0x130 */
+ uint32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
- uint32 PAD[434];
+ uint32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
+ uint32 PAD[433];
uint16 sprom[36]; /* SPROM shadow Area */
} sbpcieregs_t;
@@ -136,6 +143,7 @@ typedef struct sbpcieregs {
#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */
#define PCIE_DLLP_TESTREG 0x14C /* Test */
#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST */
+#define PCIE_DLLP_PCIE11 0x154 /* DLLP PCIE 1.1 reg */
/* PCIE protocol TLP diagnostic registers */
#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */
@@ -192,9 +200,38 @@ typedef struct sbpcieregs {
#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
-/* SERDES registers */
+/* SERDES RX registers */
+#define SERDES_RX_CTRL 1 /* Rx cntrl */
#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
#define SERDES_RX_CDR 6 /* CDR */
#define SERDES_RX_CDRBW 7 /* CDR BW */
+/* SERDES RX control register */
+#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
+#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
+
+/* SERDES PLL registers */
+#define SERDES_PLL_CTRL 1 /* PLL control reg */
+#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
+
+#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
+#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
+#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
+
+/* SPROM offsets */
+#define SRSH_ASPM_OFFSET 4 /* word 4 */
+#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
+#define SRSH_CLKREQ_OFFSET 20 /* word 20 */
+#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
+
+/* Linkcontrol reg offset in PCIE Cap */
+#define PCIE_CAP_LINKCTRL_OFFSET 16 /* linkctrl offset in pcie cap */
+#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
+#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
+#define PCIE_ASPM_ENAB 0x03 /* ASPM L0s & L1 in linkctrl */
+#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
+
+/* Status reg PCIE_PLP_STATUSREG */
+#define PCIE_PLP_POLARITYINV_STAT 0x10
+
#endif /* _SBPCIE_H */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcmcia.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcmcia.h
index 08fd453f49..651bc139f4 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcmcia.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbpcmcia.h
@@ -1,7 +1,7 @@
/*
* BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbpcmcia.h,v 1.1.1.9 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _SBPCMCIA_H
@@ -75,6 +75,8 @@
#define SROM_DATAH (0x073a / 2)
#define SROM_ADDRL (0x073c / 2)
#define SROM_ADDRH (0x073e / 2)
+#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */
+#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */
/* Values for srom_cs: */
#define SROM_IDLE 0
@@ -84,16 +86,30 @@
#define SROM_WDS 7
#define SROM_DONE 8
+/* Fields in srom_info: */
+#define SRI_SZ_MASK 0x03
+#define SRI_BLANK 0x04
+#define SRI_OTP 0x80
+
/* CIS stuff */
/* The CIS stops where the FCRs start */
#define CIS_SIZE PCMCIA_FCR
+/* CIS tuple length field max */
+#define CIS_TUPLE_LEN_MAX 0xff
+
/* Standard tuples we know about */
+#define CISTPL_VERS_1 0x15 /* CIS ver, manf, dev & ver strings */
#define CISTPL_MANFID 0x20 /* Manufacturer and device id */
+#define CISTPL_FUNCID 0x21 /* Function identification */
#define CISTPL_FUNCE 0x22 /* Function extensions */
#define CISTPL_CFTABLE 0x1b /* Config table entry */
+#define CISTPL_END 0xff /* End of the CIS tuple chain */
+
+/* Function identifier provides context for the function extentions tuple */
+
/* Function extensions for LANs */
@@ -135,7 +151,29 @@
#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */
#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */
#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */
-
+#define HNBU_PAPARMS5G 0x0e /* 5G PA params */
+#define HNBU_ANT5G 0x0f /* 4328 5G antennas available/gain */
+#define HNBU_RDLID 0x10 /* 2 byte USB remote downloader (RDL) product Id */
+#define HNBU_RSSISMBXA2G 0x11 /* 4328 2G RSSI mid pt sel & board switch arch,
+ * 2 bytes, rev 3.
+ */
+#define HNBU_RSSISMBXA5G 0x12 /* 4328 5G RSSI mid pt sel & board switch arch,
+ * 2 bytes, rev 3.
+ */
+#define HNBU_XTALFREQ 0x13 /* 4 byte Crystal frequency in kilohertz */
+#define HNBU_TRI2G 0x14 /* 4328 2G TR isolation, 1 byte */
+#define HNBU_TRI5G 0x15 /* 4328 5G TR isolation, 3 bytes */
+#define HNBU_RXPO2G 0x16 /* 4328 2G RX power offset, 1 byte */
+#define HNBU_RXPO5G 0x17 /* 4328 5G RX power offset, 1 byte */
+#define HNBU_BOARDNUM 0x18 /* board serial number, independent of mac addr */
+#define HNBU_MACADDR 0x19 /* mac addr override for the standard CIS LAN_NID */
+#define HNBU_RDLSN 0x1a /* 2 bytes; serial # advertised in USB descriptor */
+#define HNBU_BOARDTYPE 0x1b /* 2 bytes; boardtype */
+#define HNBU_RDLRNDIS 0x20 /* 1 byte; 1 = RDL advertises RNDIS config */
+#define HNBU_RDLRWU 0x30 /* 1 byte; 1 = RDL advertises Remote Wake-up */
+#define HNBU_SROM3SWRGN 0x80 /* 78 bytes; srom rev 3 s/w region without crc8
+ * plus extra info appended.
+ */
/* sbtmstatelow */
#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsdram.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsdram.h
index dec6c29289..615edabb8e 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsdram.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsdram.h
@@ -1,7 +1,7 @@
/*
* BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbsdram.h,v 1.1.1.9 2006/03/02 13:03:52 honor Exp $
+ * $Id$
*/
#ifndef _SBSDRAM_H
@@ -26,16 +26,7 @@ typedef volatile struct sbsdramregs {
uint32 pad2;
} sbsdramregs_t;
-/* SDRAM simulation */
-#ifdef RAMSZ
-#define SDRAMSZ RAMSZ
-#else
-#define SDRAMSZ (4 * 1024 * 1024)
-#endif
-
-extern uchar sdrambuf[SDRAMSZ];
-
-#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* !_LANGUAGE_ASSEMBLY */
/* SDRAM initialization control (initcontrol) register bits */
#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsocram.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsocram.h
index f13bc2e408..6dd49b7632 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsocram.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsocram.h
@@ -1,7 +1,7 @@
/*
* BCM47XX Sonics SiliconBackplane embedded ram core
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,21 +9,21 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbsocram.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _SBSOCRAM_H
#define _SBSOCRAM_H
-#define SR_COREINFO 0x00
-#define SR_BWALLOC 0x04
-#define SR_BISTSTAT 0x0c
-#define SR_BANKINDEX 0x10
-#define SR_BANKSTBYCTL 0x14
-
-
#ifndef _LANGUAGE_ASSEMBLY
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define _PADLINE(line) pad ## line
+#define _XSTR(line) _PADLINE(line)
+#define PAD _XSTR(__LINE__)
+#endif /* PAD */
+
/* Memcsocram core registers */
typedef volatile struct sbsocramregs {
uint32 coreinfo;
@@ -32,13 +32,28 @@ typedef volatile struct sbsocramregs {
uint32 biststat;
uint32 bankidx;
uint32 standbyctrl;
+ uint32 PAD[116];
+ uint32 pwrctl; /* corerev >= 2 */
} sbsocramregs_t;
-#endif
+#endif /* _LANGUAGE_ASSEMBLY */
+
+/* Register offsets */
+#define SR_COREINFO 0x00
+#define SR_BWALLOC 0x04
+#define SR_BISTSTAT 0x0c
+#define SR_BANKINDEX 0x10
+#define SR_BANKSTBYCTL 0x14
+#define SR_PWRCTL 0x1e8
/* Coreinfo register */
-#define SRCI_PT_MASK 0x30000
+#define SRCI_PT_MASK 0x00030000
#define SRCI_PT_SHIFT 16
+/* corerev >= 3 */
+#define SRCI_LSS_MASK 0x00f00000
+#define SRCI_LSS_SHIFT 20
+#define SRCI_LRS_MASK 0x0f000000
+#define SRCI_LRS_SHIFT 24
/* In corerev 0, the memory size is 2 to the power of the
* base plus 16 plus to the contents of the memsize field plus 1.
@@ -61,4 +76,11 @@ typedef volatile struct sbsocramregs {
#define SRCI_SRBSZ_SHIFT 0
#define SR_BSZ_BASE 14
+
+/* Standby control register */
+#define SRSC_SBYOVR_MASK 0x80000000
+#define SRSC_SBYOVR_SHIFT 31
+#define SRSC_SBYOVRVAL_MASK 0x60000000
+#define SRSC_SBYOVRVAL_SHIFT 29
+
#endif /* _SBSOCRAM_H */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsprom.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsprom.h
new file mode 100644
index 0000000000..042ef04412
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbsprom.h
@@ -0,0 +1,277 @@
+/*
+ * SPROM format definitions for the Broadcom 47xx and 43xx chip family.
+ *
+ * $Id$
+ * Copyright(c) 2002 Broadcom Corporation
+ */
+
+#ifndef _SBSPROM_H
+#define _SBSPROM_H
+
+#include "typedefs.h"
+#include "bcmdevs.h"
+
+/* A word is this many bytes */
+#define SRW 2
+
+/* offset into PCI config space for write enable bit */
+#define CFG_SROM_WRITABLE_OFFSET 0x88
+#define SROM_WRITEABLE 0x10
+
+/* enumeration space consists of N contiguous 4Kbyte core register sets */
+#define SBCORES_BASE 0x18000000
+#define SBCORES_EACH 0x1000
+
+/* offset from BAR0 for srom space */
+#define SROM_BASE 4096
+
+/* number of 2-byte words in srom */
+#define SROM_SIZE 64
+
+#define SROM_BYTES (SROM_SIZE * SRW)
+
+#define MAX_FN 4
+
+/* Word 0, Hardware control */
+#define SROM_HWCTL 0
+#define HW_FUNMSK 0x000f
+#define HW_FCLK 0x0200
+#define HW_CBM 0x0400
+#define HW_PIMSK 0xf000
+#define HW_PISHIFT 12
+#define HW_4301PISHIFT 13
+#define HW_PI4402 0x2
+#define HW_FUN4401 0x0001
+#define HW_FCLK4402 0x0000
+
+/* Word 1, common-power/boot-rom */
+#define SROM_COMMPW 1
+/* boot rom present bit */
+#define BR_PRESSHIFT 8
+/* 15:9 for n; boot rom size is 2^(14 + n) bytes */
+#define BR_SIZESHIFT 9
+
+/* Word 2, SubsystemId */
+#define SROM_SSID 2
+
+/* Word 3, VendorId */
+#define SROM_VID 3
+
+/* Function 0 info, function info length */
+#define SROM_FN0 4
+#define SROM_FNSZ 8
+
+/* Within each function: */
+/* Word 0, deviceID */
+#define SRFN_DID 0
+
+/* Words 1-2, ClassCode */
+#define SRFN_CCL 1
+/* Word 2, D0 Power */
+#define SRFN_CCHD0 2
+
+/* Word 3, PME and D1D2D3 power */
+#define SRFN_PMED123 3
+
+#define PME_IL 0
+#define PME_ENET0 1
+#define PME_ENET1 2
+#define PME_CODEC 3
+
+#define PME_4402_ENET 0
+#define PME_4402_CODEC 1
+#define PME_4301_WL 2
+#define PMEREP_4402_ENET (PMERD3CV | PMERD3CA | PMERD3H | PMERD2 | PMERD1 | PMERD0 | PME)
+
+/* Word 4, Bar1 enable, pme reports */
+#define SRFN_B1PMER 4
+#define B1E 1
+#define B1SZMSK 0xe
+#define B1SZSH 1
+#define PMERMSK 0x0ff0
+#define PME 0x0010
+#define PMERD0 0x0020
+#define PMERD1 0x0040
+#define PMERD2 0x0080
+#define PMERD3H 0x0100
+#define PMERD3CA 0x0200
+#define PMERD3CV 0x0400
+#define IGNCLKRR 0x0800
+#define B0LMSK 0xf000
+
+/* Words 4-5, Bar0 Sonics value */
+#define SRFN_B0H 5
+/* Words 6-7, CIS Pointer */
+#define SRFN_CISL 6
+#define SRFN_CISH 7
+
+/* Words 36-38: iLine MAC address */
+#define SROM_I_MACHI 36
+#define SROM_I_MACMID 37
+#define SROM_I_MACLO 38
+
+/* Words 36-38: wireless0 MAC address on 43xx */
+#define SROM_W0_MACHI 36
+#define SROM_W0_MACMID 37
+#define SROM_W0_MACLO 38
+
+/* Words 39-41: enet0 MAC address */
+#define SROM_E0_MACHI 39
+#define SROM_E0_MACMID 40
+#define SROM_E0_MACLO 41
+
+/* Words 42-44: enet1 MAC address */
+#define SROM_E1_MACHI 42
+#define SROM_E1_MACMID 43
+#define SROM_E1_MACLO 44
+
+/* Words 42-44: wireless1 MAC address on 4309 */
+#define SROM_W1_MACHI 42
+#define SROM_W1_MACMID 43
+#define SROM_W1_MACLO 44
+
+#define SROM_EPHY 45
+
+/* Word 46: BdRev & Antennas0/1 & ccLock for 430x */
+#define SROM_REV_AA_LOCK 46
+
+/* Words 47-51 wl0 PA bx */
+#define SROM_WL0_PAB0 47
+#define SROM_WL0_PAB1 48
+#define SROM_WL0_PAB2 49
+#define SROM_WL0_PAB3 50
+#define SROM_WL0_PAB4 51
+
+/* Word 52: wl0/wl1 MaxPower */
+#define SROM_WL_MAXPWR 52
+
+/* Words 53-55 wl1 PA bx */
+#define SROM_WL1_PAB0 53
+#define SROM_WL1_PAB1 54
+#define SROM_WL1_PAB2 55
+
+/* Woprd 56: itt */
+#define SROM_ITT 56
+
+/* Words 59-62: OEM Space */
+#define SROM_WL_OEM 59
+#define SROM_OEM_SIZE 4
+
+/* Contents for the srom */
+
+#define BU4710_SSID 0x0400
+#define VSIM4710_SSID 0x0401
+#define QT4710_SSID 0x0402
+
+#define BU4610_SSID 0x0403
+#define VSIM4610_SSID 0x0404
+
+#define BU4307_SSID 0x0405
+#define BCM94301CB_SSID 0x0406
+#define BCM94301MP_SSID 0x0407
+#define BCM94307MP_SSID 0x0408
+#define AP4307_SSID 0x0409
+
+#define BU4309_SSID 0x040a
+#define BCM94309CB_SSID 0x040b
+#define BCM94309MP_SSID 0x040c
+#define AP4309_SSID 0x040d
+
+#define BU4402_SSID 0x4402
+
+#define CLASS_OTHER 0x8000
+#define CLASS_ETHER 0x0000
+#define CLASS_NET 0x0002
+#define CLASS_COMM 0x0007
+#define CLASS_MODEM 0x0300
+#define CLASS_MIPS 0x3000
+#define CLASS_PROC 0x000b
+#define CLASS_FLASH 0x0100
+#define CLASS_MEM 0x0005
+#define CLASS_SERIALBUS 0x000c
+#define CLASS_OHCI 0x0310
+
+/* Broadcom IEEE MAC addresses are 00:90:4c:xx:xx:xx */
+#define MACHI 0x90
+
+#define MACMID_BU4710I 0x4c17
+#define MACMID_BU4710E0 0x4c18
+#define MACMID_BU4710E1 0x4c19
+
+#define MACMID_94710R1I 0x4c1a
+#define MACMID_94710R1E0 0x4c1b
+#define MACMID_94710R1E1 0x4c1c
+
+#define MACMID_94710R4I 0x4c1d
+#define MACMID_94710R4E0 0x4c1e
+#define MACMID_94710R4E1 0x4c1f
+
+#define MACMID_94710DEVI 0x4c20
+#define MACMID_94710DEVE0 0x4c21
+#define MACMID_94710DEVE1 0x4c22
+
+#define MACMID_BU4402 0x4c23
+
+#define MACMID_BU4610I 0x4c24
+#define MACMID_BU4610E0 0x4c25
+#define MACMID_BU4610E1 0x4c26
+
+#define MACMID_BU4307W 0x4c27
+#define MACMID_BU4307E 0x4c28
+
+#define MACMID_94301CB 0x4c29
+
+#define MACMID_94301MP 0x4c2a
+
+#define MACMID_94307MPW 0x4c2b
+#define MACMID_94307MPE 0x4c2c
+
+#define MACMID_AP4307W 0x4c2d
+#define MACMID_AP4307E 0x4c2e
+
+#define MACMID_BU4309W0 0x4c2f
+#define MACMID_BU4309W1 0x4c30
+#define MACMID_BU4309E 0x4c31
+
+#define MACMID_94309CBW0 0x4c32
+#define MACMID_94309CBW1 0x4c33
+
+#define MACMID_94309MPW0 0x4c34
+#define MACMID_94309MPW1 0x4c35
+#define MACMID_94309MPE 0x4c36
+
+#define MACMID_BU4401 0x4c37
+
+/* Enet phy settings one or two singles or a dual */
+/* Bits 4-0 : MII address for enet0 (0x1f for not there */
+/* Bits 9-5 : MII address for enet1 (0x1f for not there */
+/* Bit 14 : Mdio for enet0 */
+/* Bit 15 : Mdio for enet1 */
+
+/* bu4710 with only one phy on enet1 with address 7: */
+#define SROM_EPHY_ONE 0x80ff
+
+/* bu4710 with two individual phys, at 6 and 7, */
+/* each mdio connected to its own mac: */
+#define SROM_EPHY_TWO 0x80e6
+
+/* bu4710 with a dual phy addresses 0 & 1, mdio-connected to enet0 */
+#define SROM_EPHY_DUAL 0x0001
+
+/* r1 board with a dual phy at 0, 1 (NOT swapped and mdc0 */
+#define SROM_EPHY_R1 0x0010
+
+/* r4 board with a single phy on enet0 at address 5 and a switch */
+/* chip on enet1 (speciall case: 0x1e */
+#define SROM_EPHY_R4 0x83e5
+
+/* 4402 uses an internal phy at phyaddr 1; want mdcport == coreunit == 0 */
+#define SROM_EPHY_INTERNAL 0x0001
+
+/* 4307 uses an external phy at phyaddr 0; want mdcport == coreunit == 0 */
+#define SROM_EPHY_ZERO 0x0000
+
+#define SROM_VERS 0x0001
+
+
+#endif /* _SBSPROM_H */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbutils.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbutils.h
index db4d27136f..ed95cb3815 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbutils.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sbutils.h
@@ -2,7 +2,7 @@
* Misc utility routines for accessing chip-specific features
* of Broadcom HNBU SiliconBackplane-based chips.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -10,14 +10,14 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sbutils.h,v 1.4 2006/04/08 07:12:42 honor Exp $
+ * $Id$
*/
#ifndef _sbutils_h_
#define _sbutils_h_
/*
- * Datastructure to export all chip specific common variables
+ * Data structure to export all chip specific common variables
* public (read-only) portion of sbutils handle returned by
* sb_attach()/sb_kattach()
*/
@@ -29,15 +29,22 @@ struct sb_pub {
uint buscorerev; /* buscore rev */
uint buscoreidx; /* buscore index */
int ccrev; /* chip common core rev */
+ uint32 cccaps; /* chip common capabilities */
+ int pmurev; /* pmu core rev */
+ uint32 pmucaps; /* pmu capabilities */
uint boardtype; /* board type */
uint boardvendor; /* board vendor */
+ uint boardflags; /* board flags */
uint chip; /* chip number */
uint chiprev; /* chip revision */
uint chippkg; /* chip package option */
+ uint32 chipst; /* chip status */
uint sonicsrev; /* sonics backplane rev */
+ bool pr42780; /* whether PCIE 42780 WAR applies to this chip */
+ bool pr32414; /* whether 432414 WAR applis to the chip */
};
-typedef const struct sb_pub sb_t;
+typedef const struct sb_pub sb_t;
/*
* Many of the routines below take an 'sbh' handle as their first arg.
@@ -48,10 +55,11 @@ typedef const struct sb_pub sb_t;
*/
#define SB_OSH NULL /* Use for sb_kattach when no osh is available */
+
/* exported externs */
extern sb_t *sb_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
void *sdh, char **vars, uint *varsz);
-extern sb_t *sb_kattach(void);
+extern sb_t *sb_kattach(osl_t *osh);
extern void sb_detach(sb_t *sbh);
extern uint sb_chip(sb_t *sbh);
extern uint sb_chiprev(sb_t *sbh);
@@ -67,16 +75,20 @@ extern uint sb_buscoretype(sb_t *sbh);
extern uint sb_buscorerev(sb_t *sbh);
extern uint sb_corelist(sb_t *sbh, uint coreid[]);
extern uint sb_coreid(sb_t *sbh);
+extern uint sb_flag(sb_t *sbh);
extern uint sb_coreidx(sb_t *sbh);
extern uint sb_coreunit(sb_t *sbh);
extern uint sb_corevendor(sb_t *sbh);
extern uint sb_corerev(sb_t *sbh);
extern void *sb_osh(sb_t *sbh);
extern void sb_setosh(sb_t *sbh, osl_t *osh);
+extern uint sb_corereg(sb_t *sbh, uint coreidx, uint regoff, uint mask, uint val);
extern void *sb_coreregs(sb_t *sbh);
extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val);
+extern void sb_coreflags_wo(sb_t *sbh, uint32 mask, uint32 val);
extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val);
extern bool sb_iscoreup(sb_t *sbh);
+extern uint sb_findcoreidx(sb_t *sbh, uint coreid, uint coreunit);
extern void *sb_setcoreidx(sb_t *sbh, uint coreidx);
extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit);
extern int sb_corebist(sb_t *sbh);
@@ -88,6 +100,7 @@ extern void sb_core_tofixup(sb_t *sbh);
extern void sb_core_disable(sb_t *sbh, uint32 bits);
extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m);
extern uint32 sb_clock(sb_t *sbh);
+extern uint32 sb_alp_clock(sb_t *sbh);
extern void sb_pci_setup(sb_t *sbh, uint coremask);
extern void sb_pcmcia_init(sb_t *sbh);
extern void sb_watchdog(sb_t *sbh, uint ticks);
@@ -101,6 +114,17 @@ extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val);
extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority);
extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority);
+extern uint32 sb_gpiopull(sb_t *sbh, bool updown, uint32 mask, uint32 val);
+extern uint32 sb_gpioevent(sb_t *sbh, uint regtype, uint32 mask, uint32 val);
+extern uint32 sb_gpio_int_enable(sb_t *sbh, bool enable);
+
+/* GPIO event handlers */
+typedef void (*gpio_handler_t)(uint32 stat, void *arg);
+
+extern void *sb_gpio_handler_register(sb_t *sbh, uint32 event,
+ bool level, gpio_handler_t cb, void *arg);
+extern void sb_gpio_handler_unregister(sb_t *sbh, void* gpioh);
+extern void sb_gpio_handler_process(sb_t *sbh);
extern void sb_clkctl_init(sb_t *sbh);
extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh);
@@ -108,7 +132,9 @@ extern bool sb_clkctl_clk(sb_t *sbh, uint mode);
extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on);
extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn,
void *intrsenabled_fn, void *intr_arg);
-extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to);
+extern void sb_deregister_intr_callback(sb_t *sbh);
+extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to, uint idx);
+extern uint16 sb_d11_devid(sb_t *sbh);
extern int sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif,
uint8 *pciheader);
@@ -119,7 +145,19 @@ extern bool sb_backplane64(sb_t *sbh);
extern void sb_btcgpiowar(sb_t *sbh);
+#if defined(BCMDBG_ASSERT)
+extern bool sb_taclear(sb_t *sbh);
+#endif
+#ifdef BCMDBG
+extern void sb_dump(sb_t *sbh, struct bcmstrbuf *b);
+extern void sb_dumpregs(sb_t *sbh, struct bcmstrbuf *b);
+extern void sb_view(sb_t *sbh);
+extern void sb_viewall(sb_t *sbh);
+extern void sb_clkctl_dump(sb_t *sbh, struct bcmstrbuf *b);
+extern uint8 sb_pcieL1plldown(sb_t *sbh);
+extern uint32 sb_pcielcreg(sb_t *sbh, uint32 mask, uint32 val);
+#endif
extern bool sb_deviceremoved(sb_t *sbh);
extern uint32 sb_socram_size(sb_t *sbh);
@@ -130,6 +168,20 @@ extern uint32 sb_socram_size(sb_t *sbh);
* Return 0 on success, nonzero otherwise.
*/
extern int sb_devpath(sb_t *sbh, char *path, int size);
+/* Read variable with prepending the devpath to the name */
+extern char *sb_getdevpathvar(sb_t *sbh, const char *name);
+extern int sb_getdevpathintvar(sb_t *sbh, const char *name);
+
+extern uint8 sb_pcieclkreq(sb_t *sbh, uint32 mask, uint32 val);
+extern void sb_war42780_clkreq(sb_t *sbh, bool clkreq);
+extern void sb_pci_sleep(sb_t *sbh);
+extern void sb_pci_down(sb_t *sbh);
+extern void sb_pci_up(sb_t *sbh);
+
+/* Wake-on-wireless-LAN (WOWL) */
+extern bool sb_pci_pmecap(sb_t *sbh);
+extern bool sb_pci_pmeclr(sb_t *sbh);
+extern void sb_pci_pmeen(sb_t *sbh);
/* clkctl xtal what flags */
#define XTAL 0x1 /* primary crystal oscillator (2050) */
@@ -143,7 +195,16 @@ extern int sb_devpath(sb_t *sbh, char *path, int size);
/* GPIO usage priorities */
#define GPIO_DRV_PRIORITY 0 /* Driver */
#define GPIO_APP_PRIORITY 1 /* Application */
-#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */
+#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */
+
+/* GPIO pull up/down */
+#define GPIO_PULLUP 0
+#define GPIO_PULLDN 1
+
+/* GPIO event regtype */
+#define GPIO_REGEVT 0 /* GPIO register event */
+#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
+#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
/* device path */
#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sflash.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sflash.h
index 21a6788fb2..2bdd5fc13c 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sflash.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/sflash.h
@@ -1,7 +1,7 @@
/*
* Broadcom SiliconBackplane chipcommon serial flash interface
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,7 +9,7 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sflash.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#ifndef _sflash_h_
@@ -17,6 +17,7 @@
#include <typedefs.h>
#include <sbchipc.h>
+#include <sbutils.h>
struct sflash {
uint blocksize; /* Block size */
@@ -26,11 +27,14 @@ struct sflash {
};
/* Utility functions */
-extern int sflash_poll(chipcregs_t *cc, uint offset);
-extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf);
-extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
-extern int sflash_erase(chipcregs_t *cc, uint offset);
-extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
-extern struct sflash * sflash_init(chipcregs_t *cc);
+extern int sflash_poll(sb_t *sbh, chipcregs_t *cc, uint offset);
+extern int sflash_read(sb_t *sbh, chipcregs_t *cc,
+ uint offset, uint len, uchar *buf);
+extern int sflash_write(sb_t *sbh, chipcregs_t *cc,
+ uint offset, uint len, const uchar *buf);
+extern int sflash_erase(sb_t *sbh, chipcregs_t *cc, uint offset);
+extern int sflash_commit(sb_t *sbh, chipcregs_t *cc,
+ uint offset, uint len, const uchar *buf);
+extern struct sflash *sflash_init(sb_t *sbh, chipcregs_t *cc);
#endif /* _sflash_h_ */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/trxhdr.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/trxhdr.h
index 4b48dfd2fe..4620725f89 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/trxhdr.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/trxhdr.h
@@ -1,7 +1,7 @@
/*
* TRX image file header format.
*
- * Copyright 2005, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -10,16 +10,16 @@
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id$
- */
+ */
#include <typedefs.h>
#define TRX_MAGIC 0x30524448 /* "HDR0" */
-#define TRX_VERSION 1
-#define TRX_MAX_LEN 0x3A0000
-#define TRX_NO_HEADER 1 /* Do not write TRX header */
+#define TRX_VERSION 1 /* Version 1 */
+#define TRX_MAX_LEN 0x7A0000 /* Max length */
+#define TRX_NO_HEADER 1 /* Do not write TRX header */
#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
-#define TRX_MAX_OFFSET 3
+#define TRX_MAX_OFFSET 3 /* Max number of individual files */
struct trx_header {
uint32 magic; /* "HDR0" */
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/typedefs.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/typedefs.h
index 9c91e2cc57..adb6b1589d 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/typedefs.h
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/include/typedefs.h
@@ -1,12 +1,12 @@
/*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: typedefs.h,v 1.1.1.12 2006/04/08 06:13:40 honor Exp $
+ * $Id$
*/
#ifndef _TYPEDEFS_H_
@@ -69,10 +69,13 @@ typedef unsigned char bool; /* consistent w/BOOL */
#endif /* ! __cplusplus */
/* use the Windows ULONG_PTR type when compiling for 64 bit */
-#if defined(_WIN64)
+#if defined(_WIN64) && !defined(EFI)
#include <basetsd.h>
#define TYPEDEF_UINTPTR
-typedef ULONG_PTR uintptr;
+typedef ULONG_PTR uintptr;
+#elif defined(__x86_64__)
+#define TYPEDEF_UINTPTR
+typedef unsigned long long int uintptr;
#endif
@@ -80,6 +83,10 @@ typedef ULONG_PTR uintptr;
#define _NEED_SIZE_T_
#endif
+#if defined(EFI) && !defined(_WIN64)
+#define _NEED_SIZE_T_
+#endif
+
#if defined(_NEED_SIZE_T_)
typedef long unsigned int size_t;
#endif
@@ -104,14 +111,20 @@ typedef unsigned __int64 uint64;
#endif
-#if defined(linux)
+#ifdef linux
#define TYPEDEF_UINT
#define TYPEDEF_USHORT
#define TYPEDEF_ULONG
-#endif
+#ifdef __KERNEL__
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
+#define TYPEDEF_BOOL
+#endif /* >= 2.6.19 */
+#endif /* __KERNEL__ */
+#endif /* linux */
#if !defined(linux) && !defined(_WIN32) && !defined(_CFE_) && \
- !defined(_HNDRTE_) && !defined(_MINOSL_) && !defined(__DJGPP__)
+ !defined(_HNDRTE_) && !defined(_MINOSL_) && !defined(__DJGPP__) && !defined(__IOPOS__)
#define TYPEDEF_UINT
#define TYPEDEF_USHORT
#endif
@@ -137,7 +150,7 @@ typedef unsigned __int64 uint64;
#endif /* __ICL */
#if !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && \
- !defined(__DJGPP__)
+ !defined(__DJGPP__) && !defined(__IOPOS__)
/* pick up ushort & uint from standard types.h */
#if defined(linux) && defined(__KERNEL__)
@@ -150,7 +163,7 @@ typedef unsigned __int64 uint64;
#endif
-#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ && !__DJGPP__ */
+#endif
#if defined(MACOSX)
@@ -320,7 +333,7 @@ typedef float64 float_t;
#define INLINE __inline
-#elif __GNUC__
+#elif defined(__GNUC__)
#define INLINE __inline__
@@ -353,8 +366,8 @@ typedef float64 float_t;
#endif /* USE_TYPEDEF_DEFAULTS */
/*
- * Including the bcmdefs.h here, to make sure everyone including typedefs.h
- * gets this automatically
+ * Including the bcmdefs.h here, to make sure everyone including typedefs.h
+ * gets this automatically
*/
#include "bcmdefs.h"
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram.c
index d9af5ff8f8..c37023bce7 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram.c
@@ -15,7 +15,6 @@
#include <osl.h>
#include <bcmendian.h>
#include <bcmnvram.h>
-#include <bcmutils.h>
#include <sbsdram.h>
extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value);
@@ -244,10 +243,10 @@ BCMINITFN(_nvram_commit)(struct nvram_header *header)
header->config_refresh |= SDRAM_REFRESH << 16;
header->config_ncdl = 0;
} else {
- header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16;
- header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff;
- header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16;
- header->config_ncdl = bcm_strtoul(ncdl, NULL, 0);
+ header->crc_ver_init |= (simple_strtoul(init, NULL, 0) & 0xffff) << 16;
+ header->config_refresh = simple_strtoul(config, NULL, 0) & 0xffff;
+ header->config_refresh |= (simple_strtoul(refresh, NULL, 0) & 0xffff) << 16;
+ header->config_ncdl = simple_strtoul(ncdl, NULL, 0);
}
/* Clear data area */
@@ -276,7 +275,7 @@ BCMINITFN(_nvram_commit)(struct nvram_header *header)
tmp.crc_ver_init = htol32(header->crc_ver_init);
tmp.config_refresh = htol32(header->config_refresh);
tmp.config_ncdl = htol32(header->config_ncdl);
- crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);
+ crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, 0xff);
/* Continue CRC8 over data bytes */
crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc);
@@ -313,3 +312,46 @@ BCMINITFN(_nvram_exit)(void)
{
BCMINIT(nvram_free)();
}
+
+/*
+ * Search the name=value vars for a specific one and return its value.
+ * Returns NULL if not found.
+ */
+char*
+getvar(char *vars, const char *name)
+{
+ char *s;
+ int len;
+
+ len = strlen(name);
+
+ /* first look in vars[] */
+ for (s = vars; s && *s;) {
+ /* CSTYLED */
+ if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+ return (&s[len+1]);
+
+ while (*s++)
+ ;
+ }
+
+ /* then query nvram */
+ return (nvram_get(name));
+}
+
+/*
+ * Search the vars for a specific one and return its value as
+ * an integer. Returns 0 if not found.
+ */
+int
+getintvar(char *vars, const char *name)
+{
+ char *val;
+
+ if ((val = getvar(vars, name)) == NULL)
+ return (0);
+
+ return (simple_strtoul(val, NULL, 0));
+}
+
+
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram_linux.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram_linux.c
index 25104786d5..32278b3778 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram_linux.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/nvram_linux.c
@@ -33,7 +33,6 @@
#include <osl.h>
#include <bcmendian.h>
#include <bcmnvram.h>
-#include <bcmutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sbutils.h>
@@ -53,6 +52,9 @@ static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
extern void *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
+static int cfe_env;
+extern char *cfe_env_get(char *nv_buf, const char *name);
+
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
@@ -72,14 +74,14 @@ early_nvram_init(void)
if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
base = KSEG1ADDR(SB_FLASH2);
- switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
+ switch (readl(&cc->capabilities) & CC_CAP_FLASH_MASK) {
case PFLASH:
lim = SB_FLASH2_SZ;
break;
case SFLASH_ST:
case SFLASH_AT:
- if ((info = sflash_init(cc)) == NULL)
+ if ((info = sflash_init(sbh,cc)) == NULL)
return;
lim = info->size;
break;
@@ -105,6 +107,7 @@ early_nvram_init(void)
break;
*dst++ = *src++;
}
+ cfe_env = 1;
return;
}
@@ -154,6 +157,9 @@ early_nvram_get(const char *name)
if (!nvram_buf[0])
early_nvram_init();
+ if (cfe_env)
+ return cfe_env_get(nvram_buf, name);
+
/* Look for name=value and return value */
var = &nvram_buf[sizeof(struct nvram_header)];
end = nvram_buf + sizeof(nvram_buf) - 2;
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/pcibios.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/pcibios.c
index 8c8f6aab59..2d8549623a 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/pcibios.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/pcibios.c
@@ -25,7 +25,6 @@
#include <typedefs.h>
#include <osl.h>
-#include <bcmutils.h>
#include <sbconfig.h>
#include <sbutils.h>
#include <hndpci.h>
@@ -134,7 +133,7 @@ pcibios_init(void)
{
ulong flags;
- if (!(sbh = sb_kattach()))
+ if (!(sbh = sb_kattach(SB_OSH)))
panic("sb_kattach failed");
spin_lock_init(&sbh_lock);
@@ -312,6 +311,25 @@ pcibios_enable_device(struct pci_dev *dev, int mask)
writel(0x7FF, (ulong)regs + 0x200);
udelay(1);
}
+ /* PRxxxx: War for 5354 failures. */
+ if (sb_corerev(sbh) == 1) {
+ uint32 tmp;
+
+ /* Change Flush control reg */
+ tmp = readl((uintptr)regs + 0x400);
+ tmp &= ~8;
+ writel(tmp, (uintptr)regs + 0x400);
+ tmp = readl((uintptr)regs + 0x400);
+ printk("USB20H fcr: 0x%x\n", tmp);
+
+ /* Change Shim control reg */
+ tmp = readl((uintptr)regs + 0x304);
+ tmp &= ~0x100;
+ writel(tmp, (uintptr)regs + 0x304);
+ tmp = readl((uintptr)regs + 0x304);
+ printk("USB20H shim cr: 0x%x\n", tmp);
+ }
+
} else
sb_core_reset(sbh, 0, 0);
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbmips.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbmips.c
index 4a18bb9563..86e2970d24 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbmips.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbmips.c
@@ -1,7 +1,7 @@
/*
* BCM47XX Sonics SiliconBackplane MIPS core routines
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9,27 +9,27 @@
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: hndmips.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
+ * $Id$
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
-#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
#include <bcmnvram.h>
#include <sbconfig.h>
-#include <sbextif.h>
#include <sbchipc.h>
+#include <sbextif.h>
#include <sbmemc.h>
#include <mipsinc.h>
#include <sbhndmips.h>
#include <hndcpu.h>
+#include <hndmips.h>
/* sbipsflag register format, indexed by irq. */
static const uint32 sbips_int_mask[] = {
- 0, /* placeholder */
+ 0, /* placeholder */
SBIPS_INT1_MASK,
SBIPS_INT2_MASK,
SBIPS_INT3_MASK,
@@ -37,7 +37,7 @@ static const uint32 sbips_int_mask[] = {
};
static const uint32 sbips_int_shift[] = {
- 0, /* placeholder */
+ 0, /* placeholder */
SBIPS_INT1_SHIFT,
SBIPS_INT2_SHIFT,
SBIPS_INT3_SHIFT,
@@ -54,8 +54,7 @@ static const uint32 sbips_int_shift[] = {
static uint shirq_map_base = 0;
/* Returns the SB interrupt flag of the current core. */
-static uint32
-sb_getflag(sb_t *sbh)
+static uint32 sb_getflag(sb_t * sbh)
{
osl_t *osh;
void *regs;
@@ -63,7 +62,7 @@ sb_getflag(sb_t *sbh)
osh = sb_osh(sbh);
regs = sb_coreregs(sbh);
- sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
+ sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF);
return (R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK);
}
@@ -72,8 +71,7 @@ sb_getflag(sb_t *sbh)
* Returns the MIPS IRQ assignment of the current core. If unassigned,
* 0 is returned.
*/
-uint
-sb_irq(sb_t *sbh)
+uint sb_irq(sb_t * sbh)
{
osl_t *osh;
uint idx;
@@ -89,12 +87,13 @@ sb_irq(sb_t *sbh)
if ((regs = sb_setcore(sbh, SB_MIPS, 0)) ||
(regs = sb_setcore(sbh, SB_MIPS33, 0))) {
- sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
+ sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF);
/* sbipsflag specifies which core is routed to interrupts 1 to 4 */
sbipsflag = R_REG(osh, &sb->sbipsflag);
for (irq = 1; irq <= 4; irq++) {
- if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag)
+ if (((sbipsflag & sbips_int_mask[irq]) >>
+ sbips_int_shift[irq]) == flag)
break;
}
if (irq == 5)
@@ -107,9 +106,7 @@ sb_irq(sb_t *sbh)
}
/* Clears the specified MIPS IRQ. */
-static void
-BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq)
-{
+static void BCMINITFN(sb_clearirq) (sb_t * sbh, uint irq) {
osl_t *osh;
void *regs;
sbconfig_t *sb;
@@ -119,7 +116,7 @@ BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq)
if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
!(regs = sb_setcore(sbh, SB_MIPS33, 0)))
ASSERT(regs);
- sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
+ sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF);
if (irq == 0)
W_REG(osh, &sb->sbintvec, 0);
@@ -134,8 +131,7 @@ BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq)
* The old assignment to the specified core is removed first.
*/
static void
-BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit)
-{
+BCMINITFN(sb_setirq) (sb_t * sbh, uint irq, uint coreid, uint coreunit) {
osl_t *osh;
void *regs;
sbconfig_t *sb;
@@ -154,7 +150,7 @@ BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit)
if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
!(regs = sb_setcore(sbh, SB_MIPS33, 0)))
ASSERT(regs);
- sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
+ sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF);
if (!oldirq)
AND_REG(osh, &sb->sbintvec, ~(1 << flag));
@@ -175,9 +171,7 @@ BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit)
*
* 'shirqmap' enables virtual dedicated OS IRQ mapping if non-zero.
*/
-void
-BCMINITFN(sb_mips_init)(sb_t *sbh, uint shirqmap)
-{
+void BCMINITFN(sb_mips_init) (sb_t * sbh, uint shirqmap) {
osl_t *osh;
ulong hz, ns, tmp;
extifregs_t *eir;
@@ -199,28 +193,27 @@ BCMINITFN(sb_mips_init)(sb_t *sbh, uint shirqmap)
/* Set timing for the flash */
tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
- tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
- tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
+ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
W_REG(osh, &eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
/* Set programmable interface timing for external uart */
tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
- tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
- tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
- tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
+ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
+ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
W_REG(osh, &eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
} else if ((cc = sb_setcore(sbh, SB_CC, 0))) {
/* Set timing for the flash */
tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */
- tmp |= CEIL(120, ns); /* W0 = 120nS */
- if ((sb_corerev(sbh) < 9) ||
- (BCMINIT(sb_chip)(sbh) == 0x5365))
+ tmp |= CEIL(120, ns); /* W0 = 120nS */
+ if ((sb_corerev(sbh) < 9) || (sb_chip(sbh) == 0x5365))
W_REG(osh, &cc->flash_waitcount, tmp);
if ((sb_corerev(sbh) < 9) ||
- ((sb_chip(sbh) == BCM5350_CHIP_ID) && sb_chiprev(sbh) == 0) ||
- (BCMINIT(sb_chip)(sbh) == 0x5365)) {
+ ((sb_chip(sbh) == BCM5350_CHIP_ID) && sb_chiprev(sbh) == 0)
+ || (sb_chip(sbh) == 0x5365)) {
W_REG(osh, &cc->pcmcia_memwait, tmp);
}
@@ -290,18 +283,21 @@ BCMINITFN(sb_cpu_clock)(sb_t *sbh)
n = R_REG(osh, &eir->clockcontrol_n);
m = R_REG(osh, &eir->clockcontrol_sb);
} else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
- pll_type = R_REG(osh, &cc->capabilities) & CAP_PLL_MASK;
+ /* 5354 chip uses a non programmable PLL of frequency 240MHz */
+ if (sb_chip(sbh) == BCM5354_CHIP_ID) {
+ rate = 240000000;
+ goto out;
+ }
+ pll_type = R_REG(osh, &cc->capabilities) & CC_CAP_PLL_MASK;
n = R_REG(osh, &cc->clockcontrol_n);
if ((pll_type == PLL_TYPE2) ||
(pll_type == PLL_TYPE4) ||
- (pll_type == PLL_TYPE6) ||
- (pll_type == PLL_TYPE7))
+ (pll_type == PLL_TYPE6) || (pll_type == PLL_TYPE7))
m = R_REG(osh, &cc->clockcontrol_m3);
else if (pll_type == PLL_TYPE5) {
rate = 200000000;
goto out;
- }
- else if (pll_type == PLL_TYPE3) {
+ } else if (pll_type == PLL_TYPE3) {
if (sb_chip(sbh) == BCM5365_CHIP_ID) {
rate = 200000000;
goto out;
@@ -314,9 +310,8 @@ BCMINITFN(sb_cpu_clock)(sb_t *sbh)
} else
goto out;
-
/* calculate rate */
- if (BCMINIT(sb_chip)(sbh) == 0x5365)
+ if (sb_chip(sbh) == 0x5365)
rate = 100000000;
else
rate = sb_clock_rate(pll_type, n, m);
@@ -324,7 +319,7 @@ BCMINITFN(sb_cpu_clock)(sb_t *sbh)
if (pll_type == PLL_TYPE6)
rate = SB2MIPS_T6(rate);
-out:
+ out:
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
@@ -333,30 +328,20 @@ out:
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
-static void
-BCMINITFN(handler)(void)
-{
- __asm__(
- ".set\tmips32\n\t"
- "ssnop\n\t"
- "ssnop\n\t"
- /* Disable interrupts */
- /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
+static void BCMINITFN(handler) (void) {
+ __asm__(".set\tmips32\n\t" "ssnop\n\t" "ssnop\n\t"
+ /* Disable interrupts */
+ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
"mfc0 $15, $12\n\t"
- /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */
+ /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */
"li $14, -31746\n\t"
"and $15, $15, $14\n\t"
- "mtc0 $15, $12\n\t"
- "eret\n\t"
- "nop\n\t"
- "nop\n\t"
+ "mtc0 $15, $12\n\t" "eret\n\t" "nop\n\t" "nop\n\t"
".set\tmips0");
}
/* The following MUST come right after handler() */
-static void
-BCMINITFN(afterhandler)(void)
-{
+static void BCMINITFN(afterhandler) (void) {
}
/*
@@ -366,13 +351,15 @@ BCMINITFN(afterhandler)(void)
* core rev. 15 to a DLL inside the MIPS core in 4785.
*/
bool
-BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock)
-{
+BCMINITFN(sb_mips_setclock) (sb_t * sbh, uint32 mipsclock, uint32 sbclock,
+ uint32 pciclock) {
extifregs_t *eir = NULL;
chipcregs_t *cc = NULL;
mipsregs_t *mipsr = NULL;
- volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2;
- uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg;
+ volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci,
+ *clockcontrol_m2;
+ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm,
+ orig_ratio_cfg;
uint32 pll_type, sync_mode;
uint ic_size, ic_lsize;
uint idx, i;
@@ -387,63 +374,83 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
} n3m_table_t;
static n3m_table_t BCMINITDATA(type1_table)[] = {
/* 96.000 32.000 24.000 */
- { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 },
- /* 100.000 33.333 25.000 */
- { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 },
- /* 104.000 31.200 24.960 */
- { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 },
- /* 108.000 32.400 24.923 */
- { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 },
- /* 112.000 32.000 24.889 */
- { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 },
- /* 115.200 32.000 24.000 */
- { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 },
- /* 120.000 30.000 24.000 */
- { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 },
- /* 124.800 31.200 24.960 */
- { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 },
- /* 128.000 32.000 24.000 */
- { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 },
- /* 132.000 33.000 24.750 */
- { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 },
- /* 136.000 32.640 24.727 */
- { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 },
- /* 140.000 30.000 24.706 */
- { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 },
- /* 144.000 30.857 24.686 */
- { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 },
- /* 150.857 33.000 24.000 */
- { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 },
- /* 152.000 32.571 24.000 */
- { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 },
- /* 156.000 31.200 24.960 */
- { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 },
- /* 160.000 32.000 24.000 */
- { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 },
- /* 163.200 32.640 24.727 */
- { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 },
- /* 168.000 32.000 24.889 */
- { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 },
- /* 176.000 33.000 24.000 */
- { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 },
- };
+ {
+ 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011},
+ /* 100.000 33.333 25.000 */
+ {
+ 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011},
+ /* 104.000 31.200 24.960 */
+ {
+ 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009},
+ /* 108.000 32.400 24.923 */
+ {
+ 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802},
+ /* 112.000 32.000 24.889 */
+ {
+ 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403},
+ /* 115.200 32.000 24.000 */
+ {
+ 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011},
+ /* 120.000 30.000 24.000 */
+ {
+ 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011},
+ /* 124.800 31.200 24.960 */
+ {
+ 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009},
+ /* 128.000 32.000 24.000 */
+ {
+ 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305},
+ /* 132.000 33.000 24.750 */
+ {
+ 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305},
+ /* 136.000 32.640 24.727 */
+ {
+ 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603},
+ /* 140.000 30.000 24.706 */
+ {
+ 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02},
+ /* 144.000 30.857 24.686 */
+ {
+ 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021},
+ /* 150.857 33.000 24.000 */
+ {
+ 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605},
+ /* 152.000 32.571 24.000 */
+ {
+ 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02},
+ /* 156.000 31.200 24.960 */
+ {
+ 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009},
+ /* 160.000 32.000 24.000 */
+ {
+ 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309},
+ /* 163.200 32.640 24.727 */
+ {
+ 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603},
+ /* 168.000 32.000 24.889 */
+ {
+ 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403},
+ /* 176.000 33.000 24.000 */
+ {
+ 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602},};
/* PLL configuration: type 3 */
typedef struct {
uint32 mipsclock;
uint16 n;
- uint32 m2; /* that is the clockcontrol_m2 */
+ uint32 m2; /* that is the clockcontrol_m2 */
} type3_table_t;
static type3_table_t type3_table[] = {
/* for 5350, mips clock is always double sb clock */
- { 150000000, 0x311, 0x4020005 },
- { 200000000, 0x311, 0x4020003 },
- };
+ {150000000, 0x311, 0x4020005},
+ {200000000, 0x311, 0x4020003},
+ };
/* PLL configuration: type 2, 4, 7 */
typedef struct {
uint32 mipsclock;
uint32 sbclock;
+ uint32 pciclock;
uint16 n;
uint32 sb;
uint32 pci33;
@@ -455,142 +462,252 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
uint32 d11_r2;
} n4m_table_t;
static n4m_table_t BCMINITDATA(type2_table)[] = {
- { 120000000, 60000000, 0x0303, 0x01000200, 0x01000600, 0x01000200, 0x05000200, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 150000000, 75000000, 0x0303, 0x01000100, 0x01000600, 0x01000100, 0x05000100, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8,
- 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8,
- 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8,
- 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8,
- 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8,
- 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01010100, 0x05000100, 8,
- 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01010100, 0x05000100, 11,
- 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 330000000, 132000000, 0x0903, 0x01000200, 0x00020200, 0x01010100, 0x05000100, 0,
- 0, 10 /* ratio 4/10 */, 0x02520129 },
- { 330000000, 146666666, 0x0903, 0x01010000, 0x00020200, 0x01010100, 0x05000100, 0,
- 0, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 330000000, 165000000, 0x0903, 0x01000100, 0x00020200, 0x01010100, 0x05000100, 0,
- 0, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 360000000, 120000000, 0x0a03, 0x01000300, 0x00010201, 0x01010200, 0x05000100, 0,
- 0, 12 /* ratio 4/12 */, 0x04920492 },
- { 360000000, 144000000, 0x0a03, 0x01000200, 0x00010201, 0x01010200, 0x05000100, 0,
- 0, 10 /* ratio 4/10 */, 0x02520129 },
- { 360000000, 160000000, 0x0a03, 0x01010000, 0x00010201, 0x01010200, 0x05000100, 0,
- 0, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 360000000, 180000000, 0x0a03, 0x01000100, 0x00010201, 0x01010200, 0x05000100, 0,
- 0, 8 /* ratio 4/8 */, 0x00aa0055 },
- { 390000000, 130000000, 0x0b03, 0x01010100, 0x00020101, 0x01020100, 0x05000100, 0,
- 0, 12 /* ratio 4/12 */, 0x04920492 },
- { 390000000, 156000000, 0x0b03, 0x01000200, 0x00020101, 0x01020100, 0x05000100, 0,
- 0, 10 /* ratio 4/10 */, 0x02520129 },
- { 390000000, 173000000, 0x0b03, 0x01010000, 0x00020101, 0x01020100, 0x05000100, 0,
- 0, 9 /* ratio 4/9 */, 0x012a00a9 },
- { 390000000, 195000000, 0x0b03, 0x01000100, 0x00020101, 0x01020100, 0x05000100, 0,
- 0, 8 /* ratio 4/8 */, 0x00aa0055 },
+ {
+ 120000000, 60000000, 32000000, 0x0303, 0x01000200,
+ 0x01000600, 0x01000200, 0x05000200, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 150000000, 75000000, 33333333, 0x0303, 0x01000100,
+ 0x01000600, 0x01000100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 180000000, 80000000, 30000000, 0x0403, 0x01010000,
+ 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 180000000, 90000000, 30000000, 0x0403, 0x01000100,
+ 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 200000000, 100000000, 33333333, 0x0303, 0x02010000,
+ 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 211200000, 105600000, 30171428, 0x0902, 0x01000200,
+ 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 220800000, 110400000, 31542857, 0x1500, 0x01000200,
+ 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 230400000, 115200000, 32000000, 0x0604, 0x01000200,
+ 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 234000000, 104000000, 31200000, 0x0b01, 0x01010000,
+ 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 240000000, 120000000, 33333333, 0x0803, 0x01000200,
+ 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 252000000, 126000000, 33333333, 0x0504, 0x01000100,
+ 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 264000000, 132000000, 33000000, 0x0903, 0x01000200,
+ 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 270000000, 120000000, 30000000, 0x0703, 0x01010000,
+ 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 276000000, 122666666, 31542857, 0x1500, 0x01010000,
+ 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 280000000, 140000000, 31111111, 0x0503, 0x01000000,
+ 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 288000000, 128000000, 32914285, 0x0604, 0x01010000,
+ 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 288000000, 144000000, 32000000, 0x0404, 0x01000000,
+ 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 300000000, 133333333, 33333333, 0x0803, 0x01010000,
+ 0x01020600, 0x01010100, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 300000000, 133333333, 37500000, 0x0803, 0x01010000,
+ 0x01020500, 0x01010100, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 300000000, 133333333, 42857142, 0x0803, 0x01010000,
+ 0x01020400, 0x01010100, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 300000000, 133333333, 50000000, 0x0803, 0x01010000,
+ 0x01020300, 0x01010100, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 300000000, 133333333, 60000000, 0x0803, 0x01010000,
+ 0x01020200, 0x01010100, 0x05000100, 8, 0x012a00a9,
+ 9 /* ratio 4/9 */ ,
+ 0x012a00a9}, {
+ 300000000, 150000000, 33333333, 0x0803, 0x01000100,
+ 0x01020600, 0x01010100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 300000000, 150000000, 37500000, 0x0803, 0x01000100,
+ 0x01020500, 0x01010100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 300000000, 150000000, 42857142, 0x0803, 0x01000100,
+ 0x01020400, 0x01010100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 300000000, 150000000, 50000000, 0x0803, 0x01000100,
+ 0x01020300, 0x01010100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 300000000, 150000000, 60000000, 0x0803, 0x01000100,
+ 0x01020200, 0x01010100, 0x05000100, 11, 0x0aaa0555,
+ 8 /* ratio 4/8 */ ,
+ 0x00aa0055}, {
+ 330000000, 132000000, 33000000, 0x0903, 0x01000200,
+ 0x00020200, 0x01010100, 0x05000100, 0, 0,
+ 10 /* ratio 4/10 */ , 0x02520129},
+ {
+ 330000000, 146666666, 33000000, 0x0903, 0x01010000,
+ 0x00020200, 0x01010100, 0x05000100, 0, 0,
+ 9 /* ratio 4/9 */ , 0x012a00a9},
+ {
+ 330000000, 165000000, 33000000, 0x0903, 0x01000100,
+ 0x00020200, 0x01010100, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
+ {
+ 330000000, 165000000, 41250000, 0x0903, 0x01000100,
+ 0x00020100, 0x01010100, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
+ {
+ 330000000, 165000000, 55000000, 0x0903, 0x01000100,
+ 0x00020000, 0x01010100, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
+ {
+ 360000000, 120000000, 32000000, 0x0a03, 0x01000300,
+ 0x00010201, 0x01010200, 0x05000100, 0, 0,
+ 12 /* ratio 4/12 */ , 0x04920492},
+ {
+ 360000000, 144000000, 32000000, 0x0a03, 0x01000200,
+ 0x00010201, 0x01010200, 0x05000100, 0, 0,
+ 10 /* ratio 4/10 */ , 0x02520129},
+ {
+ 360000000, 160000000, 32000000, 0x0a03, 0x01010000,
+ 0x00010201, 0x01010200, 0x05000100, 0, 0,
+ 9 /* ratio 4/9 */ , 0x012a00a9},
+ {
+ 360000000, 180000000, 32000000, 0x0a03, 0x01000100,
+ 0x00010201, 0x01010200, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
+ {
+ 360000000, 180000000, 40000000, 0x0a03, 0x01000100,
+ 0x00010101, 0x01010200, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
+ {
+ 360000000, 180000000, 53333333, 0x0a03, 0x01000100,
+ 0x00010001, 0x01010200, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
+ {
+ 390000000, 130000000, 32500000, 0x0b03, 0x01010100,
+ 0x00020101, 0x01020100, 0x05000100, 0, 0,
+ 12 /* ratio 4/12 */ , 0x04920492},
+ {
+ 390000000, 156000000, 32500000, 0x0b03, 0x01000200,
+ 0x00020101, 0x01020100, 0x05000100, 0, 0,
+ 10 /* ratio 4/10 */ , 0x02520129},
+ {
+ 390000000, 173000000, 32500000, 0x0b03, 0x01010000,
+ 0x00020101, 0x01020100, 0x05000100, 0, 0,
+ 9 /* ratio 4/9 */ , 0x012a00a9},
+ {
+ 390000000, 195000000, 32500000, 0x0b03, 0x01000100,
+ 0x00020101, 0x01020100, 0x05000100, 0, 0,
+ 8 /* ratio 4/8 */ , 0x00aa0055},
};
static n4m_table_t BCMINITDATA(type4_table)[] = {
- { 120000000, 60000000, 0x0009, 0x11020009, 0x01030203, 0x11020009, 0x04000009, 11,
- 0x0aaa0555 },
- { 150000000, 75000000, 0x0009, 0x11050002, 0x01030203, 0x11050002, 0x04000005, 11,
- 0x0aaa0555 },
- { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11,
- 0x0aaa0555 },
- { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11,
- 0x0aaa0555 },
- { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11,
- 0x0aaa0555 },
- { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11,
- 0x0aaa0555 },
- { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8,
- 0x012a00a9 },
- { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13,
- 0x254a14a9 },
- { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11,
- 0x0aaa0555 },
- { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9,
- 0x02520129 },
- { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11,
- 0x0aaa0555 },
- { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11,
- 0x0aaa0555 },
- { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13,
- 0x254a14a9 },
- { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13,
- 0x254a14a9 },
- { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13,
- 0x254a14a9 },
- { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9,
- 0x02520129 },
- { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11,
- 0x0aaa0555 }
+ {
+ 120000000, 60000000, 0, 0x0009, 0x11020009, 0x01030203,
+ 0x11020009, 0x04000009, 11, 0x0aaa0555}, {
+ 150000000, 75000000, 0, 0x0009, 0x11050002, 0x01030203,
+ 0x11050002, 0x04000005, 11, 0x0aaa0555}, {
+ 192000000, 96000000, 0, 0x0702, 0x04000011, 0x11030011,
+ 0x04000011, 0x04000003, 11, 0x0aaa0555}, {
+ 198000000, 99000000, 0, 0x0603, 0x11020005, 0x11030011,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 200000000, 100000000, 0, 0x0009, 0x04020011, 0x11030011,
+ 0x04020011, 0x04020003, 11, 0x0aaa0555}, {
+ 204000000, 102000000, 0, 0x0c02, 0x11020005, 0x01030303,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 208000000, 104000000, 0, 0x0802, 0x11030002, 0x11090005,
+ 0x11030002, 0x04000003, 11, 0x0aaa0555}, {
+ 210000000, 105000000, 0, 0x0209, 0x11020005, 0x01030303,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 216000000, 108000000, 0, 0x0111, 0x11020005, 0x01030303,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 224000000, 112000000, 0, 0x0205, 0x11030002, 0x02002103,
+ 0x11030002, 0x04000003, 11, 0x0aaa0555}, {
+ 228000000, 101333333, 0, 0x0e02, 0x11030003, 0x11210005,
+ 0x01030305, 0x04000005, 8, 0x012a00a9}, {
+ 228000000, 114000000, 0, 0x0e02, 0x11020005, 0x11210005,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 240000000, 102857143, 0, 0x0109, 0x04000021, 0x01050203,
+ 0x11030021, 0x04000003, 13, 0x254a14a9}, {
+ 240000000, 120000000, 0, 0x0109, 0x11030002, 0x01050203,
+ 0x11030002, 0x04000003, 11, 0x0aaa0555}, {
+ 252000000, 100800000, 0, 0x0203, 0x04000009, 0x11050005,
+ 0x02000209, 0x04000002, 9, 0x02520129}, {
+ 252000000, 126000000, 0, 0x0203, 0x04000005, 0x11050005,
+ 0x04000005, 0x04000002, 11, 0x0aaa0555}, {
+ 264000000, 132000000, 0, 0x0602, 0x04000005, 0x11050005,
+ 0x04000005, 0x04000002, 11, 0x0aaa0555}, {
+ 272000000, 116571428, 0, 0x0c02, 0x04000021, 0x02000909,
+ 0x02000221, 0x04000003, 13, 0x254a14a9}, {
+ 280000000, 120000000, 0, 0x0209, 0x04000021, 0x01030303,
+ 0x02000221, 0x04000003, 13, 0x254a14a9}, {
+ 288000000, 123428571, 0, 0x0111, 0x04000021, 0x01030303,
+ 0x02000221, 0x04000003, 13, 0x254a14a9}, {
+ 300000000, 120000000, 0, 0x0009, 0x04000009, 0x01030203,
+ 0x02000902, 0x04000002, 9, 0x02520129}, {
+ 300000000, 150000000, 0, 0x0009, 0x04000005, 0x01030203,
+ 0x04000005, 0x04000002, 11, 0x0aaa0555}
};
static n4m_table_t BCMINITDATA(type7_table)[] = {
- { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11,
- 0x0aaa0555 },
- { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11,
- 0x0aaa0555 },
- { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11,
- 0x0aaa0555 },
- { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11,
- 0x0aaa0555 },
- { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11,
- 0x0aaa0555 },
- { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11,
- 0x0aaa0555 },
- { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11,
- 0x0aaa0555 },
- { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11,
- 0x0aaa0555 },
- { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11,
- 0x0aaa0555 },
- { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11,
- 0x0aaa0555 }
+ {
+ 183333333, 91666666, 0, 0x0605, 0x04000011, 0x11030011,
+ 0x04000011, 0x04000003, 11, 0x0aaa0555}, {
+ 187500000, 93750000, 0, 0x0a03, 0x04000011, 0x11030011,
+ 0x04000011, 0x04000003, 11, 0x0aaa0555}, {
+ 196875000, 98437500, 0, 0x1003, 0x11020005, 0x11050011,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 200000000, 100000000, 0, 0x0311, 0x04000011, 0x11030011,
+ 0x04000009, 0x04000003, 11, 0x0aaa0555}, {
+ 200000000, 100000000, 0, 0x0311, 0x04020011, 0x11030011,
+ 0x04020011, 0x04020003, 11, 0x0aaa0555}, {
+ 206250000, 103125000, 0, 0x1103, 0x11020005, 0x11050011,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 212500000, 106250000, 0, 0x0c05, 0x11020005, 0x01030303,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 215625000, 107812500, 0, 0x1203, 0x11090009, 0x11050005,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 216666666, 108333333, 0, 0x0805, 0x11020003, 0x11030011,
+ 0x11020003, 0x04000003, 11, 0x0aaa0555}, {
+ 225000000, 112500000, 0, 0x0d03, 0x11020003, 0x11030011,
+ 0x11020003, 0x04000003, 11, 0x0aaa0555}, {
+ 233333333, 116666666, 0, 0x0905, 0x11020003, 0x11030011,
+ 0x11020003, 0x04000003, 11, 0x0aaa0555}, {
+ 237500000, 118750000, 0, 0x0e05, 0x11020005, 0x11210005,
+ 0x11020005, 0x04000005, 11, 0x0aaa0555}, {
+ 240000000, 120000000, 0, 0x0b11, 0x11020009, 0x11210009,
+ 0x11020009, 0x04000009, 11, 0x0aaa0555}, {
+ 250000000, 125000000, 0, 0x0f03, 0x11020003, 0x11210003,
+ 0x11020003, 0x04000003, 11, 0x0aaa0555}
};
ulong start, end, dst;
@@ -604,6 +721,7 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
idx = sb_coreidx(sbh);
clockcontrol_m2 = NULL;
+ /* switch to chipc core */
/* switch to extif or chipc core */
if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
pll_type = PLL_TYPE1;
@@ -612,7 +730,15 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
clockcontrol_pci = &eir->clockcontrol_pci;
clockcontrol_m2 = &cc->clockcontrol_m2;
} else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
- pll_type = R_REG(osh, &cc->capabilities) & CAP_PLL_MASK;
+ /* 5354 chipcommon pll setting can't be changed.
+ * The PMU on power up comes up with the default clk frequency
+ * of 240MHz
+ */
+ if (sb_chip(sbh) == BCM5354_CHIP_ID) {
+ ret = TRUE;
+ goto done;
+ }
+ pll_type = R_REG(osh, &cc->capabilities) & CC_CAP_PLL_MASK;
if (pll_type == PLL_TYPE6) {
clockcontrol_n = NULL;
clockcontrol_sb = NULL;
@@ -639,8 +765,9 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
if (pll_type == PLL_TYPE1) {
/* Keep the current PCI clock if not specified */
if (pciclock == 0) {
- pciclock = sb_clock_rate(pll_type, R_REG(osh, clockcontrol_n),
- R_REG(osh, clockcontrol_pci));
+ pciclock =
+ sb_clock_rate(pll_type, R_REG(osh, clockcontrol_n),
+ R_REG(osh, clockcontrol_pci));
pciclock = (pciclock <= 25000000) ? 25000000 : 33000000;
}
@@ -648,7 +775,7 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
for (i = 0; i < ARRAYSIZE(type1_table); i++) {
ASSERT(type1_table[i].mipsclock ==
sb_clock_rate(pll_type, type1_table[i].n,
- type1_table[i].sb));
+ type1_table[i].sb));
if (type1_table[i].mipsclock > mipsclock)
break;
}
@@ -677,7 +804,7 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* Reset */
sb_watchdog(sbh, 1);
- while (1);
+ while (1) ;
} else if (pll_type == PLL_TYPE3) {
/* 5350 */
if (sb_chip(sbh) != BCM5365_CHIP_ID) {
@@ -700,8 +827,8 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* No PLL change */
orig_m2 = R_REG(osh, &cc->clockcontrol_m2);
- if ((orig_n == type3_table[i].n) &&
- (orig_m2 == type3_table[i].m2)) {
+ if ((orig_n == type3_table[i].n)
+ && (orig_m2 == type3_table[i].m2)) {
goto done;
}
@@ -711,12 +838,11 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* Reset */
sb_watchdog(sbh, 1);
- while (1);
+ while (1) ;
}
} else if ((pll_type == PLL_TYPE2) ||
- (pll_type == PLL_TYPE4) ||
- (pll_type == PLL_TYPE6) ||
- (pll_type == PLL_TYPE7)) {
+ (pll_type == PLL_TYPE4) ||
+ (pll_type == PLL_TYPE6) || (pll_type == PLL_TYPE7)) {
n4m_table_t *table = NULL, *te;
uint tabsz = 0;
@@ -725,19 +851,20 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
orig_mips = R_REG(osh, &cc->clockcontrol_m3);
switch (pll_type) {
- case PLL_TYPE6: {
- uint32 new_mips = 0;
+ case PLL_TYPE6:
+ {
+ uint32 new_mips = 0;
- ret = TRUE;
- if (mipsclock <= SB2MIPS_T6(CC_T6_M1))
- new_mips = CC_T6_MMASK;
+ ret = TRUE;
+ if (mipsclock <= SB2MIPS_T6(CC_T6_M1))
+ new_mips = CC_T6_MMASK;
- if (orig_mips == new_mips)
- goto done;
+ if (orig_mips == new_mips)
+ goto done;
- W_REG(osh, &cc->clockcontrol_m3, new_mips);
- goto end_fill;
- }
+ W_REG(osh, &cc->clockcontrol_m3, new_mips);
+ goto end_fill;
+ }
case PLL_TYPE2:
table = type2_table;
tabsz = ARRAYSIZE(type2_table);
@@ -765,8 +892,8 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
if ((orig_n == table[i].n) &&
(orig_sb == table[i].sb) &&
(orig_pci == table[i].pci33) &&
- (orig_m2 == table[i].m2) &&
- (orig_mips == table[i].m3)) {
+ (orig_m2 == table[i].m2)
+ && (orig_mips == table[i].m3)) {
orig_ratio_parm = table[i].ratio_parm;
orig_ratio_cfg = table[i].ratio_cfg;
break;
@@ -776,9 +903,12 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* Search for the closest MIPS clock greater or equal to a preferred value */
for (i = 0; i < tabsz; i++) {
ASSERT(table[i].mipsclock ==
- sb_clock_rate(pll_type, table[i].n, table[i].m3));
- if ((mipsclock <= table[i].mipsclock) &&
- ((sbclock == 0) || (sbclock <= table[i].sbclock)))
+ sb_clock_rate(pll_type, table[i].n,
+ table[i].m3));
+ if ((mipsclock <= table[i].mipsclock)
+ && ((sbclock == 0) || (sbclock <= table[i].sbclock))
+ && ((pciclock == 0)
+ || (pciclock <= table[i].pciclock)))
break;
}
if (i == tabsz) {
@@ -793,8 +923,7 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
if ((orig_n == te->n) &&
(orig_sb == te->sb) &&
(orig_pci == te->pci33) &&
- (orig_m2 == te->m2) &&
- (orig_mips == te->m3))
+ (orig_m2 == te->m2) && (orig_mips == te->m3))
goto done;
/* Set the PLL controls */
@@ -819,38 +948,23 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* Preload the code into the cache */
icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize);
if (sb_chip(sbh) == BCM4785_CHIP_ID) {
- start = ((ulong) &&start_fill_4785) & ~(ic_lsize - 1);
- end = ((ulong) &&end_fill_4785 + (ic_lsize - 1)) & ~(ic_lsize - 1);
- }
- else {
- start = ((ulong) &&start_fill) & ~(ic_lsize - 1);
- end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1);
+ start = ((ulong) && start_fill_4785) & ~(ic_lsize - 1);
+ end = ((ulong)
+ && end_fill_4785 + (ic_lsize - 1)) & ~(ic_lsize -
+ 1);
+ } else {
+ start = ((ulong) && start_fill) & ~(ic_lsize - 1);
+ end = ((ulong)
+ && end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1);
}
while (start < end) {
cache_op(start, Fill_I);
start += ic_lsize;
}
- /* Copy the handler */
- start = (ulong) &handler;
- end = (ulong) &afterhandler;
- dst = KSEG1ADDR(0x180);
- for (i = 0; i < (end - start); i += 4)
- *((ulong *)(dst + i)) = *((ulong *)(start + i));
-
- /* Preload the handler into the cache one line at a time */
- for (i = 0; i < (end - start); i += ic_lsize)
- cache_op(dst + i, Fill_I);
-
- /* Clear BEV bit */
- MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV);
-
- /* Enable interrupts */
- MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE));
-
/* 4785 clock freq change procedures */
if (sb_chip(sbh) == BCM4785_CHIP_ID) {
- start_fill_4785:
+ start_fill_4785:
/* Switch to async */
MTC0(C0_BROADCOM, 4, (1 << 22));
@@ -862,7 +976,8 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
*dll_r1 = *dll_r1 | 0xc0000000;
/* Set active cfg */
- MTC0(C0_BROADCOM, 2, MFC0(C0_BROADCOM, 2) | (1 << 3) | 1);
+ MTC0(C0_BROADCOM, 2,
+ MFC0(C0_BROADCOM, 2) | (1 << 3) | 1);
/* Fake soft reset (clock cfg registers not reset) */
MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | (1 << 2));
@@ -872,33 +987,50 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* set watchdog timer */
W_REG(osh, &cc->watchdog, 20);
- (void) R_REG(osh, &cc->chipid);
+ (void)R_REG(osh, &cc->chipid);
/* wait for timer interrupt */
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- "sync\n\t"
- "wait\n\t"
- ".set\tmips0");
- end_fill_4785:
- while (1);
+ __asm__ __volatile__(".set\tmips3\n\t"
+ "sync\n\t" "wait\n\t"
+ ".set\tmips0");
+ end_fill_4785:
+ while (1) ;
}
/* Generic clock freq change procedures */
else {
+ /* Copy the handler */
+ start = (ulong) & handler;
+ end = (ulong) & afterhandler;
+ dst = KSEG1ADDR(0x180);
+ for (i = 0; i < (end - start); i += 4)
+ *((ulong *) (dst + i)) =
+ *((ulong *) (start + i));
+
+ /* Preload the handler into the cache one line at a time */
+ for (i = 0; i < (end - start); i += ic_lsize)
+ cache_op(dst + i, Fill_I);
+
+ /* Clear BEV bit */
+ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV);
+
+ /* Enable interrupts */
+ MTC0(C0_STATUS, 0,
+ MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE));
+
/* Enable MIPS timer interrupt */
if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) &&
!(mipsr = sb_setcore(sbh, SB_MIPS33, 0)))
ASSERT(mipsr);
W_REG(osh, &mipsr->intmask, 1);
- start_fill:
+ start_fill:
/* step 1, set clock ratios */
MTC0(C0_BROADCOM, 3, te->ratio_parm);
MTC0(C0_BROADCOM, 1, te->ratio_cfg);
/* step 2: program timer intr */
W_REG(osh, &mipsr->timer, 100);
- (void) R_REG(osh, &mipsr->timer);
+ (void)R_REG(osh, &mipsr->timer);
/* step 3, switch to async */
sync_mode = MFC0(C0_BROADCOM, 4);
@@ -908,10 +1040,8 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
MTC0(C0_BROADCOM, 2, (1 << 3) | 1);
/* steps 5 & 6 */
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- "wait\n\t"
- ".set\tmips0");
+ __asm__ __volatile__(".set\tmips3\n\t" "wait\n\t"
+ ".set\tmips0");
/* step 7, clear cfg active */
MTC0(C0_BROADCOM, 2, 0);
@@ -922,22 +1052,20 @@ BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32
/* step 8, fake soft reset */
MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | (1 << 2));
- end_fill:
+ end_fill:
/* set watchdog timer */
W_REG(osh, &cc->watchdog, 20);
- (void) R_REG(osh, &cc->chipid);
+ (void)R_REG(osh, &cc->chipid);
/* wait for timer interrupt */
- __asm__ __volatile__(
- ".set\tmips3\n\t"
- "sync\n\t"
- "wait\n\t"
- ".set\tmips0");
- while (1);
+ __asm__ __volatile__(".set\tmips3\n\t"
+ "sync\n\t" "wait\n\t"
+ ".set\tmips0");
+ while (1) ;
}
}
-done:
+ done:
/* Enable 4785 DLL */
if (sb_chip(sbh) == BCM4785_CHIP_ID) {
uint32 tmp;
@@ -949,7 +1077,7 @@ done:
*dll_ctrl |= 0x00000080;
/* wait for lock flag to clear */
- while ((*dll_ctrl & 0x2) == 0);
+ while ((*dll_ctrl & 0x2) == 0) ;
/* clear sticky flags (clear on write 1) */
tmp = *dll_ctrl;
@@ -969,9 +1097,7 @@ done:
return ret;
}
-void
-BCMINITFN(enable_pfc)(uint32 mode)
-{
+void BCMINITFN(enable_pfc) (uint32 mode) {
ulong start, end;
uint ic_size, ic_lsize;
@@ -985,8 +1111,9 @@ BCMINITFN(enable_pfc)(uint32 mode)
/* enable prefetch cache if available */
if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) {
- start = ((ulong) &&setpfc_start) & ~(ic_lsize - 1);
- end = ((ulong) &&setpfc_end + (ic_lsize - 1)) & ~(ic_lsize - 1);
+ start = ((ulong) && setpfc_start) & ~(ic_lsize - 1);
+ end = ((ulong)
+ && setpfc_end + (ic_lsize - 1)) & ~(ic_lsize - 1);
/* Preload setpfc code into the cache one line at a time */
while (start < end) {
@@ -995,22 +1122,20 @@ BCMINITFN(enable_pfc)(uint32 mode)
}
/* Now set the pfc */
- setpfc_start:
+ setpfc_start:
/* write range */
*(volatile uint32 *)PFC_CR1 = 0xffff0000;
/* enable */
*(volatile uint32 *)PFC_CR0 = mode;
- setpfc_end:
+ setpfc_end:
/* Compiler foder */
ic_size = 0;
}
}
/* returns the ncdl value to be programmed into sdram_ncdl for calibration */
-uint32
-BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh)
-{
+uint32 BCMINITFN(sb_memc_get_ncdl) (sb_t * sbh) {
osl_t *osh;
sbmemcregs_t *memc;
uint32 ret = 0;
@@ -1021,7 +1146,7 @@ BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh)
idx = sb_coreidx(sbh);
- memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0);
+ memc = (sbmemcregs_t *) sb_setcore(sbh, SB_MEMC, 0);
if (memc == 0)
goto out;
@@ -1043,19 +1168,33 @@ BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh)
if (rev > 0)
cd = rd;
else
- cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD);
+ cd = (rd ==
+ MEMC_CD_THRESHOLD) ? rd : (wr +
+ MEMC_CD_THRESHOLD);
sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT;
sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT;
ret = (sm << 16) | (sd << 8) | cd;
}
-out:
+ out:
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
return ret;
}
+void hnd_cpu_reset(sb_t * sbh)
+{
+ if (sb_chip(sbh) == BCM4785_CHIP_ID)
+ MTC0(C0_BROADCOM, 4, (1 << 22));
+ sb_watchdog(sbh, 1);
+ if (sb_chip(sbh) == BCM4785_CHIP_ID) {
+ __asm__ __volatile__(".set\tmips3\n\t"
+ "sync\n\t" "wait\n\t" ".set\tmips0");
+ }
+ while (1) ;
+}
+
#if defined(BCMPERFSTATS)
/*
* CP0 Register 25 supports 4 semi-independent 32bit performance counters.
@@ -1065,68 +1204,64 @@ out:
*/
/* enable and start instruction counting */
-void
-hndmips_perf_instrcount_enable()
+void hndmips_perf_cyclecount_enable(void)
{
MTC0(C0_PERFORMANCE, 6, 0x80000200); /* global enable perf counters */
- MTC0(C0_PERFORMANCE, 4,
- 0x8044 | MFC0(C0_PERFORMANCE, 4)); /* enable instruction counting for counter 0 */
- MTC0(C0_PERFORMANCE, 0, 0); /* zero counter zero */
+ MTC0(C0_PERFORMANCE, 4, 0x8048 | MFC0(C0_PERFORMANCE, 4)); /* enable cycles counting for counter 0 */
+ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter zero */
+}
+
+void hndmips_perf_instrcount_enable(void)
+{
+ MTC0(C0_PERFORMANCE, 6, 0x80000200); /* global enable perf counters */
+ MTC0(C0_PERFORMANCE, 4, 0x8044 | MFC0(C0_PERFORMANCE, 4)); /* enable instructions counting for counter 0 */
+ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter zero */
}
/* enable and start I$ hit and I$ miss counting */
-void
-hndmips_perf_icachecount_enable(void)
+void hndmips_perf_icachecount_enable(void)
{
MTC0(C0_PERFORMANCE, 6, 0x80000218); /* enable I$ counting */
MTC0(C0_PERFORMANCE, 4, 0x80148018); /* count I$ hits in cntr 0 and misses in cntr 1 */
- MTC0(C0_PERFORMANCE, 0, 0); /* zero counter 0 - # I$ hits */
- MTC0(C0_PERFORMANCE, 1, 0); /* zero counter 1 - # I$ misses */
+ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter 0 - # I$ hits */
+ MTC0(C0_PERFORMANCE, 1, 0); /* zero counter 1 - # I$ misses */
}
/* enable and start D$ hit and I$ miss counting */
-void
-hndmips_perf_dcachecount_enable(void)
+void hndmips_perf_dcachecount_enable(void)
{
MTC0(C0_PERFORMANCE, 6, 0x80000211); /* enable D$ counting */
MTC0(C0_PERFORMANCE, 4, 0x80248028); /* count D$ hits in cntr 0 and misses in cntr 1 */
- MTC0(C0_PERFORMANCE, 0, 0); /* zero counter 0 - # D$ hits */
- MTC0(C0_PERFORMANCE, 1, 0); /* zero counter 1 - # D$ misses */
+ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter 0 - # D$ hits */
+ MTC0(C0_PERFORMANCE, 1, 0); /* zero counter 1 - # D$ misses */
}
-void
-hndmips_perf_icache_miss_enable()
+void hndmips_perf_icache_miss_enable()
{
- MTC0(C0_PERFORMANCE, 4,
- 0x80140000 | MFC0(C0_PERFORMANCE, 4)); /* enable cache misses counting for counter 1 */
- MTC0(C0_PERFORMANCE, 1, 0); /* zero counter one */
+ MTC0(C0_PERFORMANCE, 4, 0x80140000 | MFC0(C0_PERFORMANCE, 4)); /* enable cache misses counting for counter 1 */
+ MTC0(C0_PERFORMANCE, 1, 0); /* zero counter one */
}
-
-void
-hndmips_perf_icache_hit_enable()
+void hndmips_perf_icache_hit_enable()
{
MTC0(C0_PERFORMANCE, 5, 0x8018 | MFC0(C0_PERFORMANCE, 5));
/* enable cache hits counting for counter 2 */
- MTC0(C0_PERFORMANCE, 2, 0); /* zero counter 2 */
+ MTC0(C0_PERFORMANCE, 2, 0); /* zero counter 2 */
}
-uint32
-hndmips_perf_read_instrcount()
+uint32 hndmips_perf_read_instrcount()
{
return -(long)(MFC0(C0_PERFORMANCE, 0));
}
-uint32
-hndmips_perf_read_cache_miss()
+uint32 hndmips_perf_read_cache_miss()
{
return -(long)(MFC0(C0_PERFORMANCE, 1));
}
-uint32
-hndmips_perf_read_cache_hit()
+uint32 hndmips_perf_read_cache_hit()
{
return -(long)(MFC0(C0_PERFORMANCE, 2));
}
-#endif /* BCMINTERNAL | BCMPERFSTATS */
+#endif
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c
index 2738efaa88..f841ad119d 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c
@@ -17,7 +17,6 @@
#include <pcicfg.h>
#include <bcmdevs.h>
#include <sbconfig.h>
-#include <bcmutils.h>
#include <sbutils.h>
#include <sbpci.h>
#include <bcmendian.h>
@@ -31,7 +30,7 @@
#define PCI_MSG(args) printf args
#else
#define PCI_MSG(args)
-#endif /* BCMDBG_PCI */
+#endif /* BCMDBG_PCI */
/* Can free sbpci_init() memory after boot */
#ifndef linux
@@ -40,11 +39,11 @@
/* Emulated configuration space */
typedef struct {
- int n;
- uint size0;
- uint size1;
- uint size2;
- uint size3;
+ int n;
+ uint size0;
+ uint size1;
+ uint size2;
+ uint size3;
} sb_bar_cfg_t;
static pci_config_regs sb_config_regs[SB_MAXCORES];
static sb_bar_cfg_t sb_bar_cfg[SB_MAXCORES];
@@ -86,10 +85,9 @@ static uint8 pci_hbslot = 0;
*/
/* Assume one-hot slot wiring */
-#define PCI_SLOT_MAX 16 /* Max. PCI Slots */
+#define PCI_SLOT_MAX 16 /* Max. PCI Slots */
-static uint32
-config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
+static uint32 config_cmd(sb_t * sbh, uint bus, uint dev, uint func, uint off)
{
uint coreidx;
sbpciregs_t *regs;
@@ -112,21 +110,21 @@ config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
uint32 win;
/* Slide the PCI window to the appropriate slot */
- win = (SBTOPCI_CFG0 | ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
+ win =
+ (SBTOPCI_CFG0 |
+ ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
W_REG(osh, &regs->sbtopci1, win);
addr = SB_PCI_CFG |
- ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
- (func << PCICFG_FUN_SHIFT) |
- (off & ~3);
+ ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
+ (func << PCICFG_FUN_SHIFT) | (off & ~3);
}
} else {
/* Type 1 transaction */
W_REG(osh, &regs->sbtopci1, SBTOPCI_CFG1);
addr = SB_PCI_CFG |
- (bus << PCICFG_BUS_SHIFT) |
- (dev << PCICFG_SLOT_SHIFT) |
- (func << PCICFG_FUN_SHIFT) |
- (off & ~3);
+ (bus << PCICFG_BUS_SHIFT) |
+ (dev << PCICFG_SLOT_SHIFT) |
+ (func << PCICFG_FUN_SHIFT) | (off & ~3);
}
sb_setcoreidx(sbh, coreidx);
@@ -145,8 +143,8 @@ config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
* the register address where value in 'val' is read.
*/
static bool
-sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off,
- uint32 **addr, uint32 *val)
+sb_pcihb_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off,
+ uint32 ** addr, uint32 * val)
{
sbpciregs_t *regs;
osl_t *osh;
@@ -162,9 +160,9 @@ sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off,
/* read pci config when core rev >= 8 */
coreidx = sb_coreidx(sbh);
- regs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
+ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
if (regs && sb_corerev(sbh) >= PCI_HBSBCFG_REV) {
- *addr = (uint32 *)&regs->pcicfg[func][off >> 2];
+ *addr = (uint32 *) & regs->pcicfg[func][off >> 2];
*val = R_REG(osh, *addr);
ret = TRUE;
}
@@ -174,30 +172,30 @@ sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off,
}
int
-extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
+extpci_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off,
+ void *buf, int len)
{
uint32 addr = 0, *reg = NULL, val;
int ret = 0;
/*
* Set value to -1 when:
- * flag 'pci_disabled' is true;
- * value of 'addr' is zero;
- * REG_MAP() fails;
- * BUSPROBE() fails;
+ * flag 'pci_disabled' is true;
+ * value of 'addr' is zero;
+ * REG_MAP() fails;
+ * BUSPROBE() fails;
*/
if (pci_disabled)
val = 0xffffffff;
else if (bus == 1 && dev == pci_hbslot && func == 0 &&
- sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
- ;
+ sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val)) ;
else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
- ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
- (BUSPROBE(val, reg) != 0))
+ ((reg = (uint32 *) REG_MAP(addr, len)) == 0) ||
+ (BUSPROBE(val, reg) != 0))
val = 0xffffffff;
PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
- __FUNCTION__, val, reg, addr, len, off, buf));
+ __FUNCTION__, val, reg, addr, len, off, buf));
val >>= 8 * (off & 3);
if (len == 4)
@@ -216,7 +214,8 @@ extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf
}
int
-extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
+extpci_write_config(sb_t * sbh, uint bus, uint dev, uint func, uint off,
+ void *buf, int len)
{
osl_t *osh;
uint32 addr = 0, *reg = NULL, val;
@@ -226,19 +225,18 @@ extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *bu
/*
* Ignore write attempt when:
- * flag 'pci_disabled' is true;
- * value of 'addr' is zero;
- * REG_MAP() fails;
- * BUSPROBE() fails;
+ * flag 'pci_disabled' is true;
+ * value of 'addr' is zero;
+ * REG_MAP() fails;
+ * BUSPROBE() fails;
*/
if (pci_disabled)
return 0;
else if (bus == 1 && dev == pci_hbslot && func == 0 &&
- sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
- ;
+ sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val)) ;
else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
- ((reg = (uint32 *) REG_MAP(addr, len)) == 0) ||
- (BUSPROBE(val, reg) != 0))
+ ((reg = (uint32 *) REG_MAP(addr, len)) == 0) ||
+ (BUSPROBE(val, reg) != 0))
goto done;
if (len == 4)
@@ -258,7 +256,7 @@ extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *bu
W_REG(osh, reg, val);
-done:
+ done:
if (reg && addr)
REG_UNMAP(reg);
@@ -287,8 +285,8 @@ done:
/* Sync the emulation registers and the real PCI config registers. */
static void
-sb_pcid_read_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
- uint off, uint len)
+sb_pcid_read_config(sb_t * sbh, uint coreidx, sb_pci_cfg_t * cfg,
+ uint off, uint len)
{
osl_t *osh;
uint oldidx;
@@ -308,21 +306,23 @@ sb_pcid_read_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
sb_setcoreidx(sbh, coreidx);
if (sb_iscoreup(sbh)) {
if (len == 4)
- *(uint32 *)((ulong)cfg->emu + off) =
- htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off)));
+ *(uint32 *) ((ulong) cfg->emu + off) =
+ htol32(R_REG
+ (osh, (uint32 *) ((ulong) cfg->pci + off)));
else if (len == 2)
- *(uint16 *)((ulong)cfg->emu + off) =
- htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off)));
+ *(uint16 *) ((ulong) cfg->emu + off) =
+ htol16(R_REG
+ (osh, (uint16 *) ((ulong) cfg->pci + off)));
else if (len == 1)
- *(uint8 *)((ulong)cfg->emu + off) =
- R_REG(osh, (uint8 *)((ulong)cfg->pci + off));
+ *(uint8 *) ((ulong) cfg->emu + off) =
+ R_REG(osh, (uint8 *) ((ulong) cfg->pci + off));
}
sb_setcoreidx(sbh, oldidx);
}
static void
-sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
- uint off, uint len)
+sb_pcid_write_config(sb_t * sbh, uint coreidx, sb_pci_cfg_t * cfg,
+ uint off, uint len)
{
osl_t *osh;
uint oldidx;
@@ -342,14 +342,14 @@ sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
sb_setcoreidx(sbh, coreidx);
if (sb_iscoreup(sbh)) {
if (len == 4)
- W_REG(osh, (uint32 *)((ulong)cfg->pci + off),
- ltoh32(*(uint32 *)((ulong)cfg->emu + off)));
+ W_REG(osh, (uint32 *) ((ulong) cfg->pci + off),
+ ltoh32(*(uint32 *) ((ulong) cfg->emu + off)));
else if (len == 2)
- W_REG(osh, (uint16 *)((ulong)cfg->pci + off),
- ltoh16(*(uint16 *)((ulong)cfg->emu + off)));
+ W_REG(osh, (uint16 *) ((ulong) cfg->pci + off),
+ ltoh16(*(uint16 *) ((ulong) cfg->emu + off)));
else if (len == 1)
- W_REG(osh, (uint8 *)((ulong)cfg->pci + off),
- *(uint8 *)((ulong)cfg->emu + off));
+ W_REG(osh, (uint8 *) ((ulong) cfg->pci + off),
+ *(uint8 *) ((ulong) cfg->emu + off));
}
sb_setcoreidx(sbh, oldidx);
}
@@ -358,16 +358,18 @@ sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
* Functions for accessing translated SB configuration space
*/
static int
-sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
+sb_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, void *buf,
+ int len)
{
pci_config_regs *cfg;
- if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
+ if (dev >= SB_MAXCORES || func >= MAXFUNCS
+ || (off + len) > sizeof(pci_config_regs))
return -1;
cfg = sb_pci_cfg[dev][func].emu;
ASSERT(ISALIGNED(off, len));
- ASSERT(ISALIGNED((uintptr)buf, len));
+ ASSERT(ISALIGNED((uintptr) buf, len));
/* use special config space if the device does not exist */
if (!cfg)
@@ -377,11 +379,11 @@ sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, in
sb_pcid_read_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
if (len == 4)
- *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
+ *((uint32 *) buf) = ltoh32(*((uint32 *) ((ulong) cfg + off)));
else if (len == 2)
- *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
+ *((uint16 *) buf) = ltoh16(*((uint16 *) ((ulong) cfg + off)));
else if (len == 1)
- *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off));
+ *((uint8 *) buf) = *((uint8 *) ((ulong) cfg + off));
else
return -1;
@@ -389,7 +391,8 @@ sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, in
}
static int
-sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
+sb_write_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, void *buf,
+ int len)
{
uint coreidx;
void *regs;
@@ -397,14 +400,15 @@ sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, i
osl_t *osh;
sb_bar_cfg_t *bar;
- if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
+ if (dev >= SB_MAXCORES || func >= MAXFUNCS
+ || (off + len) > sizeof(pci_config_regs))
return -1;
cfg = sb_pci_cfg[dev][func].emu;
if (!cfg)
return -1;
ASSERT(ISALIGNED(off, len));
- ASSERT(ISALIGNED((uintptr)buf, len));
+ ASSERT(ISALIGNED((uintptr) buf, len));
osh = sb_osh(sbh);
@@ -418,33 +422,37 @@ sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, i
/* Highest numbered address match register */
if (off == OFFSETOF(pci_config_regs, base[0]))
cfg->base[0] = ~(bar->size0 - 1);
- else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1)
+ else if (off == OFFSETOF(pci_config_regs, base[1])
+ && bar->n >= 1)
cfg->base[1] = ~(bar->size1 - 1);
- else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2)
+ else if (off == OFFSETOF(pci_config_regs, base[2])
+ && bar->n >= 2)
cfg->base[2] = ~(bar->size2 - 1);
- else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3)
+ else if (off == OFFSETOF(pci_config_regs, base[3])
+ && bar->n >= 3)
cfg->base[3] = ~(bar->size3 - 1);
}
sb_setcoreidx(sbh, coreidx);
- }
- else if (len == 4)
- *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf));
+ } else if (len == 4)
+ *((uint32 *) ((ulong) cfg + off)) = htol32(*((uint32 *) buf));
else if (len == 2)
- *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf));
+ *((uint16 *) ((ulong) cfg + off)) = htol16(*((uint16 *) buf));
else if (len == 1)
- *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf);
+ *((uint8 *) ((ulong) cfg + off)) = *((uint8 *) buf);
else
return -1;
/* sync emulation with real PCI config if necessary */
if (sb_pci_cfg[dev][func].pci)
- sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
+ sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off,
+ len);
return 0;
}
int
-sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
+sbpci_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off,
+ void *buf, int len)
{
if (bus == 0)
return sb_read_config(sbh, bus, dev, func, off, buf, len);
@@ -453,7 +461,8 @@ sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf,
}
int
-sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
+sbpci_write_config(sb_t * sbh, uint bus, uint dev, uint func, uint off,
+ void *buf, int len)
{
if (bus == 0)
return sb_write_config(sbh, bus, dev, func, off, buf, len);
@@ -461,8 +470,7 @@ sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf
return extpci_write_config(sbh, bus, dev, func, off, buf, len);
}
-void
-sbpci_ban(uint16 core)
+void sbpci_ban(uint16 core)
{
if (pci_banned < ARRAYSIZE(pci_ban))
pci_ban[pci_banned++] = core;
@@ -473,8 +481,7 @@ sbpci_ban(uint16 core)
* Otherwise return -1 to indicate there is no PCI core and return 1
* to indicate PCI core is disabled.
*/
-int __init
-sbpci_init_pci(sb_t *sbh)
+int __init sbpci_init_pci(sb_t * sbh)
{
uint chip, chiprev, chippkg, host;
uint32 boardflags;
@@ -499,8 +506,8 @@ sbpci_init_pci(sb_t *sbh)
if ((chip == 0x4310) && (chiprev == 0))
pci_disabled = TRUE;
-
- sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
+
+ sb = (sbconfig_t *) ((ulong) pci + SBCONFIGOFF);
boardflags = (uint32) getintvar(NULL, "boardflags");
@@ -511,8 +518,7 @@ sbpci_init_pci(sb_t *sbh)
*/
if (((chip == BCM4712_CHIP_ID) &&
((chippkg == BCM4712SMALL_PKG_ID) ||
- (chippkg == BCM4712MID_PKG_ID))) ||
- (boardflags & BFL_NOPCI))
+ (chippkg == BCM4712MID_PKG_ID))) || (boardflags & BFL_NOPCI))
pci_disabled = TRUE;
/* Enable the core */
@@ -550,13 +556,13 @@ sbpci_init_pci(sb_t *sbh)
}
/* Reset the external PCI bus and enable the clock */
- W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */
- W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */
- OSL_DELAY(150); /* delay > 100 us */
- W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */
+ W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */
+ W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */
+ OSL_DELAY(150); /* delay > 100 us */
+ W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */
/* Use internal arbiter and park REQ/GRNT at external master 0 */
W_REG(osh, &pci->arbcontrol, PCI_INT_ARB);
- OSL_DELAY(1); /* delay 1 us */
+ OSL_DELAY(1); /* delay 1 us */
if (sb_corerev(sbh) >= 8) {
val = getintvar(NULL, "parkid");
ASSERT(val <= PCI_PARKID_LAST);
@@ -571,7 +577,8 @@ sbpci_init_pci(sb_t *sbh)
/* GPIO 1 resets the CardBus device on bcm94710ap */
sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY);
sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY);
- W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400);
+ W_REG(osh, &pci->sprom[0],
+ R_REG(osh, &pci->sprom[0]) | 0x400);
}
/* 64 MB I/O access window */
@@ -583,13 +590,14 @@ sbpci_init_pci(sb_t *sbh)
/* Host bridge slot # nvram overwrite */
if ((hbslot = nvram_get("pcihbslot"))) {
- pci_hbslot = bcm_strtoul(hbslot, NULL, 0);
+ pci_hbslot = simple_strtoul(hbslot, NULL, 0);
ASSERT(pci_hbslot < PCI_MAX_DEVICES);
}
/* Enable PCI bridge BAR0 prefetch and burst */
val = 6;
- sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val));
+ sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val,
+ sizeof(val));
/* Enable PCI interrupts */
W_REG(osh, &pci->intmask, PCI_INTA);
@@ -602,7 +610,8 @@ sbpci_init_pci(sb_t *sbh)
* Get the PCI region address and size information.
*/
static void __init
-sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar)
+sbpci_init_regions(sb_t * sbh, uint func, pci_config_regs * cfg,
+ sb_bar_cfg_t * bar)
{
osl_t *osh;
uint16 coreid;
@@ -610,26 +619,26 @@ sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar
sbconfig_t *sb;
uint32 base;
- osh = sb_osh(sbh);
- coreid = sb_coreid(sbh);
- regs = sb_coreregs(sbh);
- sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
+ osh = sb_osh(sbh);
+ coreid = sb_coreid(sbh);
+ regs = sb_coreregs(sbh);
+ sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF);
switch (coreid) {
case SB_USB20H:
base = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
- cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */
+ cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */
cfg->base[1] = 0;
cfg->base[2] = 0;
cfg->base[3] = 0;
cfg->base[4] = 0;
cfg->base[5] = 0;
- bar->n = 1;
- bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */
- bar->size1 = 0;
- bar->size2 = 0;
- bar->size3 = 0;
+ bar->n = 1;
+ bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */
+ bar->size1 = 0;
+ bar->size2 = 0;
+ bar->size3 = 0;
break;
default:
cfg->base[0] = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
@@ -638,11 +647,13 @@ sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar
cfg->base[3] = htol32(sb_base(R_REG(osh, &sb->sbadmatch3)));
cfg->base[4] = 0;
cfg->base[5] = 0;
- bar->n = (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
- bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0));
- bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1));
- bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2));
- bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3));
+ bar->n =
+ (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >>
+ SBIDL_AR_SHIFT;
+ bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0));
+ bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1));
+ bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2));
+ bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3));
break;
}
}
@@ -651,8 +662,7 @@ sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar
* Construct PCI config spaces for SB cores so that they
* can be accessed as if they were PCI devices.
*/
-static void __init
-sbpci_init_cores(sb_t *sbh)
+static void __init sbpci_init_cores(sb_t * sbh)
{
uint chiprev, coreidx, i;
sbconfig_t *sb;
@@ -679,11 +689,11 @@ sbpci_init_cores(sb_t *sbh)
memset(&sb_pci_null, -1, sizeof(sb_pci_null));
cfg = sb_config_regs;
bar = sb_bar_cfg;
- for (dev = 0; dev < SB_MAXCORES; dev ++) {
+ for (dev = 0; dev < SB_MAXCORES; dev++) {
/* Check if the core exists */
if (!(regs = sb_setcoreidx(sbh, dev)))
continue;
- sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
+ sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF);
/* Check if this core is banned */
coreid = sb_coreid(sbh);
@@ -701,8 +711,9 @@ sbpci_init_cores(sb_t *sbh)
}
/* Convert core id to pci id */
- if (sb_corepciid(sbh, func, &vendor, &device, &class, &subclass,
- &progif, &header))
+ if (sb_corepciid
+ (sbh, func, &vendor, &device, &class, &subclass,
+ &progif, &header))
continue;
/*
@@ -712,13 +723,16 @@ sbpci_init_cores(sb_t *sbh)
*/
switch (device) {
case BCM47XX_GIGETH_ID:
- pci = (pci_config_regs *)((uint32)regs + 0x800);
+ pci =
+ (pci_config_regs *) ((uint32) regs + 0x800);
break;
case BCM47XX_SATAXOR_ID:
- pci = (pci_config_regs *)((uint32)regs + 0x400);
+ pci =
+ (pci_config_regs *) ((uint32) regs + 0x400);
break;
case BCM47XX_ATA100_ID:
- pci = (pci_config_regs *)((uint32)regs + 0x800);
+ pci =
+ (pci_config_regs *) ((uint32) regs + 0x800);
break;
default:
pci = NULL;
@@ -734,22 +748,23 @@ sbpci_init_cores(sb_t *sbh)
cfg->header_type = header;
sbpci_init_regions(sbh, func, cfg, bar);
/* Save core interrupt flag */
- cfg->int_pin = R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
+ cfg->int_pin =
+ R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
/* Save core interrupt assignment */
cfg->int_line = sb_irq(sbh);
/* Indicate there is no SROM */
- *((uint32 *) &cfg->sprom_control) = 0xffffffff;
+ *((uint32 *) & cfg->sprom_control) = 0xffffffff;
/* Point to the PCI config spaces */
sb_pci_cfg[dev][func].emu = cfg;
sb_pci_cfg[dev][func].pci = pci;
sb_pci_cfg[dev][func].bar = bar;
- cfg ++;
- bar ++;
+ cfg++;
+ bar++;
}
}
-done:
+ done:
sb_setcoreidx(sbh, coreidx);
}
@@ -758,11 +773,9 @@ done:
* Must propagate sbpci_init_pci() return value to the caller to let
* them know the PCI core initialization status.
*/
-int __init
-sbpci_init(sb_t *sbh)
+int __init sbpci_init(sb_t * sbh)
{
int status = sbpci_init_pci(sbh);
sbpci_init_cores(sbh);
return status;
}
-
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbutils.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbutils.c
index 672e027d88..244a1324f6 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbutils.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbutils.c
@@ -2,87 +2,123 @@
* Misc utility routines for accessing chip-specific features
* of the SiliconBackplane-based Broadcom chips.
*
- * Copyright 2006, Broadcom Corporation
+ * Copyright 2007, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- * $Id: sbutils.c,v 1.10 2006/04/08 07:12:42 honor Exp $
+ * $Id$
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
-#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
#include <sbconfig.h>
#include <sbchipc.h>
+#include <sbextif.h>
#include <sbpci.h>
#include <sbpcie.h>
#include <pcicfg.h>
#include <sbpcmcia.h>
-#include <sbextif.h>
#include <sbsocram.h>
+#include <bcmnvram.h>
#include <bcmsrom.h>
-#ifdef __mips__
-#include <mipsinc.h>
-#endif /* __mips__ */
+#include <hndpmu.h>
/* debug/trace */
#define SB_ERROR(args)
-typedef uint32 (*sb_intrsoff_t)(void *intr_arg);
-typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg);
-typedef bool (*sb_intrsenabled_t)(void *intr_arg);
+#ifdef BCMDBG
+#define SB_MSG(args) printf args
+#else
+#define SB_MSG(args)
+#endif /* BCMDBG */
+
+typedef uint32(*sb_intrsoff_t) (void *intr_arg);
+typedef void (*sb_intrsrestore_t) (void *intr_arg, uint32 arg);
+typedef bool(*sb_intrsenabled_t) (void *intr_arg);
+
+typedef struct gpioh_item {
+ void *arg;
+ bool level;
+ gpio_handler_t handler;
+ uint32 event;
+ struct gpioh_item *next;
+} gpioh_item_t;
/* misc sb info needed by some of the routines */
typedef struct sb_info {
- struct sb_pub sb; /* back plane public state (must be first field) */
+ struct sb_pub sb; /* back plane public state (must be first field) */
+
+ void *osh; /* osl os handle */
+ void *sdh; /* bcmsdh handle */
+
+ void *curmap; /* current regs va */
+ void *regs[SB_MAXCORES]; /* other regs va */
- void *osh; /* osl os handle */
- void *sdh; /* bcmsdh handle */
+ uint curidx; /* current core index */
+ uint dev_coreid; /* the core provides driver functions */
- void *curmap; /* current regs va */
- void *regs[SB_MAXCORES]; /* other regs va */
+ bool memseg; /* flag to toggle MEM_SEG register */
- uint curidx; /* current core index */
- uint dev_coreid; /* the core provides driver functions */
+ uint gpioidx; /* gpio control core index */
+ uint gpioid; /* gpio control coretype */
- bool memseg; /* flag to toggle MEM_SEG register */
+ uint numcores; /* # discovered cores */
+ uint coreid[SB_MAXCORES]; /* id of each core */
- uint gpioidx; /* gpio control core index */
- uint gpioid; /* gpio control coretype */
+ void *intr_arg; /* interrupt callback function arg */
+ sb_intrsoff_t intrsoff_fn; /* turns chip interrupts off */
+ sb_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
+ sb_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
- uint numcores; /* # discovered cores */
- uint coreid[SB_MAXCORES]; /* id of each core */
+ uint8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */
+ bool pr42767_war;
+ uint8 pcie_polarity;
+ bool pcie_war_ovr; /* Override ASPM/Clkreq settings */
- void *intr_arg; /* interrupt callback function arg */
- sb_intrsoff_t intrsoff_fn; /* turns chip interrupts off */
- sb_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
- sb_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
+ uint8 pmecap_offset; /* PM Capability offset in the config space */
+ bool pmecap; /* Capable of generating PME */
+ gpioh_item_t *gpioh_head; /* GPIO event handlers list */
+
+ char *vars;
+ uint varsz;
} sb_info_t;
/* local prototypes */
-static sb_info_t * sb_doattach(sb_info_t *si, uint devid, osl_t *osh, void *regs,
- uint bustype, void *sdh, char **vars, uint *varsz);
-static void sb_scan(sb_info_t *si);
-static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val);
-static uint _sb_coreidx(sb_info_t *si);
-static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit);
+static sb_info_t *sb_doattach(sb_info_t * si, uint devid, osl_t * osh,
+ void *regs, uint bustype, void *sdh,
+ char **vars, uint * varsz);
+static void sb_scan(sb_info_t * si);
+static uint _sb_coreidx(sb_info_t * si);
static uint sb_pcidev2chip(uint pcidev);
static uint sb_chip2numcores(uint chip);
-static bool sb_ispcie(sb_info_t *si);
-static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen);
-static int sb_pci_fixcfg(sb_info_t *si);
-
+static bool sb_ispcie(sb_info_t * si);
+static uint8 sb_find_pci_capability(sb_info_t * si, uint8 req_cap_id,
+ uchar * buf, uint32 * buflen);
+static int sb_pci_fixcfg(sb_info_t * si);
/* routines to access mdio slave device registers */
-static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val);
-static void sb_war30841(sb_info_t *si);
+static int sb_pcie_mdiowrite(sb_info_t * si, uint physmedia, uint readdr,
+ uint val);
+static int sb_pcie_mdioread(sb_info_t * si, uint physmedia, uint readdr,
+ uint * ret_val);
+
+/* dev path concatenation util */
+static char *sb_devpathvar(sb_t * sbh, char *var, int len, const char *name);
+
+/* WARs */
+static void sb_war43448(sb_t * sbh);
+static void sb_war43448_aspm(sb_t * sbh);
+static void sb_war32414_forceHT(sb_t * sbh, bool forceHT);
+static void sb_war30841(sb_info_t * si);
+static void sb_war42767(sb_t * sbh);
+static void sb_war42767_clkreq(sb_t * sbh);
/* delay needed between the mdio control/ mdiodata register data access */
#define PR28829_DELAY() OSL_DELAY(10)
@@ -93,19 +129,24 @@ static void sb_war30841(sb_info_t *si);
/* global variable to indicate reservation/release of gpio's */
static uint32 sb_gpioreservation = 0;
-#define SB_INFO(sbh) (sb_info_t*)sbh
+/* global flag to prevent shared resources from being initialized multiple times in sb_attach() */
+static bool sb_onetimeinit = FALSE;
+
+#define SB_INFO(sbh) (sb_info_t*)(uintptr)sbh
#define SET_SBREG(si, r, mask, val) \
W_SBREG((si), (r), ((R_SBREG((si), (r)) & ~(mask)) | (val)))
-#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && \
+#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && \
ISALIGNED((x), SB_CORE_SIZE))
#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE))
#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF)
+#define BADCOREADDR 0
#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES)
#define BADIDX (SB_MAXCORES+1)
-#define NOREV -1 /* Invalid rev */
+#define NOREV -1 /* Invalid rev */
#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI))
#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE))
+#define PCMCIA(si) ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->memseg == TRUE))
/* sonicsrev */
#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
@@ -128,54 +169,51 @@ static uint32 sb_gpioreservation = 0;
(*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
/* dynamic clock control defines */
-#define LPOMINFREQ 25000 /* low power oscillator min */
-#define LPOMAXFREQ 43000 /* low power oscillator max */
+#define LPOMINFREQ 25000 /* low power oscillator min */
+#define LPOMAXFREQ 43000 /* low power oscillator max */
#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
#define PCIMINFREQ 25000000 /* 25 MHz */
#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
-#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
-#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
-
-/* different register spaces to access thr'u pcie indirect access */
-#define PCIE_CONFIGREGS 1 /* Access to config space */
-#define PCIE_PCIEREGS 2 /* Access to pcie registers */
+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
/* force HT war check */
-#define FORCEHT_WAR32414(si) \
- ((PCIE(si)) && (((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev == 1)) || \
- ((si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev <= 3))))
+#define FORCEHT_WAR32414(si) \
+ (((PCIE(si)) && (si->sb.chip == BCM4311_CHIP_ID) && ((si->sb.chiprev <= 1))) || \
+ ((PCI(si) || PCIE(si)) && (si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev <= 3)))
+
+#define PCIE_ASPMWARS(si) \
+ ((PCIE(si)) && ((si->sb.buscorerev >= 3) && (si->sb.buscorerev <= 5)))
/* GPIO Based LED powersave defines */
-#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
-#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
+#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
+#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
-static uint32
-sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr)
+static uint32 sb_read_sbreg(sb_info_t * si, volatile uint32 * sbr)
{
uint8 tmp;
uint32 val, intr_val = 0;
-
/*
* compact flash only has 11 bits address, while we needs 12 bits address.
* MEM_SEG will be OR'd with other 11 bits address in hardware,
* so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
* For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
*/
- if (si->memseg) {
+ if (PCMCIA(si)) {
INTR_OFF(si, intr_val);
tmp = 1;
OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
- sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */
+ sbr = (volatile uint32 *)((uintptr) sbr & ~(1 << 11)); /* mask out bit 11 */
}
val = R_REG(si->osh, sbr);
- if (si->memseg) {
+ if (PCMCIA(si)) {
tmp = 0;
OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
INTR_RESTORE(si, intr_val);
@@ -184,43 +222,43 @@ sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr)
return (val);
}
-static void
-sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v)
+static void sb_write_sbreg(sb_info_t * si, volatile uint32 * sbr, uint32 v)
{
uint8 tmp;
volatile uint32 dummy;
uint32 intr_val = 0;
-
/*
* compact flash only has 11 bits address, while we needs 12 bits address.
* MEM_SEG will be OR'd with other 11 bits address in hardware,
* so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
* For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
*/
- if (si->memseg) {
+ if (PCMCIA(si)) {
INTR_OFF(si, intr_val);
tmp = 1;
OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
- sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */
+ sbr = (volatile uint32 *)((uintptr) sbr & ~(1 << 11)); /* mask out bit 11 */
}
if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
#ifdef IL_BIGENDIAN
dummy = R_REG(si->osh, sbr);
- W_REG(si->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff));
+ W_REG(si->osh, ((volatile uint16 *)sbr + 1),
+ (uint16) ((v >> 16) & 0xffff));
dummy = R_REG(si->osh, sbr);
- W_REG(si->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff));
+ W_REG(si->osh, (volatile uint16 *)sbr, (uint16) (v & 0xffff));
#else
dummy = R_REG(si->osh, sbr);
- W_REG(si->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff));
+ W_REG(si->osh, (volatile uint16 *)sbr, (uint16) (v & 0xffff));
dummy = R_REG(si->osh, sbr);
- W_REG(si->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff));
-#endif /* IL_BIGENDIAN */
+ W_REG(si->osh, ((volatile uint16 *)sbr + 1),
+ (uint16) ((v >> 16) & 0xffff));
+#endif /* IL_BIGENDIAN */
} else
W_REG(si->osh, sbr, v);
- if (si->memseg) {
+ if (PCMCIA(si)) {
tmp = 0;
OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
INTR_RESTORE(si, intr_val);
@@ -236,24 +274,27 @@ sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v)
* vars - pointer to a pointer area for "environment" variables
* varsz - pointer to int to return the size of the vars
*/
-sb_t *
-BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs,
- uint bustype, void *sdh, char **vars, uint *varsz)
-{
+sb_t *sb_attach(uint devid, osl_t * osh, void *regs,
+ uint bustype, void *sdh, char **vars,
+ uint * varsz) {
sb_info_t *si;
/* alloc sb_info_t */
- if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) {
- SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
+ if ((si = MALLOC(osh, sizeof(sb_info_t))) == NULL) {
+ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n",
+ MALLOCED(osh)));
return (NULL);
}
- if (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, (uint*)varsz) == NULL) {
+ if (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz) ==
+ NULL) {
MFREE(osh, si, sizeof(sb_info_t));
return (NULL);
}
+ si->vars = vars ? *vars : NULL;
+ si->varsz = varsz ? *varsz : 0;
- return (sb_t *)si;
+ return (sb_t *) si;
}
/* Using sb_kattach depends on SB_BUS support, either implicit */
@@ -262,74 +303,55 @@ BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs,
/* global kernel resource */
static sb_info_t ksi;
-static bool ksi_attached = FALSE;
/* generic kernel variant of sb_attach() */
-sb_t *
-BCMINITFN(sb_kattach)(void)
-{
- osl_t *osh = NULL;
+sb_t *BCMINITFN(sb_kattach) (osl_t * osh) {
+ static bool ksi_attached = FALSE;
uint32 *regs;
if (!ksi_attached) {
uint32 cid;
- regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
- cid = R_REG(osh, (uint32 *)regs);
+ regs = (uint32 *) REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
+ cid = R_REG(osh, (uint32 *) regs);
if (((cid & CID_ID_MASK) == BCM4712_CHIP_ID) &&
((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) &&
((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) {
uint32 *scc, val;
- scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl));
+ scc =
+ (uint32 *) ((uchar *) regs +
+ OFFSETOF(chipcregs_t, slow_clk_ctl));
val = R_REG(osh, scc);
SB_ERROR((" initial scc = 0x%x\n", val));
val |= SCC_SS_XTAL;
W_REG(osh, scc, val);
}
- if (sb_doattach(&ksi, BCM4710_DEVICE_ID, osh, (void*)regs,
- SB_BUS, NULL, NULL, NULL) == NULL) {
+ if (sb_doattach(&ksi, BCM4710_DEVICE_ID, osh, (void *)regs, SB_BUS, NULL,
+ osh != SB_OSH ? &ksi.vars : NULL,
+ osh != SB_OSH ? &ksi.varsz : NULL) == NULL)
return NULL;
- }
- else
- ksi_attached = TRUE;
+ ksi_attached = TRUE;
}
- return (sb_t *)&ksi;
+ return &ksi.sb;
}
-#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
+#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
-void
-BCMINITFN(sb_war32414_forceHT)(sb_t *sbh, bool forceHT)
-{
- sb_info_t *si;
-
- si = SB_INFO(sbh);
-
-
- if (FORCEHT_WAR32414(si)) {
- uint32 val = 0;
- if (forceHT)
- val = SYCC_HR;
- sb_corereg((void*)si, SB_CC_IDX, OFFSETOF(chipcregs_t, system_clk_ctl),
- SYCC_HR, val);
- }
-}
-
-static sb_info_t *
-BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
- uint bustype, void *sdh, char **vars, uint *varsz)
-{
+static sb_info_t *BCMINITFN(sb_doattach) (sb_info_t * si, uint devid,
+ osl_t * osh, void *regs,
+ uint bustype, void *sdh,
+ char **vars, uint * varsz) {
uint origidx;
chipcregs_t *cc;
sbconfig_t *sb;
uint32 w;
+ char *pvars;
ASSERT(GOODREGS(regs));
- bzero((uchar*)si, sizeof(sb_info_t));
-
+ bzero((uchar *) si, sizeof(sb_info_t));
si->sb.buscoreidx = si->gpioidx = BADIDX;
si->curmap = regs;
@@ -338,17 +360,16 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
/* check to see if we are a sb core mimic'ing a pci core */
if (bustype == PCI_BUS) {
- if (OSL_PCI_READ_CONFIG(si->osh, PCI_SPROM_CONTROL, sizeof(uint32)) == 0xffffffff) {
- SB_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SB "
- "devid:0x%x\n", __FUNCTION__, devid));
+ if (OSL_PCI_READ_CONFIG
+ (si->osh, PCI_SPROM_CONTROL,
+ sizeof(uint32)) == 0xffffffff) {
+ SB_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SB " "devid:0x%x\n", __FUNCTION__, devid));
bustype = SB_BUS;
}
}
-
si->sb.bustype = bustype;
if (si->sb.bustype != BUSTYPE(si->sb.bustype)) {
- SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n",
- si->sb.bustype, BUSTYPE(si->sb.bustype)));
+ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", si->sb.bustype, BUSTYPE(si->sb.bustype)));
return NULL;
}
@@ -357,13 +378,14 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
si->memseg = TRUE;
/* kludge to enable the clock on the 4306 which lacks a slowclock */
- if (BUSTYPE(si->sb.bustype) == PCI_BUS)
- sb_clkctl_xtal(&si->sb, XTAL|PLL, ON);
+ if (BUSTYPE(si->sb.bustype) == PCI_BUS && !sb_ispcie(si))
+ sb_clkctl_xtal(&si->sb, XTAL | PLL, ON);
if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
w = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32));
if (!GOODCOREADDR(w))
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), SB_ENUM_BASE);
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN,
+ sizeof(uint32), SB_ENUM_BASE);
}
/* initialize current core index value */
@@ -375,9 +397,9 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
}
/* get sonics backplane revision */
- sb = REGS2SB(si->curmap);
- si->sb.sonicsrev = (R_SBREG(si, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
-
+ sb = REGS2SB(regs);
+ si->sb.sonicsrev =
+ (R_SBREG(si, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
/* keep and reuse the initial register mapping */
origidx = si->curidx;
if (BUSTYPE(si->sb.bustype) == SB_BUS)
@@ -385,7 +407,7 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
/* is core-0 a chipcommon core? */
si->numcores = 1;
- cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0);
+ cc = (chipcregs_t *) sb_setcoreidx(&si->sb, 0);
if (sb_coreid(&si->sb) != SB_CC)
cc = NULL;
@@ -393,8 +415,12 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
if (cc) {
/* chip common core found! */
si->sb.chip = R_REG(si->osh, &cc->chipid) & CID_ID_MASK;
- si->sb.chiprev = (R_REG(si->osh, &cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT;
- si->sb.chippkg = (R_REG(si->osh, &cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT;
+ si->sb.chiprev =
+ (R_REG(si->osh, &cc->chipid) & CID_REV_MASK) >>
+ CID_REV_SHIFT;
+ si->sb.chippkg =
+ (R_REG(si->osh, &cc->chipid) & CID_PKG_MASK) >>
+ CID_PKG_SHIFT;
} else {
/* no chip common core -- must convert device id to chip id */
if ((si->sb.chip = sb_pcidev2chip(devid)) == 0) {
@@ -407,9 +433,13 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
/* get chipcommon rev */
si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV;
+ /* get chipcommon capabilites */
+ si->sb.cccaps = cc ? R_REG(si->osh, &cc->capabilities) : 0;
+
/* determine numcores */
if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6)))
- si->numcores = (R_REG(si->osh, &cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT;
+ si->numcores =
+ (R_REG(si->osh, &cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT;
else
si->numcores = sb_chip2numcores(si->sb.chip);
@@ -423,19 +453,27 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
sb_scan(si);
/* fixup necessary chip/core configurations */
- if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
- if (sb_pci_fixcfg(si)) {
- SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n"));
- return NULL;
- }
+ if (BUSTYPE(si->sb.bustype) == PCI_BUS && sb_pci_fixcfg(si)) {
+ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n"));
+ return NULL;
}
- /* srom_var_init() depends on sb_scan() info */
- if (srom_var_init(si, si->sb.bustype, si->curmap, si->osh, vars, varsz)) {
+ /* Init nvram from sprom/otp if they exist */
+ if (srom_var_init
+ (&si->sb, BUSTYPE(si->sb.bustype), regs, si->osh, vars, varsz)) {
SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n"));
return (NULL);
}
-
+ pvars = vars ? *vars : NULL;
+
+ /* PMU specific initializations */
+ if ((si->sb.cccaps & CC_CAP_PMU) && !sb_onetimeinit) {
+ sb_pmu_init(&si->sb, si->osh);
+ /* Find out Crystal frequency and init PLL */
+ sb_pmu_pll_init(&si->sb, si->osh, getintvar(pvars, "xtalfreq"));
+ /* Initialize PMU resources (up/dn timers, dep masks, etc.) */
+ sb_pmu_res_init(&si->sb, si->osh);
+ }
if (cc == NULL) {
/*
* The chip revision number is hardwired into all
@@ -448,17 +486,17 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
ASSERT(vars);
si->sb.chiprev = getintvar(*vars, "chiprev");
} else if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
- w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_REV, sizeof(uint32));
+ w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_REV,
+ sizeof(uint32));
si->sb.chiprev = w & 0xff;
} else
si->sb.chiprev = 0;
}
if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
- w = getintvar(*vars, "regwindowsz");
+ w = getintvar(pvars, "regwindowsz");
si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE;
}
-
/* gpio control core is required */
if (!GOODIDX(si->gpioidx)) {
SB_ERROR(("sb_doattach: gpio control core not found\n"));
@@ -470,21 +508,32 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
case PCI_BUS:
/* do a pci config read to get subsystem id and subvendor id */
w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_SVID, sizeof(uint32));
- si->sb.boardvendor = w & 0xffff;
- si->sb.boardtype = (w >> 16) & 0xffff;
+ /* Let nvram variables override subsystem Vend/ID */
+ if ((si->sb.boardvendor =
+ (uint16) sb_getdevpathintvar(&si->sb, "boardvendor")) == 0)
+ si->sb.boardvendor = w & 0xffff;
+ else
+ SB_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", si->sb.boardvendor, w & 0xffff));
+ if ((si->sb.boardtype =
+ (uint16) sb_getdevpathintvar(&si->sb, "boardtype")) == 0)
+ si->sb.boardtype = (w >> 16) & 0xffff;
+ else
+ SB_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", si->sb.boardtype, (w >> 16) & 0xffff));
break;
case PCMCIA_BUS:
- case SDIO_BUS:
- si->sb.boardvendor = getintvar(*vars, "manfid");
- si->sb.boardtype = getintvar(*vars, "prodid");
+ si->sb.boardvendor = getintvar(pvars, "manfid");
+ si->sb.boardtype = getintvar(pvars, "prodid");
break;
case SB_BUS:
case JTAG_BUS:
si->sb.boardvendor = VENDOR_BROADCOM;
- if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0)
- si->sb.boardtype = 0xffff;
+ if (pvars == NULL
+ || ((si->sb.boardtype = getintvar(pvars, "prodid")) == 0))
+ if ((si->sb.boardtype =
+ getintvar(NULL, "boardtype")) == 0)
+ si->sb.boardtype = 0xffff;
break;
}
@@ -493,25 +542,147 @@ BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
ASSERT(si->sb.boardtype);
}
+ si->sb.boardflags = getintvar(pvars, "boardflags");
+
/* setup the GPIO based LED powersave register */
if (si->sb.ccrev >= 16) {
- if ((vars == NULL) || ((w = getintvar(*vars, "leddc")) == 0))
+ if ((pvars == NULL) || ((w = getintvar(pvars, "leddc")) == 0))
w = DEFAULT_GPIOTIMERVAL;
- sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
+ sb_corereg(&si->sb, SB_CC_IDX,
+ OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
+ }
+
+ /* Determine if this board needs override */
+ if (PCIE(si) && (si->sb.chip == BCM4321_CHIP_ID))
+ si->pcie_war_ovr = ((si->sb.boardvendor == VENDOR_APPLE) &&
+ ((uint8) getintvar(pvars, "sromrev") == 4)
+ && ((uint8) getintvar(pvars, "boardrev") <=
+ 0x71))
+ || ((uint32) getintvar(pvars, "boardflags2") &
+ BFL2_PCIEWAR_OVR);
+
+ if (PCIE_ASPMWARS(si)) {
+ sb_war43448_aspm((void *)si);
+ sb_war42767_clkreq((void *)si);
}
+
if (FORCEHT_WAR32414(si)) {
- /* set proper clk setup delays before forcing HT */
- sb_clkctl_init((void *)si);
- sb_war32414_forceHT((void *)si, 1);
+ si->sb.pr32414 = TRUE;
+ sb_clkctl_init(&si->sb);
+ sb_war32414_forceHT(&si->sb, 1);
+ }
+
+ if (PCIE(si) && ((si->sb.buscorerev == 6) || (si->sb.buscorerev == 7)))
+ si->sb.pr42780 = TRUE;
+
+ if (PCIE_ASPMWARS(si))
+ sb_pcieclkreq(&si->sb, 1, 0);
+
+ if (PCIE(si) &&
+ (((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev == 2)) ||
+ ((si->sb.chip == BCM4312_CHIP_ID) && (si->sb.chiprev == 0))))
+ sb_set_initiator_to(&si->sb, 0x3,
+ sb_findcoreidx(&si->sb, SB_D11, 0));
+
+ /* Disable gpiopullup and gpiopulldown */
+ if (!sb_onetimeinit && si->sb.ccrev >= 20) {
+ cc = (chipcregs_t *) sb_setcore(&si->sb, SB_CC, 0);
+ W_REG(osh, &cc->gpiopullup, 0);
+ W_REG(osh, &cc->gpiopulldown, 0);
+ sb_setcoreidx(&si->sb, origidx);
}
+#ifdef BCMDBG
+ /* clear any previous epidiag-induced target abort */
+ sb_taclear(&si->sb);
+#endif /* BCMDBG */
+#ifdef HNDRTE
+ sb_onetimeinit = TRUE;
+#endif
return (si);
}
+/* Enable/Disable clkreq for PCIE (4311B0/4321B1) */
+void sb_war42780_clkreq(sb_t * sbh, bool clkreq) {
+ sb_info_t *si;
-uint
-sb_coreid(sb_t *sbh)
+ si = SB_INFO(sbh);
+
+ /* Don't change clkreq value if serdespll war has not yet been applied */
+ if (!si->pr42767_war && PCIE_ASPMWARS(si))
+ return;
+
+ sb_pcieclkreq(sbh, 1, (int32) clkreq);
+}
+
+static void BCMINITFN(sb_war43448) (sb_t * sbh) {
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
+
+ /* if not pcie bus, we're done */
+ if (!PCIE(si) || !PCIE_ASPMWARS(si))
+ return;
+
+ /* Restore the polarity */
+ if (si->pcie_polarity != 0)
+ sb_pcie_mdiowrite((void *)(uintptr) & si->sb, MDIODATA_DEV_RX,
+ SERDES_RX_CTRL, si->pcie_polarity);
+}
+
+static void BCMINITFN(sb_war43448_aspm) (sb_t * sbh) {
+ uint32 w;
+ uint16 val16, *reg16;
+ sbpcieregs_t *pcieregs;
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
+
+ /* if not pcie bus, we're done */
+ if (!PCIE(si) || !PCIE_ASPMWARS(si))
+ return;
+
+ /* no ASPM stuff on QT or VSIM */
+ if (si->sb.chippkg == HDLSIM_PKG_ID || si->sb.chippkg == HWSIM_PKG_ID)
+ return;
+
+ pcieregs = (sbpcieregs_t *) sb_setcoreidx(sbh, si->sb.buscoreidx);
+
+ /* Enable ASPM in the shadow SROM and Link control */
+ reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
+ val16 = R_REG(si->osh, reg16);
+ if (!si->pcie_war_ovr)
+ val16 |= SRSH_ASPM_ENB;
+ else
+ val16 &= ~SRSH_ASPM_ENB;
+ W_REG(si->osh, reg16, val16);
+
+ w = OSL_PCI_READ_CONFIG(si->osh, si->pciecap_lcreg_offset,
+ sizeof(uint32));
+ if (!si->pcie_war_ovr)
+ w |= PCIE_ASPM_ENAB;
+ else
+ w &= ~PCIE_ASPM_ENAB;
+ OSL_PCI_WRITE_CONFIG(si->osh, si->pciecap_lcreg_offset, sizeof(uint32),
+ w);
+}
+
+static void BCMINITFN(sb_war32414_forceHT) (sb_t * sbh, bool forceHT) {
+ sb_info_t *si;
+ uint32 val = 0;
+
+ si = SB_INFO(sbh);
+
+ ASSERT(FORCEHT_WAR32414(si));
+
+ if (forceHT)
+ val = SYCC_HR;
+ sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, system_clk_ctl),
+ SYCC_HR, val);
+}
+
+uint sb_coreid(sb_t * sbh)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -522,8 +693,18 @@ sb_coreid(sb_t *sbh)
return ((R_SBREG(si, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
}
-uint
-sb_coreidx(sb_t *sbh)
+uint sb_flag(sb_t * sbh)
+{
+ sb_info_t *si;
+ sbconfig_t *sb;
+
+ si = SB_INFO(sbh);
+ sb = REGS2SB(si->curmap);
+
+ return R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
+}
+
+uint sb_coreidx(sb_t * sbh)
{
sb_info_t *si;
@@ -531,10 +712,9 @@ sb_coreidx(sb_t *sbh)
return (si->curidx);
}
-/* return current index of core */
-static uint
-_sb_coreidx(sb_info_t *si)
+static uint _sb_coreidx(sb_info_t * si)
{
+
sbconfig_t *sb;
uint32 sbaddr = 0;
@@ -547,26 +727,27 @@ _sb_coreidx(sb_info_t *si)
break;
case PCI_BUS:
- sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32));
+ sbaddr =
+ OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32));
break;
- case PCMCIA_BUS: {
- uint8 tmp = 0;
+ case PCMCIA_BUS:{
+ uint8 tmp = 0;
- OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
- sbaddr = (uint)tmp << 12;
- OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
- sbaddr |= (uint)tmp << 16;
- OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
- sbaddr |= (uint)tmp << 24;
- break;
- }
+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
+ sbaddr = (uint) tmp << 12;
+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
+ sbaddr |= (uint) tmp << 16;
+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
+ sbaddr |= (uint) tmp << 24;
+ break;
+ }
#ifdef BCMJTAG
case JTAG_BUS:
- sbaddr = (uint32)si->curmap;
+ sbaddr = (uint32) si->curmap;
break;
-#endif /* BCMJTAG */
+#endif /* BCMJTAG */
default:
ASSERT(0);
@@ -578,8 +759,7 @@ _sb_coreidx(sb_info_t *si)
return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE);
}
-uint
-sb_corevendor(sb_t *sbh)
+uint sb_corevendor(sb_t * sbh)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -590,8 +770,7 @@ sb_corevendor(sb_t *sbh)
return ((R_SBREG(si, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
}
-uint
-sb_corerev(sb_t *sbh)
+uint sb_corerev(sb_t * sbh)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -604,8 +783,7 @@ sb_corerev(sb_t *sbh)
return (SBCOREREV(sbidh));
}
-void *
-sb_osh(sb_t *sbh)
+void *sb_osh(sb_t * sbh)
{
sb_info_t *si;
@@ -613,8 +791,7 @@ sb_osh(sb_t *sbh)
return si->osh;
}
-void
-sb_setosh(sb_t *sbh, osl_t *osh)
+void sb_setosh(sb_t * sbh, osl_t * osh)
{
sb_info_t *si;
@@ -626,9 +803,25 @@ sb_setosh(sb_t *sbh, osl_t *osh)
si->osh = osh;
}
+/* set sbtmstatelow core-specific flags */
+void sb_coreflags_wo(sb_t * sbh, uint32 mask, uint32 val)
+{
+ sb_info_t *si;
+ sbconfig_t *sb;
+ uint32 w;
+
+ si = SB_INFO(sbh);
+ sb = REGS2SB(si->curmap);
+
+ ASSERT((val & ~mask) == 0);
+
+ /* mask and set */
+ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val;
+ W_SBREG(si, &sb->sbtmstatelow, w);
+}
+
/* set/clear sbtmstatelow core-specific flags */
-uint32
-sb_coreflags(sb_t *sbh, uint32 mask, uint32 val)
+uint32 sb_coreflags(sb_t * sbh, uint32 mask, uint32 val)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -645,13 +838,14 @@ sb_coreflags(sb_t *sbh, uint32 mask, uint32 val)
W_SBREG(si, &sb->sbtmstatelow, w);
}
- /* return the new value */
+ /* return the new value
+ * for write operation, the following readback ensures the completion of write opration.
+ */
return (R_SBREG(si, &sb->sbtmstatelow));
}
/* set/clear sbtmstatehigh core-specific flags */
-uint32
-sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val)
+uint32 sb_coreflagshi(sb_t * sbh, uint32 mask, uint32 val)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -670,12 +864,11 @@ sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val)
}
/* return the new value */
- return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK);
+ return (R_SBREG(si, &sb->sbtmstatehigh));
}
/* Run bist on current core. Caller needs to take care of core-specific bist hazards */
-int
-sb_corebist(sb_t *sbh)
+int sb_corebist(sb_t * sbh)
{
uint32 sblo;
sb_info_t *si;
@@ -688,18 +881,18 @@ sb_corebist(sb_t *sbh)
sblo = R_SBREG(si, &sb->sbtmstatelow);
W_SBREG(si, &sb->sbtmstatelow, (sblo | SBTML_FGC | SBTML_BE));
- SPINWAIT(((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTD) == 0), 100000);
+ SPINWAIT(((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTD) == 0),
+ 100000);
if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTF)
- result = BCME_ERROR;
+ result = -1;
W_SBREG(si, &sb->sbtmstatelow, sblo);
return result;
}
-bool
-sb_iscoreup(sb_t *sbh)
+bool sb_iscoreup(sb_t * sbh)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -708,7 +901,7 @@ sb_iscoreup(sb_t *sbh)
sb = REGS2SB(si->curmap);
return ((R_SBREG(si, &sb->sbtmstatelow) &
- (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK);
+ (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK);
}
/*
@@ -720,51 +913,62 @@ sb_iscoreup(sb_t *sbh)
* Also, when using pci/pcie, we can optimize away the core switching for pci registers
* and (on newer pci cores) chipcommon registers.
*/
-static uint
-sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val)
+uint sb_corereg(sb_t * sbh, uint coreidx, uint regoff, uint mask, uint val)
{
uint origidx = 0;
uint32 *r = NULL;
uint w;
uint intr_val = 0;
bool fast = FALSE;
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
ASSERT(GOODIDX(coreidx));
ASSERT(regoff < SB_CORE_SIZE);
ASSERT((val & ~mask) == 0);
-#ifdef notyet
- if (si->sb.bustype == SB_BUS) {
+#if 0
+ if (BUSTYPE(si->sb.bustype) == SB_BUS) {
/* If internal bus, we can always get at everything */
fast = TRUE;
- r = (uint32 *)((uchar *)si->regs[coreidx] + regoff);
- } else if (si->sb.bustype == PCI_BUS) {
+ /* map if does not exist */
+ if (!si->regs[coreidx]) {
+ si->regs[coreidx] =
+ (void *)REG_MAP(si->coresba[coreidx], SB_CORE_SIZE);
+ ASSERT(GOODREGS(si->regs[coreidx]));
+ }
+ r = (uint32 *) ((uchar *) si->regs[coreidx] + regoff);
+ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
/* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
if ((si->coreid[coreidx] == SB_CC) &&
- ((si->sb.buscoretype == SB_PCIE) ||
- (si->sb.buscorerev >= 13))) {
+ ((si->sb.buscoretype == SB_PCIE)
+ || (si->sb.buscorerev >= 13))) {
/* Chipc registers are mapped at 12KB */
fast = TRUE;
- r = (uint32 *)((char *)si->curmap + PCI_16KB0_CCREGS_OFFSET + regoff);
+ r = (uint32 *) ((char *)si->curmap +
+ PCI_16KB0_CCREGS_OFFSET + regoff);
} else if (si->sb.buscoreidx == coreidx) {
/* pci registers are at either in the last 2KB of an 8KB window
* or, in pcie and pci rev 13 at 8KB
*/
fast = TRUE;
- if ((si->sb.buscoretype == SB_PCIE) ||
- (si->sb.buscorerev >= 13))
- r = (uint32 *)((char *)si->curmap +
- PCI_16KB0_PCIREGS_OFFSET + regoff);
+ if ((si->sb.buscoretype == SB_PCIE)
+ || (si->sb.buscorerev >= 13))
+ r = (uint32 *) ((char *)si->curmap +
+ PCI_16KB0_PCIREGS_OFFSET +
+ regoff);
else
- r = (uint32 *)((char *)si->curmap +
- ((regoff >= SBCONFIGOFF) ?
- PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
- regoff);
+ r = (uint32 *) ((char *)si->curmap +
+ ((regoff >= SBCONFIGOFF) ?
+ PCI_BAR0_PCISBR_OFFSET :
+ PCI_BAR0_PCIREGS_OFFSET)
+ + regoff);
}
}
-#endif /* notyet */
+#endif
if (!fast) {
INTR_OFF(si, intr_val);
@@ -773,7 +977,8 @@ sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val)
origidx = sb_coreidx(&si->sb);
/* switch core */
- r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff);
+ r = (uint32 *) ((uchar *) sb_setcoreidx(&si->sb, coreidx) +
+ regoff);
}
ASSERT(r);
@@ -791,8 +996,14 @@ sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val)
/* readback */
if (regoff >= SBCONFIGOFF)
w = R_SBREG(si, r);
- else
- w = R_REG(si->osh, r);
+ else {
+ if ((si->sb.chip == BCM5354_CHIP_ID) &&
+ (coreidx == SB_CC_IDX) &&
+ (regoff == OFFSETOF(chipcregs_t, watchdog))) {
+ w = val;
+ } else
+ w = R_REG(si->osh, r);
+ }
if (!fast) {
/* restore core index */
@@ -821,78 +1032,290 @@ sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val)
#define read_pci_cfg_word(a) \
(WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff)
-
-/* return TRUE if requested capability exists in the PCI config space */
-static bool
-sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen)
+/* return cap_offset if requested capability exists in the PCI config space */
+static uint8
+sb_find_pci_capability(sb_info_t * si, uint8 req_cap_id, uchar * buf,
+ uint32 * buflen)
{
uint8 cap_id;
- uint8 cap_ptr;
- uint32 bufsize;
+ uint8 cap_ptr = 0;
+ uint32 bufsize;
uint8 byte_val;
if (BUSTYPE(si->sb.bustype) != PCI_BUS)
- return FALSE;
+ goto end;
/* check for Header type 0 */
byte_val = read_pci_cfg_byte(PCI_CFG_HDR);
if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
- return FALSE;
+ goto end;
/* check if the capability pointer field exists */
byte_val = read_pci_cfg_byte(PCI_CFG_STAT);
if (!(byte_val & PCI_CAPPTR_PRESENT))
- return FALSE;
+ goto end;
cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR);
/* check if the capability pointer is 0x00 */
if (cap_ptr == 0x00)
- return FALSE;
-
+ goto end;
/* loop thr'u the capability list and see if the pcie capabilty exists */
cap_id = read_pci_cfg_byte(cap_ptr);
while (cap_id != req_cap_id) {
- cap_ptr = read_pci_cfg_byte((cap_ptr+1));
- if (cap_ptr == 0x00) break;
+ cap_ptr = read_pci_cfg_byte((cap_ptr + 1));
+ if (cap_ptr == 0x00)
+ break;
cap_id = read_pci_cfg_byte(cap_ptr);
}
if (cap_id != req_cap_id) {
- return FALSE;
+ goto end;
}
/* found the caller requested capability */
if ((buf != NULL) && (buflen != NULL)) {
+ uint8 cap_data;
+
bufsize = *buflen;
- if (!bufsize) goto end;
+ if (!bufsize)
+ goto end;
*buflen = 0;
/* copy the cpability data excluding cap ID and next ptr */
- cap_ptr += 2;
- if ((bufsize + cap_ptr) > SZPCR)
- bufsize = SZPCR - cap_ptr;
+ cap_data = cap_ptr + 2;
+ if ((bufsize + cap_data) > SZPCR)
+ bufsize = SZPCR - cap_data;
*buflen = bufsize;
while (bufsize--) {
- *buf = read_pci_cfg_byte(cap_ptr);
- cap_ptr++;
+ *buf = read_pci_cfg_byte(cap_data);
+ cap_data++;
buf++;
}
}
-end:
+ end:
+ return cap_ptr;
+}
+
+uint8 sb_pcieclkreq(sb_t * sbh, uint32 mask, uint32 val)
+{
+ sb_info_t *si;
+ uint32 reg_val;
+ uint8 offset;
+
+ si = SB_INFO(sbh);
+
+ offset = si->pciecap_lcreg_offset;
+ if (!offset)
+ return 0;
+
+ reg_val = OSL_PCI_READ_CONFIG(si->osh, offset, sizeof(uint32));
+ /* set operation */
+ if (mask) {
+ if (val)
+ reg_val |= PCIE_CLKREQ_ENAB;
+ else
+ reg_val &= ~PCIE_CLKREQ_ENAB;
+ OSL_PCI_WRITE_CONFIG(si->osh, offset, sizeof(uint32), reg_val);
+ reg_val = OSL_PCI_READ_CONFIG(si->osh, offset, sizeof(uint32));
+ }
+ if (reg_val & PCIE_CLKREQ_ENAB)
+ return 1;
+ else
+ return 0;
+}
+
+#ifdef BCMDBG
+
+uint32 sb_pcielcreg(sb_t * sbh, uint32 mask, uint32 val)
+{
+ sb_info_t *si;
+ uint32 reg_val;
+ uint8 offset;
+
+ si = SB_INFO(sbh);
+
+ if (!PCIE(si))
+ return 0;
+
+ offset = si->pciecap_lcreg_offset;
+ if (!offset)
+ return 0;
+
+ /* set operation */
+ if (mask)
+ OSL_PCI_WRITE_CONFIG(si->osh, offset, sizeof(uint32), val);
+
+ reg_val = OSL_PCI_READ_CONFIG(si->osh, offset, sizeof(uint32));
+
+ return reg_val;
+}
+
+uint8 sb_pcieL1plldown(sb_t * sbh)
+{
+ sb_info_t *si;
+ uint intr_val = 0;
+ uint origidx;
+ uint32 reg_val;
+
+ si = SB_INFO(sbh);
+
+ if (!PCIE(si))
+ return 0;
+ if (!((si->sb.buscorerev == 3) || (si->sb.buscorerev == 4)))
+ return 0;
+
+ if (!sb_pcieclkreq((void *)(uintptr) sbh, 0, 0)) {
+ SB_ERROR(("PCIEL1PLLDOWN requires Clkreq be enabled, so enable it\n"));
+ sb_pcieclkreq((void *)(uintptr) sbh, 1, 1);
+ }
+ reg_val = sb_pcielcreg((void *)(uintptr) sbh, 0, 0);
+ if (reg_val & PCIE_CAP_LCREG_ASPML0s) {
+ SB_ERROR(("PCIEL1PLLDOWN requires L0s to be disabled\n"));
+ reg_val &= ~PCIE_CAP_LCREG_ASPML0s;
+ sb_pcielcreg((void *)(uintptr) sbh, 1, reg_val);
+ } else
+ SB_ERROR(("PCIEL1PLLDOWN: L0s is already disabled\n"));
+
+ /* turnoff intrs, change core, set original back, turn on intrs back on */
+ origidx = si->curidx;
+ INTR_OFF(si, intr_val);
+ sb_setcore(sbh, SB_PCIE, 0);
+
+ sb_pcie_writereg((void *)(uintptr) sbh, (void *)PCIE_PCIEREGS,
+ PCIE_DLLP_PCIE11, 0);
+
+ sb_setcoreidx(sbh, origidx);
+ INTR_RESTORE(si, intr_val);
+ return 1;
+}
+#endif /* BCMDBG */
+
+/* return TRUE if PCIE capability exists in the pci config space */
+static bool sb_ispcie(sb_info_t * si)
+{
+ uint8 cap_ptr;
+
+ cap_ptr = sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL);
+ if (!cap_ptr)
+ return FALSE;
+
+ si->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
+
return TRUE;
}
-/* return TRUE if PCIE capability exists the pci config space */
-static inline bool
-sb_ispcie(sb_info_t *si)
+/* Wake-on-wireless-LAN (WOWL) support functions */
+/* return TRUE if PM capability exists in the pci config space */
+bool sb_pci_pmecap(sb_t * sbh)
{
- return (sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL));
+ uint8 cap_ptr;
+ uint32 pmecap;
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
+
+ if (si == NULL || !(PCI(si) || PCIE(si)))
+ return FALSE;
+
+ if (!si->pmecap_offset) {
+ cap_ptr =
+ sb_find_pci_capability(si, PCI_CAP_POWERMGMTCAP_ID, NULL,
+ NULL);
+ if (!cap_ptr)
+ return FALSE;
+
+ si->pmecap_offset = cap_ptr;
+
+ pmecap =
+ OSL_PCI_READ_CONFIG(si->osh, si->pmecap_offset,
+ sizeof(uint32));
+
+ /* At least one state can generate PME */
+ si->pmecap = (pmecap & PME_CAP_PM_STATES) != 0;
+ }
+
+ return (si->pmecap);
}
-/* scan the sb enumerated space to identify all cores */
-static void
-BCMINITFN(sb_scan)(sb_info_t *si)
+/* Enable PME generation and disable clkreq */
+void sb_pci_pmeen(sb_t * sbh)
{
+ sb_info_t *si;
+ uint32 w;
+ si = SB_INFO(sbh);
+
+ /* if not pmecapable return */
+ if (!sb_pci_pmecap(sbh))
+ return;
+
+ w = OSL_PCI_READ_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32));
+ w |= (PME_CSR_PME_EN);
+ OSL_PCI_WRITE_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32), w);
+
+ /* Disable clkreq */
+ if (si->pr42767_war) {
+ sb_pcieclkreq(sbh, 1, 0);
+ si->pr42767_war = FALSE;
+ } else if (si->sb.pr42780) {
+ sb_pcieclkreq(sbh, 1, 1);
+ }
+}
+
+/* Disable PME generation, clear the PME status bit if set and
+ * return TRUE if PME status set
+ */
+bool sb_pci_pmeclr(sb_t * sbh)
+{
+ sb_info_t *si;
+ uint32 w;
+ bool ret = FALSE;
+
+ si = SB_INFO(sbh);
+
+ if (!sb_pci_pmecap(sbh))
+ return ret;
+
+ w = OSL_PCI_READ_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32));
+
+ SB_ERROR(("sb_pci_pmeclr PMECSR : 0x%x\n", w));
+ ret = (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT;
+
+ /* PMESTAT is cleared by writing 1 to it */
+ w &= ~(PME_CSR_PME_EN);
+
+ OSL_PCI_WRITE_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
+ sizeof(uint32), w);
+
+ return ret;
+}
+
+/* use pci dev id to determine chip id for chips not having a chipcommon core */
+static uint BCMINITFN(sb_pcidev2chip) (uint pcidev) {
+ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
+ return (BCM4710_CHIP_ID);
+ if ((pcidev >= BCM4402_ENET_ID) && (pcidev <= BCM4402_V90_ID))
+ return (BCM4402_CHIP_ID);
+ if (pcidev == BCM4401_ENET_ID)
+ return (BCM4402_CHIP_ID);
+ if (pcidev == SDIOH_FPGA_ID)
+ return (SDIOH_FPGA_ID);
+
+ return (0);
+}
+
+/* Scan the enumeration space to find all cores starting from the given
+ * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba'
+ * is the default core address at chip POR time and 'regs' is the virtual
+ * address that the default core is mapped at. 'ncores' is the number of
+ * cores expected on bus 'sbba'. It returns the total number of cores
+ * starting from bus 'sbba', inclusive.
+ */
+
+static void BCMINITFN(sb_scan) (sb_info_t * si) {
+ sb_t *sbh;
uint origidx;
uint i;
bool pci;
@@ -902,6 +1325,7 @@ BCMINITFN(sb_scan)(sb_info_t *si)
uint pcirev;
uint pcierev;
+ sbh = (sb_t *) si;
/* numcores should already be set */
ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES));
@@ -959,14 +1383,14 @@ BCMINITFN(sb_scan)(sb_info_t *si)
* - else if there's a pci core (rev >= 2) - use that
* - else there had better be an extif core (4710 only)
*/
- if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) {
- si->gpioidx = sb_findcoreidx(si, SB_CC, 0);
+ if (GOODIDX(sb_findcoreidx(sbh, SB_CC, 0))) {
+ si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0);
si->gpioid = SB_CC;
} else if (PCI(si) && (si->sb.buscorerev >= 2)) {
si->gpioidx = si->sb.buscoreidx;
si->gpioid = SB_PCI;
- } else if (sb_findcoreidx(si, SB_EXTIF, 0)) {
- si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0);
+ } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) {
+ si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0);
si->gpioid = SB_EXTIF;
} else
ASSERT(si->gpioidx != BADIDX);
@@ -976,8 +1400,7 @@ BCMINITFN(sb_scan)(sb_info_t *si)
}
/* may be called with core in reset */
-void
-sb_detach(sb_t *sbh)
+void sb_detach(sb_t * sbh)
{
sb_info_t *si;
uint idx;
@@ -995,29 +1418,13 @@ sb_detach(sb_t *sbh)
}
#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS)
if (si != &ksi)
-#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
+#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
MFREE(si->osh, si, sizeof(sb_info_t));
-
}
-/* use pci dev id to determine chip id for chips not having a chipcommon core */
-static uint
-BCMINITFN(sb_pcidev2chip)(uint pcidev)
-{
- if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
- return (BCM4710_CHIP_ID);
- if ((pcidev >= BCM4402_ENET_ID) && (pcidev <= BCM4402_V90_ID))
- return (BCM4402_CHIP_ID);
- if (pcidev == BCM4401_ENET_ID)
- return (BCM4402_CHIP_ID);
-
- return (0);
-}
/* convert chip number to number of i/o cores */
-static uint
-BCMINITFN(sb_chip2numcores)(uint chip)
-{
+static uint BCMINITFN(sb_chip2numcores) (uint chip) {
if (chip == BCM4710_CHIP_ID)
return (9);
if (chip == BCM4402_CHIP_ID)
@@ -1028,6 +1435,8 @@ BCMINITFN(sb_chip2numcores)(uint chip)
return (9);
if (chip == BCM5365_CHIP_ID)
return (7);
+ if (chip == SDIOH_FPGA_ID)
+ return (2);
SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip));
ASSERT(0);
@@ -1035,12 +1444,14 @@ BCMINITFN(sb_chip2numcores)(uint chip)
}
/* return index of coreid or BADIDX if not found */
-static uint
-sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit)
+uint sb_findcoreidx(sb_t * sbh, uint coreid, uint coreunit)
{
+ sb_info_t *si;
uint found;
uint i;
+ si = SB_INFO(sbh);
+
found = 0;
for (i = 0; i < si->numcores; i++)
@@ -1058,8 +1469,7 @@ sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit)
* must be called with interrupt off.
* Moreover, callers should keep interrupts off during switching out of and back to d11 core
*/
-void*
-sb_setcoreidx(sb_t *sbh, uint coreidx)
+void *sb_setcoreidx(sb_t * sbh, uint coreidx)
{
sb_info_t *si;
uint32 sbaddr;
@@ -1074,7 +1484,8 @@ sb_setcoreidx(sb_t *sbh, uint coreidx)
* If the user has provided an interrupt mask enabled function,
* then assert interrupts are disabled before switching the core.
*/
- ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg));
+ ASSERT((si->intrsenabled_fn == NULL)
+ || !(*(si)->intrsenabled_fn) ((si)->intr_arg));
sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE);
@@ -1082,7 +1493,8 @@ sb_setcoreidx(sb_t *sbh, uint coreidx)
case SB_BUS:
/* map new one */
if (!si->regs[coreidx]) {
- si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE);
+ si->regs[coreidx] =
+ (void *)REG_MAP(sbaddr, SB_CORE_SIZE);
ASSERT(GOODREGS(si->regs[coreidx]));
}
si->curmap = si->regs[coreidx];
@@ -1110,7 +1522,7 @@ sb_setcoreidx(sb_t *sbh, uint coreidx)
}
si->curmap = si->regs[coreidx];
break;
-#endif /* BCMJTAG */
+#endif /* BCMJTAG */
}
si->curidx = coreidx;
@@ -1123,14 +1535,11 @@ sb_setcoreidx(sb_t *sbh, uint coreidx)
* must be called with interrupt off.
* Moreover, callers should keep interrupts off during switching out of and back to d11 core
*/
-void*
-sb_setcore(sb_t *sbh, uint coreid, uint coreunit)
+void *sb_setcore(sb_t * sbh, uint coreid, uint coreunit)
{
- sb_info_t *si;
uint idx;
- si = SB_INFO(sbh);
- idx = sb_findcoreidx(si, coreid, coreunit);
+ idx = sb_findcoreidx(sbh, coreid, coreunit);
if (!GOODIDX(idx))
return (NULL);
@@ -1138,9 +1547,7 @@ sb_setcore(sb_t *sbh, uint coreid, uint coreunit)
}
/* return chip number */
-uint
-sb_chip(sb_t *sbh)
-{
+uint BCMINITFN(sb_chip) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1148,9 +1555,7 @@ sb_chip(sb_t *sbh)
}
/* return chip revision number */
-uint
-sb_chiprev(sb_t *sbh)
-{
+uint BCMINITFN(sb_chiprev) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1158,9 +1563,7 @@ sb_chiprev(sb_t *sbh)
}
/* return chip common revision number */
-uint
-sb_chipcrev(sb_t *sbh)
-{
+uint BCMINITFN(sb_chipcrev) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1168,9 +1571,7 @@ sb_chipcrev(sb_t *sbh)
}
/* return chip package option */
-uint
-sb_chippkg(sb_t *sbh)
-{
+uint BCMINITFN(sb_chippkg) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1178,18 +1579,14 @@ sb_chippkg(sb_t *sbh)
}
/* return PCI core rev. */
-uint
-sb_pcirev(sb_t *sbh)
-{
+uint BCMINITFN(sb_pcirev) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
return (si->sb.buscorerev);
}
-bool
-BCMINITFN(sb_war16165)(sb_t *sbh)
-{
+bool BCMINITFN(sb_war16165) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1197,18 +1594,14 @@ BCMINITFN(sb_war16165)(sb_t *sbh)
return (PCI(si) && (si->sb.buscorerev <= 10));
}
-static void
-BCMINITFN(sb_war30841)(sb_info_t *si)
-{
+static void BCMINITFN(sb_war30841) (sb_info_t * si) {
sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
}
/* return PCMCIA core rev. */
-uint
-BCMINITFN(sb_pcmciarev)(sb_t *sbh)
-{
+uint BCMINITFN(sb_pcmciarev) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1216,9 +1609,7 @@ BCMINITFN(sb_pcmciarev)(sb_t *sbh)
}
/* return board vendor id */
-uint
-sb_boardvendor(sb_t *sbh)
-{
+uint BCMINITFN(sb_boardvendor) (sb_t * sbh) {
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1226,9 +1617,7 @@ sb_boardvendor(sb_t *sbh)
}
/* return boardtype */
-uint
-sb_boardtype(sb_t *sbh)
-{
+uint BCMINITFN(sb_boardtype) (sb_t * sbh) {
sb_info_t *si;
char *var;
@@ -1239,7 +1628,8 @@ sb_boardtype(sb_t *sbh)
si->sb.boardtype = getintvar(NULL, "boardtype");
/* backward compatibility for older boardtype string format */
- if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) {
+ if ((si->sb.boardtype == 0)
+ && (var = getvar(NULL, "boardtype"))) {
if (!strcmp(var, "bcm94710dev"))
si->sb.boardtype = BCM94710D_BOARD;
else if (!strcmp(var, "bcm94710ap"))
@@ -1263,8 +1653,7 @@ sb_boardtype(sb_t *sbh)
}
/* return bus type of sbh device */
-uint
-sb_bus(sb_t *sbh)
+uint sb_bus(sb_t * sbh)
{
sb_info_t *si;
@@ -1273,8 +1662,7 @@ sb_bus(sb_t *sbh)
}
/* return bus core type */
-uint
-sb_buscoretype(sb_t *sbh)
+uint sb_buscoretype(sb_t * sbh)
{
sb_info_t *si;
@@ -1284,8 +1672,7 @@ sb_buscoretype(sb_t *sbh)
}
/* return bus core revision */
-uint
-sb_buscorerev(sb_t *sbh)
+uint sb_buscorerev(sb_t * sbh)
{
sb_info_t *si;
si = SB_INFO(sbh);
@@ -1294,20 +1681,19 @@ sb_buscorerev(sb_t *sbh)
}
/* return list of found cores */
-uint
-sb_corelist(sb_t *sbh, uint coreid[])
+uint sb_corelist(sb_t * sbh, uint coreid[])
{
sb_info_t *si;
si = SB_INFO(sbh);
- bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof(uint)));
+ bcopy((uchar *) si->coreid, (uchar *) coreid,
+ (si->numcores * sizeof(uint)));
return (si->numcores);
}
/* return current register mapping */
-void *
-sb_coreregs(sb_t *sbh)
+void *sb_coreregs(sb_t * sbh)
{
sb_info_t *si;
@@ -1317,10 +1703,166 @@ sb_coreregs(sb_t *sbh)
return (si->curmap);
}
+#if defined(BCMDBG_ASSERT)
+/* traverse all cores to find and clear source of serror */
+static void sb_serr_clear(sb_info_t * si)
+{
+ sbconfig_t *sb;
+ uint origidx;
+ uint i, intr_val = 0;
+ void *corereg = NULL;
+
+ INTR_OFF(si, intr_val);
+ origidx = sb_coreidx(&si->sb);
+
+ for (i = 0; i < si->numcores; i++) {
+ corereg = sb_setcoreidx(&si->sb, i);
+ if (NULL != corereg) {
+ sb = REGS2SB(corereg);
+ if ((R_SBREG(si, &sb->sbtmstatehigh)) & SBTMH_SERR) {
+ AND_SBREG(si, &sb->sbtmstatehigh, ~SBTMH_SERR);
+ SB_ERROR(("sb_serr_clear: SError at core 0x%x\n", sb_coreid(&si->sb)));
+ }
+ }
+ }
+
+ sb_setcoreidx(&si->sb, origidx);
+ INTR_RESTORE(si, intr_val);
+}
+
+/*
+ * Check if any inband, outband or timeout errors has happened and clear them.
+ * Must be called with chip clk on !
+ */
+bool sb_taclear(sb_t * sbh)
+{
+ sb_info_t *si;
+ sbconfig_t *sb;
+ uint origidx;
+ uint intr_val = 0;
+ bool rc = FALSE;
+ uint32 inband = 0, serror = 0, timeout = 0;
+ void *corereg = NULL;
+ volatile uint32 imstate, tmstate;
+
+ si = SB_INFO(sbh);
+
+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
+ volatile uint32 stcmd;
+
+ /* inband error is Target abort for PCI */
+ stcmd =
+ OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(uint32));
+ inband = stcmd & PCI_CFG_CMD_STAT_TA;
+ if (inband) {
+#ifdef BCMDBG
+ SB_ERROR(("inband:\n"));
+ sb_viewall((void *)si);
+#endif
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD,
+ sizeof(uint32), stcmd);
+ }
+
+ /* serror */
+ stcmd =
+ OSL_PCI_READ_CONFIG(si->osh, PCI_INT_STATUS,
+ sizeof(uint32));
+ serror = stcmd & PCI_SBIM_STATUS_SERR;
+ if (serror) {
+#ifdef BCMDBG
+ SB_ERROR(("serror:\n"));
+ sb_viewall((void *)si);
+#endif
+ sb_serr_clear(si);
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_STATUS,
+ sizeof(uint32), stcmd);
+ }
+
+ /* timeout */
+ imstate = sb_corereg(sbh, si->sb.buscoreidx,
+ SBCONFIGOFF + OFFSETOF(sbconfig_t,
+ sbimstate), 0, 0);
+ if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) {
+ sb_corereg(sbh, si->sb.buscoreidx,
+ SBCONFIGOFF + OFFSETOF(sbconfig_t,
+ sbimstate), ~0,
+ (imstate & ~(SBIM_IBE | SBIM_TO)));
+ /* inband = imstate & SBIM_IBE; same as TA above */
+ timeout = imstate & SBIM_TO;
+ if (timeout) {
+#ifdef BCMDBG
+ SB_ERROR(("timeout:\n"));
+ sb_viewall((void *)si);
+#endif
+ }
+ }
+
+ if (inband) {
+ /* dump errlog for sonics >= 2.3 */
+ if (si->sb.sonicsrev == SONICS_2_2) ;
+ else {
+ uint32 imerrlog, imerrloga;
+ imerrlog =
+ sb_corereg(sbh, si->sb.buscoreidx,
+ SBIMERRLOG, 0, 0);
+ if (imerrlog & SBTMEL_EC) {
+ imerrloga =
+ sb_corereg(sbh, si->sb.buscoreidx,
+ SBIMERRLOGA, 0, 0);
+ /* clear errlog */
+ sb_corereg(sbh, si->sb.buscoreidx,
+ SBIMERRLOG, ~0, 0);
+ SB_ERROR(("sb_taclear: ImErrLog 0x%x, ImErrLogA 0x%x\n", imerrlog, imerrloga));
+ }
+ }
+ }
+
+ } else if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
+
+ INTR_OFF(si, intr_val);
+ origidx = sb_coreidx(sbh);
+
+ corereg = sb_setcore(sbh, SB_PCMCIA, 0);
+ if (NULL != corereg) {
+ sb = REGS2SB(corereg);
+
+ imstate = R_SBREG(si, &sb->sbimstate);
+ /* handle surprise removal */
+ if ((imstate != 0xffffffff)
+ && (imstate & (SBIM_IBE | SBIM_TO))) {
+ AND_SBREG(si, &sb->sbimstate,
+ ~(SBIM_IBE | SBIM_TO));
+ inband = imstate & SBIM_IBE;
+ timeout = imstate & SBIM_TO;
+ }
+ tmstate = R_SBREG(si, &sb->sbtmstatehigh);
+ if ((tmstate != 0xffffffff)
+ && (tmstate & SBTMH_INT_STATUS)) {
+ if (!inband) {
+ serror = 1;
+ sb_serr_clear(si);
+ }
+ OR_SBREG(si, &sb->sbtmstatelow, SBTML_INT_ACK);
+ AND_SBREG(si, &sb->sbtmstatelow,
+ ~SBTML_INT_ACK);
+ }
+ }
+ sb_setcoreidx(sbh, origidx);
+ INTR_RESTORE(si, intr_val);
+
+ }
+
+ if (inband | timeout | serror) {
+ rc = TRUE;
+ SB_ERROR(("sb_taclear: inband 0x%x, serror 0x%x, timeout 0x%x!\n", inband, serror, timeout));
+ }
+
+ return (rc);
+}
+#endif /* BCMDBG */
/* do buffered registers update */
-void
-sb_commit(sb_t *sbh)
+void sb_commit(sb_t * sbh)
{
sb_info_t *si;
uint origidx;
@@ -1335,13 +1877,14 @@ sb_commit(sb_t *sbh)
/* switch over to chipcommon core if there is one, else use pci */
if (si->sb.ccrev != NOREV) {
- chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0);
+ chipcregs_t *ccregs = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
/* do the buffer registers update */
W_REG(si->osh, &ccregs->broadcastaddress, SB_COMMIT);
W_REG(si->osh, &ccregs->broadcastdata, 0x0);
} else if (PCI(si)) {
- sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
+ sbpciregs_t *pciregs =
+ (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
/* do the buffer registers update */
W_REG(si->osh, &pciregs->bcastaddr, SB_COMMIT);
@@ -1359,8 +1902,7 @@ sb_commit(sb_t *sbh)
* bits - core specific bits that are set during and after reset sequence
* resetbits - core specific bits that are set only during reset sequence
*/
-void
-sb_core_reset(sb_t *sbh, uint32 bits, uint32 resetbits)
+void sb_core_reset(sb_t * sbh, uint32 bits, uint32 resetbits)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -1380,7 +1922,8 @@ sb_core_reset(sb_t *sbh, uint32 bits, uint32 resetbits)
*/
/* set reset while enabling the clock and forcing them on throughout the core */
- W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits | resetbits));
+ W_SBREG(si, &sb->sbtmstatelow,
+ (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits | resetbits));
dummy = R_SBREG(si, &sb->sbtmstatelow);
OSL_DELAY(1);
@@ -1402,8 +1945,7 @@ sb_core_reset(sb_t *sbh, uint32 bits, uint32 resetbits)
OSL_DELAY(1);
}
-void
-sb_core_tofixup(sb_t *sbh)
+void sb_core_tofixup(sb_t * sbh)
{
sb_info_t *si;
sbconfig_t *sb;
@@ -1419,15 +1961,16 @@ sb_core_tofixup(sb_t *sbh)
if (BUSTYPE(si->sb.bustype) == SB_BUS) {
SET_SBREG(si, &sb->sbimconfiglow,
- SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
- (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
+ (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
} else {
if (sb_coreid(sbh) == SB_PCI) {
SET_SBREG(si, &sb->sbimconfiglow,
- SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
- (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
} else {
- SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
+ SET_SBREG(si, &sb->sbimconfiglow,
+ (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
}
}
@@ -1458,11 +2001,10 @@ sb_core_tofixup(sb_t *sbh)
#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK)
-uint32
-sb_set_initiator_to(sb_t *sbh, uint32 to)
+uint32 sb_set_initiator_to(sb_t * sbh, uint32 to, uint idx)
{
sb_info_t *si;
- uint origidx, idx;
+ uint origidx;
uint intr_val = 0;
uint32 tmp, ret = 0xffffffff;
sbconfig_t *sb;
@@ -1473,27 +2015,28 @@ sb_set_initiator_to(sb_t *sbh, uint32 to)
return ret;
/* Figure out the master core */
- idx = BADIDX;
- switch (BUSTYPE(si->sb.bustype)) {
- case PCI_BUS:
- idx = si->sb.buscoreidx;
- break;
- case JTAG_BUS:
- idx = SB_CC_IDX;
- break;
- case PCMCIA_BUS:
- case SDIO_BUS:
- idx = sb_findcoreidx(si, SB_PCMCIA, 0);
- break;
- case SB_BUS:
- if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX)
- idx = sb_findcoreidx(si, SB_MIPS, 0);
- break;
- default:
- ASSERT(0);
+ if (idx == BADIDX) {
+ switch (BUSTYPE(si->sb.bustype)) {
+ case PCI_BUS:
+ idx = si->sb.buscoreidx;
+ break;
+ case JTAG_BUS:
+ idx = SB_CC_IDX;
+ break;
+ case PCMCIA_BUS:
+ case SDIO_BUS:
+ idx = sb_findcoreidx(sbh, SB_PCMCIA, 0);
+ break;
+ case SB_BUS:
+ if ((idx = sb_findcoreidx(sbh, SB_MIPS33, 0)) == BADIDX)
+ idx = sb_findcoreidx(sbh, SB_MIPS, 0);
+ break;
+ default:
+ ASSERT(0);
+ }
+ if (idx == BADIDX)
+ return ret;
}
- if (idx == BADIDX)
- return ret;
INTR_OFF(si, intr_val);
origidx = sb_coreidx(sbh);
@@ -1510,8 +2053,7 @@ sb_set_initiator_to(sb_t *sbh, uint32 to)
return ret;
}
-void
-sb_core_disable(sb_t *sbh, uint32 bits)
+void sb_core_disable(sb_t * sbh, uint32 bits)
{
sb_info_t *si;
volatile uint32 dummy;
@@ -1553,7 +2095,8 @@ sb_core_disable(sb_t *sbh, uint32 bits)
}
/* set reset and reject while enabling the clocks */
- W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET));
+ W_SBREG(si, &sb->sbtmstatelow,
+ (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET));
dummy = R_SBREG(si, &sb->sbtmstatelow);
OSL_DELAY(10);
@@ -1561,50 +2104,43 @@ sb_core_disable(sb_t *sbh, uint32 bits)
if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT)
AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ);
-disable:
+ disable:
/* leave reset and reject asserted */
W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET));
OSL_DELAY(1);
}
/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */
-void
-sb_watchdog(sb_t *sbh, uint ticks)
+void sb_watchdog(sb_t * sbh, uint ticks)
{
sb_info_t *si = SB_INFO(sbh);
- /* make sure we come up in fast clock mode */
- sb_clkctl_clk(sbh, CLK_FAST);
+ /* make sure we come up in fast clock mode; or if clearing, clear clock */
+ if (ticks)
+ sb_clkctl_clk(sbh, CLK_FAST);
+ else
+ sb_clkctl_clk(sbh, CLK_DYNAMIC);
+
+ if (sbh->chip == BCM4328_CHIP_ID && ticks != 0)
+ sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask),
+ PMURES_BIT(RES4328_ROM_SWITCH),
+ PMURES_BIT(RES4328_ROM_SWITCH));
/* instant NMI */
switch (si->gpioid) {
case SB_CC:
-#ifdef __mips__
- if (sb_chip(sbh) == BCM4785_CHIP_ID && ticks <= 1)
- MTC0(C0_BROADCOM, 4, (1 << 22));
-#endif /* __mips__ */
- sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
-#ifdef __mips__
- if (sb_chip(sbh) == BCM4785_CHIP_ID && ticks <= 1) {
- __asm__ __volatile__ (
- ".set\tmips3\n\t"
- "sync\n\t"
- "wait\n\t"
- ".set\tmips0"
- );
- while (1);
- }
-#endif /* __mips__ */
+ sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0,
+ ticks);
break;
case SB_EXTIF:
- sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks);
+ sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog),
+ ~0, ticks);
break;
}
}
/* initialize the pcmcia core */
-void
-sb_pcmcia_init(sb_t *sbh)
+void sb_pcmcia_init(sb_t * sbh)
{
sb_info_t *si;
uint8 cor = 0;
@@ -1618,21 +2154,120 @@ sb_pcmcia_init(sb_t *sbh)
}
+void BCMINITFN(sb_pci_up) (sb_t * sbh) {
+ sb_info_t *si = SB_INFO(sbh);
+ if (si->gpioid == SB_EXTIF)
+ return;
+
+ /* if not pci bus, we're done */
+ if (BUSTYPE(si->sb.bustype) != PCI_BUS)
+ return;
+
+ if (FORCEHT_WAR32414(si))
+ sb_war32414_forceHT(sbh, 1);
+
+ if (PCIE_ASPMWARS(si) || si->sb.pr42780)
+ sb_pcieclkreq(sbh, 1, 0);
+
+ if (PCIE(si) &&
+ (((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev == 2)) ||
+ ((si->sb.chip == BCM4312_CHIP_ID) && (si->sb.chiprev == 0))))
+ sb_set_initiator_to((void *)si, 0x3,
+ sb_findcoreidx((void *)si, SB_D11, 0));
+}
+
+/* Unconfigure and/or apply various WARs when system is going to sleep mode */
+void BCMUNINITFN(sb_pci_sleep) (sb_t * sbh) {
+ sb_info_t *si = SB_INFO(sbh);
+ if (si->gpioid == SB_EXTIF)
+ return;
+ uint32 w;
+
+ /* if not pci bus, we're done */
+ if (!PCIE(si) || !PCIE_ASPMWARS(si))
+ return;
+
+ w = OSL_PCI_READ_CONFIG(si->osh, si->pciecap_lcreg_offset,
+ sizeof(uint32));
+ w &= ~PCIE_CAP_LCREG_ASPML1;
+ OSL_PCI_WRITE_CONFIG(si->osh, si->pciecap_lcreg_offset, sizeof(uint32),
+ w);
+}
+
+/* Unconfigure and/or apply various WARs when going down */
+void BCMINITFN(sb_pci_down) (sb_t * sbh) {
+ sb_info_t *si = SB_INFO(sbh);
+ if (si->gpioid == SB_EXTIF)
+ return;
+
+ /* if not pci bus, we're done */
+ if (BUSTYPE(si->sb.bustype) != PCI_BUS)
+ return;
+
+ if (FORCEHT_WAR32414(si))
+ sb_war32414_forceHT(sbh, 0);
+
+ if (si->pr42767_war) {
+ sb_pcieclkreq(sbh, 1, 1);
+ si->pr42767_war = FALSE;
+ } else if (si->sb.pr42780) {
+ sb_pcieclkreq(sbh, 1, 1);
+ }
+}
+
+static void BCMINITFN(sb_war42767_clkreq) (sb_t * sbh) {
+ sbpcieregs_t *pcieregs;
+ uint16 val16, *reg16;
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
+
+ /* if not pcie bus, we're done */
+ if (!PCIE(si) || !PCIE_ASPMWARS(si))
+ return;
+
+ pcieregs = (sbpcieregs_t *) sb_setcoreidx(sbh, si->sb.buscoreidx);
+ reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET];
+ val16 = R_REG(si->osh, reg16);
+ /* if clockreq is not advertized advertize it */
+ if (!si->pcie_war_ovr) {
+ val16 |= SRSH_CLKREQ_ENB;
+ si->pr42767_war = TRUE;
+
+ si->sb.pr42780 = TRUE;
+ } else
+ val16 &= ~SRSH_CLKREQ_ENB;
+ W_REG(si->osh, reg16, val16);
+}
+
+static void BCMINITFN(sb_war42767) (sb_t * sbh) {
+ uint32 w = 0;
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
+
+ /* if not pcie bus, we're done */
+ if (!PCIE(si) || !PCIE_ASPMWARS(si))
+ return;
+
+ sb_pcie_mdioread(si, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
+ if (w & PLL_CTRL_FREQDET_EN) {
+ w &= ~PLL_CTRL_FREQDET_EN;
+ sb_pcie_mdiowrite(si, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
+ }
+}
/*
* Configure the pci core for pci client (NIC) action
* coremask is the bitvec of cores by index to be enabled.
*/
-void
-BCMINITFN(sb_pci_setup)(sb_t *sbh, uint coremask)
-{
+void BCMINITFN(sb_pci_setup) (sb_t * sbh, uint coremask) {
sb_info_t *si;
sbconfig_t *sb;
sbpciregs_t *pciregs;
uint32 sbflag;
uint32 w;
uint idx;
- int reg_val;
si = SB_INFO(sbh);
@@ -1652,7 +2287,7 @@ BCMINITFN(sb_pci_setup)(sb_t *sbh, uint coremask)
sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
/* switch over to pci core */
- pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx);
+ pciregs = (sbpciregs_t *) sb_setcoreidx(sbh, si->sb.buscoreidx);
sb = REGS2SB(pciregs);
/*
@@ -1670,45 +2305,69 @@ BCMINITFN(sb_pci_setup)(sb_t *sbh, uint coremask)
}
if (PCI(si)) {
- OR_REG(si->osh, &pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST));
+ OR_REG(si->osh, &pciregs->sbtopci2,
+ (SBTOPCI_PREF | SBTOPCI_BURST));
if (si->sb.buscorerev >= 11)
- OR_REG(si->osh, &pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
+ OR_REG(si->osh, &pciregs->sbtopci2,
+ SBTOPCI_RC_READMULTI);
if (si->sb.buscorerev < 5) {
- SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
- (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
+ SET_SBREG(si, &sb->sbimconfiglow,
+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
sb_commit(sbh);
}
}
-#ifdef PCIE_SUPPOER
/* PCIE workarounds */
if (PCIE(si)) {
if ((si->sb.buscorerev == 0) || (si->sb.buscorerev == 1)) {
- reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS,
- PCIE_TLP_WORKAROUNDSREG);
- reg_val |= 0x8;
- sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS,
- PCIE_TLP_WORKAROUNDSREG, reg_val);
+ w = sb_pcie_readreg((void *)(uintptr) sbh,
+ (void *)(uintptr) PCIE_PCIEREGS,
+ PCIE_TLP_WORKAROUNDSREG);
+ w |= 0x8;
+ sb_pcie_writereg((void *)(uintptr) sbh,
+ (void *)(uintptr) PCIE_PCIEREGS,
+ PCIE_TLP_WORKAROUNDSREG, w);
}
if (si->sb.buscorerev == 1) {
- reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS,
- PCIE_DLLP_LCREG);
- reg_val |= (0x40);
- sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val);
+ w = sb_pcie_readreg((void *)(uintptr) sbh,
+ (void *)(uintptr) PCIE_PCIEREGS,
+ PCIE_DLLP_LCREG);
+ w |= (0x40);
+ sb_pcie_writereg((void *)(uintptr) sbh,
+ (void *)(uintptr) PCIE_PCIEREGS,
+ PCIE_DLLP_LCREG, w);
}
if (si->sb.buscorerev == 0)
sb_war30841(si);
+
+ if ((si->sb.buscorerev >= 3) && (si->sb.buscorerev <= 5)) {
+ w = sb_pcie_readreg((void *)(uintptr) sbh,
+ (void *)(uintptr) PCIE_PCIEREGS,
+ PCIE_DLLP_PMTHRESHREG);
+ w &= ~(PCIE_L1THRESHOLDTIME_MASK);
+ w |= (PCIE_L1THRESHOLD_WARVAL <<
+ PCIE_L1THRESHOLDTIME_SHIFT);
+ sb_pcie_writereg((void *)(uintptr) sbh,
+ (void *)(uintptr) PCIE_PCIEREGS,
+ PCIE_DLLP_PMTHRESHREG, w);
+
+ sb_war43448(sbh);
+
+ sb_war42767(sbh);
+
+ sb_war43448_aspm(sbh);
+ sb_war42767_clkreq(sbh);
+ }
}
-#endif
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
}
-uint32
-sb_base(uint32 admatch)
+uint32 sb_base(uint32 admatch)
{
uint32 base;
uint type;
@@ -1731,8 +2390,7 @@ sb_base(uint32 admatch)
return (base);
}
-uint32
-sb_size(uint32 admatch)
+uint32 sb_size(uint32 admatch)
{
uint32 size;
uint type;
@@ -1743,21 +2401,26 @@ sb_size(uint32 admatch)
size = 0;
if (type == 0) {
- size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1);
+ size =
+ 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) +
+ 1);
} else if (type == 1) {
ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
- size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1);
+ size =
+ 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) +
+ 1);
} else if (type == 2) {
ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
- size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1);
+ size =
+ 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) +
+ 1);
}
return (size);
}
/* return the core-type instantiation # of the current core */
-uint
-sb_coreunit(sb_t *sbh)
+uint sb_coreunit(sb_t * sbh)
{
sb_info_t *si;
uint idx;
@@ -1781,24 +2444,27 @@ sb_coreunit(sb_t *sbh)
return (coreunit);
}
-static INLINE uint32
-factor6(uint32 x)
-{
+static uint32 BCMINITFN(factor6) (uint32 x) {
switch (x) {
- case CC_F6_2: return 2;
- case CC_F6_3: return 3;
- case CC_F6_4: return 4;
- case CC_F6_5: return 5;
- case CC_F6_6: return 6;
- case CC_F6_7: return 7;
- default: return 0;
+ case CC_F6_2:
+ return 2;
+ case CC_F6_3:
+ return 3;
+ case CC_F6_4:
+ return 4;
+ case CC_F6_5:
+ return 5;
+ case CC_F6_6:
+ return 6;
+ case CC_F6_7:
+ return 7;
+ default:
+ return 0;
}
}
/* calculate the speed the SB would run at given a set of clockcontrol values */
-uint32
-sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
-{
+uint32 BCMINITFN(sb_clock_rate) (uint32 pll_type, uint32 n, uint32 m) {
uint32 n1, n2, clock, m1, m2, m3, mc;
n1 = n & CN_N1_MASK;
@@ -1810,9 +2476,8 @@ sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
else
return CC_T6_M0;
} else if ((pll_type == PLL_TYPE1) ||
- (pll_type == PLL_TYPE3) ||
- (pll_type == PLL_TYPE4) ||
- (pll_type == PLL_TYPE7)) {
+ (pll_type == PLL_TYPE3) ||
+ (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
n1 = factor6(n1);
n2 += CC_F5_BIAS;
} else if (pll_type == PLL_TYPE2) {
@@ -1825,9 +2490,8 @@ sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
} else
ASSERT(0);
/* PLL types 3 and 7 use BASE2 (25Mhz) */
- if ((pll_type == PLL_TYPE3) ||
- (pll_type == PLL_TYPE7)) {
- clock = CC_CLOCK_BASE2 * n1 * n2;
+ if ((pll_type == PLL_TYPE3) || (pll_type == PLL_TYPE7)) {
+ clock = CC_CLOCK_BASE2 * n1 * n2;
} else
clock = CC_CLOCK_BASE1 * n1 * n2;
@@ -1841,8 +2505,7 @@ sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
if ((pll_type == PLL_TYPE1) ||
(pll_type == PLL_TYPE3) ||
- (pll_type == PLL_TYPE4) ||
- (pll_type == PLL_TYPE7)) {
+ (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
m1 = factor6(m1);
if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
m2 += CC_F5_BIAS;
@@ -1851,12 +2514,18 @@ sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
m3 = factor6(m3);
switch (mc) {
- case CC_MC_BYPASS: return (clock);
- case CC_MC_M1: return (clock / m1);
- case CC_MC_M1M2: return (clock / (m1 * m2));
- case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3));
- case CC_MC_M1M3: return (clock / (m1 * m3));
- default: return (0);
+ case CC_MC_BYPASS:
+ return (clock);
+ case CC_MC_M1:
+ return (clock / m1);
+ case CC_MC_M1M2:
+ return (clock / (m1 * m2));
+ case CC_MC_M1M2M3:
+ return (clock / (m1 * m2 * m3));
+ case CC_MC_M1M3:
+ return (clock / (m1 * m3));
+ default:
+ return (0);
}
} else {
ASSERT(pll_type == PLL_TYPE2);
@@ -1880,15 +2549,13 @@ sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
}
/* returns the current speed the SB is running at */
-uint32
-sb_clock(sb_t *sbh)
-{
+uint32 BCMINITFN(sb_clock) (sb_t * sbh) {
sb_info_t *si;
extifregs_t *eir;
chipcregs_t *cc;
uint32 n, m;
uint idx;
- uint32 pll_type, rate;
+ uint32 cap, pll_type, rate;
uint intr_val = 0;
si = SB_INFO(sbh);
@@ -1902,7 +2569,24 @@ sb_clock(sb_t *sbh)
n = R_REG(si->osh, &eir->clockcontrol_n);
m = R_REG(si->osh, &eir->clockcontrol_sb);
} else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
- pll_type = R_REG(si->osh, &cc->capabilities) & CAP_PLL_MASK;
+
+ cap = R_REG(si->osh, &cc->capabilities);
+
+ if (cap & CC_CAP_PMU) {
+
+ if (sb_chip(sbh) == BCM5354_CHIP_ID) {
+ /* 5354 has a constant sb clock of 120MHz */
+ rate = 120000000;
+ goto end;
+ } else
+ if (sb_chip(sbh) == BCM4328_CHIP_ID) {
+ rate = 80000000;
+ goto end;
+ } else
+ ASSERT(0);
+ }
+
+ pll_type = cap & CC_CAP_PLL_MASK;
if (pll_type == PLL_NONE) {
INTR_RESTORE(si, intr_val);
return 80000000;
@@ -1910,7 +2594,8 @@ sb_clock(sb_t *sbh)
n = R_REG(si->osh, &cc->clockcontrol_n);
if (pll_type == PLL_TYPE6)
m = R_REG(si->osh, &cc->clockcontrol_m3);
- else if ((pll_type == PLL_TYPE3) && !(BCMINIT(sb_chip)(sbh) == 0x5365))
+ else if (pll_type == PLL_TYPE3
+ && !(BCMINIT(sb_chip) (sbh) == 0x5365))
m = R_REG(si->osh, &cc->clockcontrol_m2);
else
m = R_REG(si->osh, &cc->clockcontrol_sb);
@@ -1920,7 +2605,7 @@ sb_clock(sb_t *sbh)
}
/* calculate rate */
- if (BCMINIT(sb_chip)(sbh) == 0x5365)
+ if (BCMINIT(sb_chip) (sbh) == 0x5365)
rate = 100000000;
else {
rate = sb_clock_rate(pll_type, n, m);
@@ -1929,6 +2614,7 @@ sb_clock(sb_t *sbh)
rate = rate / 2;
}
+ end:
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
@@ -1937,9 +2623,17 @@ sb_clock(sb_t *sbh)
return rate;
}
+uint32 BCMINITFN(sb_alp_clock) (sb_t * sbh) {
+ uint32 clock = ALP_CLOCK;
+
+ if (sbh->cccaps & CC_CAP_PMU)
+ clock = sb_pmu_alp_clock(sbh, sb_osh(sbh));
+
+ return clock;
+}
+
/* change logical "focus" to the gpio core for optimized access */
-void*
-sb_gpiosetcore(sb_t *sbh)
+void *sb_gpiosetcore(sb_t * sbh)
{
sb_info_t *si;
@@ -1949,8 +2643,7 @@ sb_gpiosetcore(sb_t *sbh)
}
/* mask&set gpiocontrol bits */
-uint32
-sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
+uint32 sb_gpiocontrol(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
{
sb_info_t *si;
uint regoff;
@@ -1958,12 +2651,13 @@ sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
si = SB_INFO(sbh);
regoff = 0;
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
- /* gpios could be shared on router platforms */
- if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
mask = priority ? (sb_gpioreservation & mask) :
- ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
val &= mask;
}
@@ -1980,12 +2674,11 @@ sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
return (0);
}
- return (sb_corereg(si, si->gpioidx, regoff, mask, val));
+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
}
/* mask&set gpio output enable bits */
-uint32
-sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
+uint32 sb_gpioouten(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
{
sb_info_t *si;
uint regoff;
@@ -1993,12 +2686,13 @@ sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
si = SB_INFO(sbh);
regoff = 0;
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
- /* gpios could be shared on router platforms */
- if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
mask = priority ? (sb_gpioreservation & mask) :
- ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
val &= mask;
}
@@ -2016,12 +2710,11 @@ sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
break;
}
- return (sb_corereg(si, si->gpioidx, regoff, mask, val));
+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
}
/* mask&set gpio output bits */
-uint32
-sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
+uint32 sb_gpioout(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
{
sb_info_t *si;
uint regoff;
@@ -2029,12 +2722,13 @@ sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
si = SB_INFO(sbh);
regoff = 0;
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
- /* gpios could be shared on router platforms */
- if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
+ /* gpios could be shared on router platforms
+ * ignore reservation if it's high priority (e.g., test apps)
+ */
+ if ((priority != GPIO_HI_PRIORITY) &&
+ (BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
mask = priority ? (sb_gpioreservation & mask) :
- ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
val &= mask;
}
@@ -2052,29 +2746,27 @@ sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
break;
}
- return (sb_corereg(si, si->gpioidx, regoff, mask, val));
+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
}
/* reserve one gpio */
-uint32
-sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
+uint32 sb_gpioreserve(sb_t * sbh, uint32 gpio_bitmask, uint8 priority)
{
sb_info_t *si;
si = SB_INFO(sbh);
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
/* only cores on SB_BUS share GPIO's and only applcation users need to
* reserve/release GPIO
*/
- if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
+ if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
return -1;
}
/* make sure only one bit is set */
if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
- ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
+ ASSERT((gpio_bitmask)
+ && !((gpio_bitmask) & (gpio_bitmask - 1)));
return -1;
}
@@ -2093,25 +2785,23 @@ sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
* persists till some one overwrites it
*/
-uint32
-sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
+uint32 sb_gpiorelease(sb_t * sbh, uint32 gpio_bitmask, uint8 priority)
{
sb_info_t *si;
si = SB_INFO(sbh);
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
/* only cores on SB_BUS share GPIO's and only applcation users need to
* reserve/release GPIO
*/
- if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
+ if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
return -1;
}
/* make sure only one bit is set */
if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
- ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
+ ASSERT((gpio_bitmask)
+ && !((gpio_bitmask) & (gpio_bitmask - 1)));
return -1;
}
@@ -2126,8 +2816,7 @@ sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
}
/* return the current gpioin register value */
-uint32
-sb_gpioin(sb_t *sbh)
+uint32 sb_gpioin(sb_t * sbh)
{
sb_info_t *si;
uint regoff;
@@ -2149,12 +2838,11 @@ sb_gpioin(sb_t *sbh)
break;
}
- return (sb_corereg(si, si->gpioidx, regoff, 0, 0));
+ return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0));
}
/* mask&set gpio interrupt polarity bits */
-uint32
-sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
+uint32 sb_gpiointpolarity(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
{
sb_info_t *si;
uint regoff;
@@ -2162,12 +2850,10 @@ sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
si = SB_INFO(sbh);
regoff = 0;
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
/* gpios could be shared on router platforms */
if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
mask = priority ? (sb_gpioreservation & mask) :
- ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
val &= mask;
}
@@ -2186,12 +2872,11 @@ sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
break;
}
- return (sb_corereg(si, si->gpioidx, regoff, mask, val));
+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
}
/* mask&set gpio interrupt mask bits */
-uint32
-sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
+uint32 sb_gpiointmask(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
{
sb_info_t *si;
uint regoff;
@@ -2199,12 +2884,10 @@ sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
si = SB_INFO(sbh);
regoff = 0;
- priority = GPIO_DRV_PRIORITY; /* compatibility hack */
-
/* gpios could be shared on router platforms */
if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
mask = priority ? (sb_gpioreservation & mask) :
- ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
val &= mask;
}
@@ -2223,12 +2906,11 @@ sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
break;
}
- return (sb_corereg(si, si->gpioidx, regoff, mask, val));
+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
}
/* assign the gpio to an led */
-uint32
-sb_gpioled(sb_t *sbh, uint32 mask, uint32 val)
+uint32 sb_gpioled(sb_t * sbh, uint32 mask, uint32 val)
{
sb_info_t *si;
@@ -2237,12 +2919,13 @@ sb_gpioled(sb_t *sbh, uint32 mask, uint32 val)
return -1;
/* gpio led powersave reg */
- return (sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
+ return (sb_corereg
+ (sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask,
+ val));
}
-/* mask & set gpio timer val */
-uint32
-sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval)
+/* mask&set gpio timer val */
+uint32 sb_gpiotimerval(sb_t * sbh, uint32 mask, uint32 gpiotimerval)
{
sb_info_t *si;
si = SB_INFO(sbh);
@@ -2250,78 +2933,318 @@ sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval)
if (si->sb.ccrev < 16)
return -1;
- return (sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
+ return (sb_corereg(sbh, SB_CC_IDX,
+ OFFSETOF(chipcregs_t, gpiotimerval), mask,
+ gpiotimerval));
+}
+
+uint32 sb_gpiopull(sb_t * sbh, bool updown, uint32 mask, uint32 val)
+{
+ sb_info_t *si;
+ uint offs;
+
+ si = SB_INFO(sbh);
+ if (si->sb.ccrev < 20)
+ return -1;
+
+ offs =
+ (updown ? OFFSETOF(chipcregs_t, gpiopulldown) :
+ OFFSETOF(chipcregs_t, gpiopullup));
+ return (sb_corereg(sbh, SB_CC_IDX, offs, mask, val));
+}
+
+uint32 sb_gpioevent(sb_t * sbh, uint regtype, uint32 mask, uint32 val)
+{
+ sb_info_t *si;
+ uint offs;
+
+ si = SB_INFO(sbh);
+ if (si->sb.ccrev < 11)
+ return -1;
+
+ if (regtype == GPIO_REGEVT)
+ offs = OFFSETOF(chipcregs_t, gpioevent);
+ else if (regtype == GPIO_REGEVT_INTMSK)
+ offs = OFFSETOF(chipcregs_t, gpioeventintmask);
+ else if (regtype == GPIO_REGEVT_INTPOL)
+ offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
+ else
+ return -1;
+
+ return (sb_corereg(sbh, SB_CC_IDX, offs, mask, val));
+}
+
+void *BCMINITFN(sb_gpio_handler_register) (sb_t * sbh, uint32 event,
+ bool level, gpio_handler_t cb,
+ void *arg) {
+ sb_info_t *si;
+ gpioh_item_t *gi;
+
+ ASSERT(event);
+ ASSERT(cb);
+
+ si = SB_INFO(sbh);
+ if (si->sb.ccrev < 11)
+ return NULL;
+
+ if ((gi = MALLOC(si->osh, sizeof(gpioh_item_t))) == NULL)
+ return NULL;
+
+ bzero(gi, sizeof(gpioh_item_t));
+ gi->event = event;
+ gi->handler = cb;
+ gi->arg = arg;
+ gi->level = level;
+
+ gi->next = si->gpioh_head;
+ si->gpioh_head = gi;
+
+ return (void *)(gi);
+}
+
+void BCMINITFN(sb_gpio_handler_unregister) (sb_t * sbh, void *gpioh) {
+ sb_info_t *si;
+ gpioh_item_t *p, *n;
+
+ si = SB_INFO(sbh);
+ if (si->sb.ccrev < 11)
+ return;
+
+ ASSERT(si->gpioh_head);
+ if ((void *)si->gpioh_head == gpioh) {
+ si->gpioh_head = si->gpioh_head->next;
+ MFREE(si->osh, gpioh, sizeof(gpioh_item_t));
+ return;
+ } else {
+ p = si->gpioh_head;
+ n = p->next;
+ while (n) {
+ if ((void *)n == gpioh) {
+ p->next = n->next;
+ MFREE(si->osh, gpioh, sizeof(gpioh_item_t));
+ return;
+ }
+ p = n;
+ n = n->next;
+ }
+ }
+
+ ASSERT(0); /* Not found in list */
+}
+
+void sb_gpio_handler_process(sb_t * sbh)
+{
+ sb_info_t *si;
+ gpioh_item_t *h;
+ uint32 status;
+ uint32 level = sb_gpioin(sbh);
+ uint32 edge = sb_gpioevent(sbh, GPIO_REGEVT, 0, 0);
+
+ si = SB_INFO(sbh);
+ for (h = si->gpioh_head; h != NULL; h = h->next) {
+ if (h->handler) {
+ status = (h->level ? level : edge);
+
+ if (status & h->event)
+ h->handler(status, h->arg);
+ }
+ }
+
+ sb_gpioevent(sbh, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
+}
+
+uint32 sb_gpio_int_enable(sb_t * sbh, bool enable)
+{
+ sb_info_t *si;
+ uint offs;
+
+ si = SB_INFO(sbh);
+ if (si->sb.ccrev < 11)
+ return -1;
+
+ offs = OFFSETOF(chipcregs_t, intmask);
+ return (sb_corereg
+ (sbh, SB_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
}
+#ifdef BCMDBG
+void sb_dump(sb_t * sbh, struct bcmstrbuf *b)
+{
+ sb_info_t *si;
+ uint i;
+
+ si = SB_INFO(sbh);
+
+ bcm_bprintf(b,
+ "si %p chip 0x%x chiprev 0x%x boardtype 0x%x boardvendor 0x%x bus %d\n",
+ si, si->sb.chip, si->sb.chiprev, si->sb.boardtype,
+ si->sb.boardvendor, si->sb.bustype);
+ bcm_bprintf(b, "osh %p curmap %p\n", si->osh, si->curmap);
+ bcm_bprintf(b,
+ "sonicsrev %d ccrev %d buscoretype 0x%x buscorerev %d curidx %d\n",
+ si->sb.sonicsrev, si->sb.ccrev, si->sb.buscoretype,
+ si->sb.buscorerev, si->curidx);
+
+ bcm_bprintf(b, "forceHT %d ASPM overflowPR42780 %d pcie_polarity %d\n",
+ si->sb.pr32414, si->sb.pr42780, si->pcie_polarity);
+
+ bcm_bprintf(b, "cores: ");
+ for (i = 0; i < si->numcores; i++)
+ bcm_bprintf(b, "0x%x ", si->coreid[i]);
+ bcm_bprintf(b, "\n");
+}
+
+/* print interesting sbconfig registers */
+void sb_dumpregs(sb_t * sbh, struct bcmstrbuf *b)
+{
+ sb_info_t *si;
+ sbconfig_t *sb;
+ uint origidx;
+ uint curidx, i, intr_val = 0;
+
+ si = SB_INFO(sbh);
+ origidx = si->curidx;
+
+ INTR_OFF(si, intr_val);
+ curidx = si->curidx;
+
+ for (i = 0; i < si->numcores; i++) {
+ sb = REGS2SB(sb_setcoreidx(sbh, i));
+
+ bcm_bprintf(b, "core 0x%x: \n", si->coreid[i]);
+ bcm_bprintf(b,
+ "sbtmstatelow 0x%x sbtmstatehigh 0x%x sbidhigh 0x%x "
+ "sbimstate 0x%x\n sbimconfiglow 0x%x sbimconfighigh 0x%x\n",
+ R_SBREG(si, &sb->sbtmstatelow), R_SBREG(si,
+ &sb->
+ sbtmstatehigh),
+ R_SBREG(si, &sb->sbidhigh), R_SBREG(si,
+ &sb->sbimstate),
+ R_SBREG(si, &sb->sbimconfiglow), R_SBREG(si,
+ &sb->
+ sbimconfighigh));
+ }
+
+ sb_setcoreidx(sbh, origidx);
+ INTR_RESTORE(si, intr_val);
+}
+
+void sb_view(sb_t * sbh)
+{
+ sb_info_t *si;
+ sbconfig_t *sb;
+
+ si = SB_INFO(sbh);
+ sb = REGS2SB(si->curmap);
+
+ if (si->sb.sonicsrev > SONICS_2_2)
+ SB_ERROR(("sbimerrlog 0x%x sbimerrloga 0x%x\n",
+ sb_corereg(sbh, sb_coreidx(&si->sb), SBIMERRLOG, 0,
+ 0), sb_corereg(sbh, sb_coreidx(&si->sb),
+ SBIMERRLOGA, 0, 0)));
+
+ SB_ERROR(("sbipsflag 0x%x sbtpsflag 0x%x sbtmerrloga 0x%x sbtmerrlog 0x%x\n", R_SBREG(si, &sb->sbipsflag), R_SBREG(si, &sb->sbtpsflag), R_SBREG(si, &sb->sbtmerrloga), R_SBREG(si, &sb->sbtmerrlog)));
+ SB_ERROR(("sbadmatch3 0x%x sbadmatch2 0x%x sbadmatch1 0x%x\n",
+ R_SBREG(si, &sb->sbadmatch3), R_SBREG(si, &sb->sbadmatch2),
+ R_SBREG(si, &sb->sbadmatch1)));
+ SB_ERROR(("sbimstate 0x%x sbintvec 0x%x sbtmstatelow 0x%x sbtmstatehigh 0x%x\n", R_SBREG(si, &sb->sbimstate), R_SBREG(si, &sb->sbintvec), R_SBREG(si, &sb->sbtmstatelow), R_SBREG(si, &sb->sbtmstatehigh)));
+ SB_ERROR(("sbbwa0 0x%x sbimconfiglow 0x%x sbimconfighigh 0x%x sbadmatch0 0x%x\n", R_SBREG(si, &sb->sbbwa0), R_SBREG(si, &sb->sbimconfiglow), R_SBREG(si, &sb->sbimconfighigh), R_SBREG(si, &sb->sbadmatch0)));
+ SB_ERROR(("sbtmconfiglow 0x%x sbtmconfighigh 0x%x sbbconfig 0x%x sbbstate 0x%x\n", R_SBREG(si, &sb->sbtmconfiglow), R_SBREG(si, &sb->sbtmconfighigh), R_SBREG(si, &sb->sbbconfig), R_SBREG(si, &sb->sbbstate)));
+ SB_ERROR(("sbactcnfg 0x%x sbflagst 0x%x sbidlow 0x%x sbidhigh 0x%x\n",
+ R_SBREG(si, &sb->sbactcnfg), R_SBREG(si, &sb->sbflagst),
+ R_SBREG(si, &sb->sbidlow), R_SBREG(si, &sb->sbidhigh)));
+}
+
+void sb_viewall(sb_t * sbh)
+{
+ sb_info_t *si;
+ uint curidx, i;
+ uint intr_val = 0;
+
+ si = SB_INFO(sbh);
+ curidx = si->curidx;
+
+ for (i = 0; i < si->numcores; i++) {
+ INTR_OFF(si, intr_val);
+ sb_setcoreidx(sbh, i);
+ sb_view(sbh);
+ INTR_RESTORE(si, intr_val);
+ }
+
+ sb_setcoreidx(sbh, curidx);
+}
+#endif /* BCMDBG */
/* return the slow clock source - LPO, XTAL, or PCI */
-static uint
-sb_slowclk_src(sb_info_t *si)
+static uint sb_slowclk_src(sb_info_t * si)
{
chipcregs_t *cc;
-
ASSERT(sb_coreid(&si->sb) == SB_CC);
if (si->sb.ccrev < 6) {
if ((BUSTYPE(si->sb.bustype) == PCI_BUS) &&
- (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32)) &
- PCI_CFG_GPIO_SCS))
+ (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32))
+ & PCI_CFG_GPIO_SCS))
return (SCC_SS_PCI);
else
return (SCC_SS_XTAL);
} else if (si->sb.ccrev < 10) {
- cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx);
+ cc = (chipcregs_t *) sb_setcoreidx(&si->sb, si->curidx);
return (R_REG(si->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
- } else /* Insta-clock */
+ } else /* Insta-clock */
return (SCC_SS_XTAL);
}
/* return the ILP (slowclock) min or max frequency */
-static uint
-sb_slowclk_freq(sb_info_t *si, bool max)
+static uint sb_slowclk_freq(sb_info_t * si, bool max_freq)
{
chipcregs_t *cc;
uint32 slowclk;
uint div;
-
ASSERT(sb_coreid(&si->sb) == SB_CC);
- cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx);
+ cc = (chipcregs_t *) sb_setcoreidx(&si->sb, si->curidx);
/* shouldn't be here unless we've established the chip has dynamic clk control */
- ASSERT(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL);
+ ASSERT(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
slowclk = sb_slowclk_src(si);
if (si->sb.ccrev < 6) {
if (slowclk == SCC_SS_PCI)
- return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64));
+ return (max_freq ? (PCIMAXFREQ / 64)
+ : (PCIMINFREQ / 64));
else
- return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32));
+ return (max_freq ? (XTALMAXFREQ / 32)
+ : (XTALMINFREQ / 32));
} else if (si->sb.ccrev < 10) {
- div = 4 * (((R_REG(si->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
+ div =
+ 4 *
+ (((R_REG(si->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >>
+ SCC_CD_SHIFT)
+ + 1);
if (slowclk == SCC_SS_LPO)
- return (max? LPOMAXFREQ : LPOMINFREQ);
+ return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
else if (slowclk == SCC_SS_XTAL)
- return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div));
+ return (max_freq ? (XTALMAXFREQ / div)
+ : (XTALMINFREQ / div));
else if (slowclk == SCC_SS_PCI)
- return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div));
+ return (max_freq ? (PCIMAXFREQ / div)
+ : (PCIMINFREQ / div));
else
ASSERT(0);
} else {
/* Chipc rev 10 is InstaClock */
div = R_REG(si->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
div = 4 * (div + 1);
- return (max ? XTALMAXFREQ : (XTALMINFREQ/div));
+ return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
}
return (0);
}
-static void
-BCMINITFN(sb_clkctl_setdelay)(sb_info_t *si, void *chipcregs)
-{
- chipcregs_t * cc;
+static void BCMINITFN(sb_clkctl_setdelay) (sb_info_t * si, void *chipcregs) {
+ chipcregs_t *cc;
uint slowmaxfreq, pll_delay, slowclk;
uint pll_on_delay, fref_sel_delay;
@@ -2341,15 +3264,13 @@ BCMINITFN(sb_clkctl_setdelay)(sb_info_t *si, void *chipcregs)
pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
- cc = (chipcregs_t *)chipcregs;
+ cc = (chipcregs_t *) chipcregs;
W_REG(si->osh, &cc->pll_on_delay, pll_on_delay);
W_REG(si->osh, &cc->fref_sel_delay, fref_sel_delay);
}
/* initialize power control delay registers */
-void
-BCMINITFN(sb_clkctl_init)(sb_t *sbh)
-{
+void BCMINITFN(sb_clkctl_init) (sb_t * sbh) {
sb_info_t *si;
uint origidx;
chipcregs_t *cc;
@@ -2358,31 +3279,30 @@ BCMINITFN(sb_clkctl_init)(sb_t *sbh)
origidx = si->curidx;
- if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
+ if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0)) == NULL)
return;
if ((si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev < 2))
W_REG(si->osh, &cc->chipcontrol,
- (si->sb.chiprev == 0) ? CHIPCTRL_4321A0_DEFAULT : CHIPCTRL_4321A1_DEFAULT);
+ (si->sb.chiprev ==
+ 0) ? CHIPCTRL_4321A0_DEFAULT : CHIPCTRL_4321A1_DEFAULT);
- if (!(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL))
+ if (!(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL))
goto done;
/* set all Instaclk chip ILP to 1 MHz */
- else if (si->sb.ccrev >= 10)
+ if (si->sb.ccrev >= 10)
SET_REG(si->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
- (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+ (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
- sb_clkctl_setdelay(si, (void *)cc);
+ sb_clkctl_setdelay(si, (void *)(uintptr) cc);
-done:
+ done:
sb_setcoreidx(sbh, origidx);
}
/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
-uint16
-sb_clkctl_fast_pwrup_delay(sb_t *sbh)
-{
+uint16 BCMINITFN(sb_clkctl_fast_pwrup_delay) (sb_t * sbh) {
sb_info_t *si;
uint origidx;
chipcregs_t *cc;
@@ -2396,25 +3316,29 @@ sb_clkctl_fast_pwrup_delay(sb_t *sbh)
INTR_OFF(si, intr_val);
- if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
+ if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0)) == NULL)
goto done;
- if (!(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL))
+ if (sbh->cccaps & CC_CAP_PMU) {
+ fpdelay = sb_pmu_fast_pwrup_delay(sbh, si->osh);
+ goto done;
+ }
+
+ if (!(sbh->cccaps & CC_CAP_PWR_CTL))
goto done;
slowminfreq = sb_slowclk_freq(si, FALSE);
fpdelay = (((R_REG(si->osh, &cc->pll_on_delay) + 2) * 1000000) +
- (slowminfreq - 1)) / slowminfreq;
+ (slowminfreq - 1)) / slowminfreq;
-done:
+ done:
sb_setcoreidx(sbh, origidx);
INTR_RESTORE(si, intr_val);
return (fpdelay);
}
/* turn primary xtal and/or pll off/on */
-int
-sb_clkctl_xtal(sb_t *sbh, uint what, bool on)
+int sb_clkctl_xtal(sb_t * sbh, uint what, bool on)
{
sb_info_t *si;
uint32 in, out, outen;
@@ -2423,66 +3347,68 @@ sb_clkctl_xtal(sb_t *sbh, uint what, bool on)
switch (BUSTYPE(si->sb.bustype)) {
+ case PCMCIA_BUS:
+ return (0);
- case PCMCIA_BUS:
- return (0);
-
-
- case PCI_BUS:
+ case PCI_BUS:
- /* pcie core doesn't have any mapping to control the xtal pu */
- if (PCIE(si))
- return -1;
+ /* pcie core doesn't have any mapping to control the xtal pu */
+ if (PCIE(si))
+ return -1;
- in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof(uint32));
- out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32));
- outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof(uint32));
+ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof(uint32));
+ out =
+ OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32));
+ outen =
+ OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32));
- /*
- * Avoid glitching the clock if GPRS is already using it.
- * We can't actually read the state of the PLLPD so we infer it
- * by the value of XTAL_PU which *is* readable via gpioin.
- */
- if (on && (in & PCI_CFG_GPIO_XTAL))
- return (0);
+ /*
+ * Avoid glitching the clock if GPRS is already using it.
+ * We can't actually read the state of the PLLPD so we infer it
+ * by the value of XTAL_PU which *is* readable via gpioin.
+ */
+ if (on && (in & PCI_CFG_GPIO_XTAL))
+ return (0);
- if (what & XTAL)
- outen |= PCI_CFG_GPIO_XTAL;
- if (what & PLL)
- outen |= PCI_CFG_GPIO_PLL;
-
- if (on) {
- /* turn primary xtal on */
- if (what & XTAL) {
- out |= PCI_CFG_GPIO_XTAL;
- if (what & PLL)
- out |= PCI_CFG_GPIO_PLL;
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
- sizeof(uint32), out);
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN,
- sizeof(uint32), outen);
- OSL_DELAY(XTAL_ON_DELAY);
- }
+ if (what & XTAL)
+ outen |= PCI_CFG_GPIO_XTAL;
+ if (what & PLL)
+ outen |= PCI_CFG_GPIO_PLL;
- /* turn pll on */
- if (what & PLL) {
- out &= ~PCI_CFG_GPIO_PLL;
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
- sizeof(uint32), out);
- OSL_DELAY(2000);
- }
- } else {
- if (what & XTAL)
- out &= ~PCI_CFG_GPIO_XTAL;
+ if (on) {
+ /* turn primary xtal on */
+ if (what & XTAL) {
+ out |= PCI_CFG_GPIO_XTAL;
if (what & PLL)
out |= PCI_CFG_GPIO_PLL;
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32), out);
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof(uint32),
- outen);
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
+ sizeof(uint32), out);
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32), outen);
+ OSL_DELAY(XTAL_ON_DELAY);
}
- default:
- return (-1);
+ /* turn pll on */
+ if (what & PLL) {
+ out &= ~PCI_CFG_GPIO_PLL;
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
+ sizeof(uint32), out);
+ OSL_DELAY(2000);
+ }
+ } else {
+ if (what & XTAL)
+ out &= ~PCI_CFG_GPIO_XTAL;
+ if (what & PLL)
+ out |= PCI_CFG_GPIO_PLL;
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
+ sizeof(uint32), out);
+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32), outen);
+ }
+
+ default:
+ return (-1);
}
return (0);
@@ -2490,8 +3416,7 @@ sb_clkctl_xtal(sb_t *sbh, uint what, bool on)
/* set dynamic clk control mode (forceslow, forcefast, dynamic) */
/* returns true if we are forcing fast clock */
-bool
-sb_clkctl_clk(sb_t *sbh, uint mode)
+bool sb_clkctl_clk(sb_t * sbh, uint mode)
{
sb_info_t *si;
uint origidx;
@@ -2505,7 +3430,6 @@ sb_clkctl_clk(sb_t *sbh, uint mode)
if (si->sb.ccrev < 6)
return (FALSE);
-
/* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
ASSERT(si->sb.ccrev != 10);
@@ -2517,31 +3441,41 @@ sb_clkctl_clk(sb_t *sbh, uint mode)
(BUSTYPE(si->sb.bustype) == SB_BUS) && (si->sb.ccrev >= 10))
goto done;
- /* PR32414WAR "Force HT clock on" all the time, no dynamic clk ctl */
- if ((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev <= 1))
+ if (FORCEHT_WAR32414(si))
goto done;
- cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);
+ cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
ASSERT(cc != NULL);
- if (!(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL))
+ if (!(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL)
+ && (si->sb.ccrev < 20))
goto done;
switch (mode) {
- case CLK_FAST: /* force fast (pll) clock */
+ case CLK_FAST: /* force fast (pll) clock */
if (si->sb.ccrev < 10) {
/* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
sb_clkctl_xtal(&si->sb, XTAL, ON);
- SET_REG(si->osh, &cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
- } else
+ SET_REG(si->osh, &cc->slow_clk_ctl,
+ (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
+ } else if (si->sb.ccrev < 20) {
OR_REG(si->osh, &cc->system_clk_ctl, SYCC_HR);
+ } else {
+ OR_REG(si->osh, &cc->clk_ctl_st, CCS_FORCEHT);
+ }
+
/* wait for the PLL */
- OSL_DELAY(PLL_DELAY);
+ if (R_REG(si->osh, &cc->capabilities) & CC_CAP_PMU) {
+ SPINWAIT(((R_REG(si->osh, &cc->clk_ctl_st) &
+ CCS_HTAVAIL) == 0), PMU_MAX_TRANSITION_DLY);
+ ASSERT(R_REG(si->osh, &cc->clk_ctl_st) & CCS_HTAVAIL);
+ } else {
+ OSL_DELAY(PLL_DELAY);
+ }
break;
case CLK_DYNAMIC: /* enable dynamic clock control */
-
if (si->sb.ccrev < 10) {
scc = R_REG(si->osh, &cc->slow_clk_ctl);
scc &= ~(SCC_FS | SCC_IP | SCC_XC);
@@ -2552,9 +3486,11 @@ sb_clkctl_clk(sb_t *sbh, uint mode)
/* for dynamic control, we have to release our xtal_pu "force on" */
if (scc & SCC_XC)
sb_clkctl_xtal(&si->sb, XTAL, OFF);
- } else {
+ } else if (si->sb.ccrev < 20) {
/* Instaclock */
AND_REG(si->osh, &cc->system_clk_ctl, ~SYCC_HR);
+ } else {
+ AND_REG(si->osh, &cc->clk_ctl_st, ~CCS_FORCEHT);
}
break;
@@ -2562,7 +3498,7 @@ sb_clkctl_clk(sb_t *sbh, uint mode)
ASSERT(0);
}
-done:
+ done:
sb_setcoreidx(sbh, origidx);
INTR_RESTORE(si, intr_val);
return (mode == CLK_FAST);
@@ -2570,50 +3506,124 @@ done:
/* register driver interrupt disabling and restoring callback functions */
void
-sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn,
- void *intrsenabled_fn, void *intr_arg)
+sb_register_intr_callback(sb_t * sbh, void *intrsoff_fn,
+ void *intrsrestore_fn, void *intrsenabled_fn,
+ void *intr_arg)
{
sb_info_t *si;
si = SB_INFO(sbh);
si->intr_arg = intr_arg;
- si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn;
- si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn;
- si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn;
+ si->intrsoff_fn = (sb_intrsoff_t) intrsoff_fn;
+ si->intrsrestore_fn = (sb_intrsrestore_t) intrsrestore_fn;
+ si->intrsenabled_fn = (sb_intrsenabled_t) intrsenabled_fn;
/* save current core id. when this function called, the current core
* must be the core which provides driver functions(il, et, wl, etc.)
*/
si->dev_coreid = si->coreid[si->curidx];
}
+void sb_deregister_intr_callback(sb_t * sbh)
+{
+ sb_info_t *si;
-int
-sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
- uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif,
- uint8 *pciheader)
+ si = SB_INFO(sbh);
+ si->intrsoff_fn = NULL;
+}
+
+#ifdef BCMDBG
+/* dump dynamic clock control related registers */
+void sb_clkctl_dump(sb_t * sbh, struct bcmstrbuf *b)
{
- uint16 vendor = 0xffff, device = 0xffff;
- uint core, unit;
- uint chip, chippkg;
- uint nfunc;
- char varname[SB_DEVPATH_BUFSZ + 8];
- uint8 class, subclass, progif;
- char devpath[SB_DEVPATH_BUFSZ];
- uint8 header;
+ sb_info_t *si;
+ chipcregs_t *cc;
+ uint origidx;
+ uint intr_val = 0;
- core = sb_coreid(sbh);
- unit = sb_coreunit(sbh);
+ si = SB_INFO(sbh);
- chip = sb_chip(sbh);
- chippkg = sb_chippkg(sbh);
+ INTR_OFF(si, intr_val);
- progif = 0;
- header = PCI_HEADER_NORMAL;
+ origidx = si->curidx;
+
+ if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0)) == NULL) {
+ INTR_RESTORE(si, intr_val);
+ return;
+ }
+
+ if (!(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL))
+ goto done;
+
+ bcm_bprintf(b, "pll_on_delay 0x%x fref_sel_delay 0x%x ",
+ cc->pll_on_delay, cc->fref_sel_delay);
+ if ((si->sb.ccrev >= 6) && (si->sb.ccrev < 10))
+ bcm_bprintf(b, "slow_clk_ctl 0x%x ", cc->slow_clk_ctl);
+ if (si->sb.ccrev >= 10) {
+ bcm_bprintf(b, "system_clk_ctl 0x%x ", cc->system_clk_ctl);
+ bcm_bprintf(b, "clkstatestretch 0x%x ", cc->clkstatestretch);
+ }
+ if (BUSTYPE(si->sb.bustype) == PCI_BUS)
+ bcm_bprintf(b, "gpioout 0x%x gpioouten 0x%x ",
+ OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT,
+ sizeof(uint32)),
+ OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN,
+ sizeof(uint32)));
+ bcm_bprintf(b, "\n");
+
+ done:
+ sb_setcoreidx(sbh, origidx);
+ INTR_RESTORE(si, intr_val);
+}
+#endif /* BCMDBG */
+
+uint16 BCMINITFN(sb_d11_devid) (sb_t * sbh) {
+ sb_info_t *si = SB_INFO(sbh);
+ uint16 device;
+
+#if defined(BCM4328)
+ /* Fix device id for dual band BCM4328 */
+ if (sbh->chip == BCM4328_CHIP_ID &&
+ (sbh->chippkg == BCM4328USBDUAL_PKG_ID
+ || sbh->chippkg == BCM4328SDIODUAL_PKG_ID))
+ device = BCM4328_D11DUAL_ID;
+ else
+#endif /* BCM4328 */
+ /* Let an nvram variable with devpath override devid */
+ if ((device = (uint16) sb_getdevpathintvar(sbh, "devid")) != 0) ;
+ /* Get devid from OTP/SPROM depending on where the SROM is read */
+ else if ((device = (uint16) getintvar(si->vars, "devid")) != 0) ;
+ /*
+ * no longer support wl0id, but keep the code
+ * here for backward compatibility.
+ */
+ else if ((device = (uint16) getintvar(si->vars, "wl0id")) != 0) ;
+ /* Chip specific conversion */
+ else if (sbh->chip == BCM4712_CHIP_ID) {
+ if (sbh->chippkg == BCM4712SMALL_PKG_ID)
+ device = BCM4306_D11G_ID;
+ else
+ device = BCM4306_D11DUAL_ID;
+ }
+ /* ignore it */
+ else
+ device = 0xffff;
+
+ return device;
+}
+
+int
+BCMINITFN(sb_corepciid) (sb_t * sbh, uint func, uint16 * pcivendor,
+ uint16 * pcidevice, uint8 * pciclass,
+ uint8 * pcisubclass, uint8 * pciprogif,
+ uint8 * pciheader) {
+ uint16 vendor = 0xffff, device = 0xffff;
+ uint8 class, subclass, progif = 0;
+ uint8 header = PCI_HEADER_NORMAL;
+ uint32 core = sb_coreid(sbh);
/* Verify whether the function exists for the core */
- nfunc = (core == SB_USB20H) ? 2 : 1;
- if (func >= nfunc)
- return BCME_ERROR;
+ if (func >= (uint) (core == SB_USB20H ? 2 : 1))
+ return -1;
/* Known vendor translations */
switch (sb_corevendor(sbh)) {
@@ -2621,7 +3631,7 @@ sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
vendor = VENDOR_BROADCOM;
break;
default:
- return BCME_ERROR;
+ return -1;
}
/* Determine class based on known core codes */
@@ -2645,20 +3655,20 @@ sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
case SB_MEMC:
class = PCI_CLASS_MEMORY;
subclass = PCI_MEMORY_RAM;
- device = (uint16)core;
+ device = (uint16) core;
break;
case SB_PCI:
case SB_PCIE:
class = PCI_CLASS_BRIDGE;
subclass = PCI_BRIDGE_PCI;
- device = (uint16)core;
+ device = (uint16) core;
header = PCI_HEADER_BRIDGE;
break;
case SB_MIPS:
case SB_MIPS33:
class = PCI_CLASS_CPU;
subclass = PCI_CPU_MIPS;
- device = (uint16)core;
+ device = (uint16) core;
break;
case SB_CODEC:
class = PCI_CLASS_COMM;
@@ -2668,31 +3678,21 @@ sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
case SB_USB:
class = PCI_CLASS_SERIAL;
subclass = PCI_SERIAL_USB;
- progif = 0x10; /* OHCI */
+ progif = 0x10; /* OHCI */
device = BCM47XX_USB_ID;
break;
case SB_USB11H:
class = PCI_CLASS_SERIAL;
subclass = PCI_SERIAL_USB;
- progif = 0x10; /* OHCI */
+ progif = 0x10; /* OHCI */
device = BCM47XX_USBH_ID;
break;
case SB_USB20H:
class = PCI_CLASS_SERIAL;
subclass = PCI_SERIAL_USB;
- progif = func == 0 ? 0x10 : 0x20; /* OHCI/EHCI */
+ progif = func == 0 ? 0x10 : 0x20; /* OHCI/EHCI */
device = BCM47XX_USB20H_ID;
- header = 0x80; /* multifunction */
- break;
- case SB_USB11D:
- class = PCI_CLASS_SERIAL;
- subclass = PCI_SERIAL_USB;
- device = BCM47XX_USBD_ID;
- break;
- case SB_USB20D:
- class = PCI_CLASS_SERIAL;
- subclass = PCI_SERIAL_USB;
- device = BCM47XX_USB20D_ID;
+ header = 0x80; /* multifunction */
break;
case SB_IPSEC:
class = PCI_CLASS_CRYPT;
@@ -2708,33 +3708,7 @@ sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
case SB_CC:
class = PCI_CLASS_MEMORY;
subclass = PCI_MEMORY_FLASH;
- device = (uint16)core;
- break;
- case SB_D11:
- class = PCI_CLASS_NET;
- subclass = PCI_NET_OTHER;
- /* Let nvram variable override core ID */
- sb_devpath(sbh, devpath, sizeof(devpath));
- sprintf(varname, "%sdevid", devpath);
- if ((device = (uint16)getintvar(NULL, varname)))
- break;
- /*
- * no longer support wl%did, but keep the code
- * here for backward compatibility.
- */
- sprintf(varname, "wl%did", unit);
- if ((device = (uint16)getintvar(NULL, varname)))
- break;
- /* Chip specific conversion */
- if (chip == BCM4712_CHIP_ID) {
- if (chippkg == BCM4712SMALL_PKG_ID)
- device = BCM4306_D11G_ID;
- else
- device = BCM4306_D11DUAL_ID;
- break;
- }
- /* ignore it */
- device = 0xffff;
+ device = (uint16) core;
break;
case SB_SATAXOR:
class = PCI_CLASS_XOR;
@@ -2746,10 +3720,25 @@ sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
subclass = PCI_DASDI_IDE;
device = BCM47XX_ATA100_ID;
break;
+ case SB_USB11D:
+ class = PCI_CLASS_SERIAL;
+ subclass = PCI_SERIAL_USB;
+ device = BCM47XX_USBD_ID;
+ break;
+ case SB_USB20D:
+ class = PCI_CLASS_SERIAL;
+ subclass = PCI_SERIAL_USB;
+ device = BCM47XX_USB20D_ID;
+ break;
+ case SB_D11:
+ class = PCI_CLASS_NET;
+ subclass = PCI_NET_OTHER;
+ device = sb_d11_devid(sbh);
+ break;
default:
class = subclass = progif = 0xff;
- device = (uint16)core;
+ device = (uint16) core;
break;
}
@@ -2763,25 +3752,69 @@ sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
return 0;
}
+/* use the mdio interface to read from mdio slaves */
+static int
+sb_pcie_mdioread(sb_info_t * si, uint physmedia, uint regaddr, uint * regval)
+{
+ uint mdiodata;
+ uint i = 0;
+ sbpcieregs_t *pcieregs;
+
+ pcieregs = (sbpcieregs_t *) sb_setcoreidx(&si->sb, si->sb.buscoreidx);
+ ASSERT(pcieregs);
+ /* enable mdio access to SERDES */
+ W_REG(si->osh, (&pcieregs->mdiocontrol),
+ MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
+
+ mdiodata = MDIODATA_START | MDIODATA_READ |
+ (physmedia << MDIODATA_DEVADDR_SHF) |
+ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA;
+
+ W_REG(si->osh, &pcieregs->mdiodata, mdiodata);
+
+ PR28829_DELAY();
+
+ /* retry till the transaction is complete */
+ while (i < 10) {
+ if (R_REG(si->osh, &(pcieregs->mdiocontrol)) &
+ MDIOCTL_ACCESS_DONE) {
+ PR28829_DELAY();
+ *regval =
+ (R_REG(si->osh, &(pcieregs->mdiodata)) &
+ MDIODATA_MASK);
+ /* Disable mdio access to SERDES */
+ W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
+ return 0;
+ }
+ OSL_DELAY(1000);
+ i++;
+ }
+
+ SB_ERROR(("sb_pcie_mdioread: timed out\n"));
+ /* Disable mdio access to SERDES */
+ W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
+ return 1;
+}
/* use the mdio interface to write to mdio slaves */
static int
-sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val)
+sb_pcie_mdiowrite(sb_info_t * si, uint physmedia, uint regaddr, uint val)
{
uint mdiodata;
uint i = 0;
sbpcieregs_t *pcieregs;
- pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx);
+ pcieregs = (sbpcieregs_t *) sb_setcoreidx(&si->sb, si->sb.buscoreidx);
ASSERT(pcieregs);
/* enable mdio access to SERDES */
- W_REG(si->osh, (&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
+ W_REG(si->osh, (&pcieregs->mdiocontrol),
+ MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
mdiodata = MDIODATA_START | MDIODATA_WRITE |
- (physmedia << MDIODATA_DEVADDR_SHF) |
- (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val;
+ (physmedia << MDIODATA_DEVADDR_SHF) |
+ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val;
W_REG(si->osh, (&pcieregs->mdiodata), mdiodata);
@@ -2789,7 +3822,8 @@ sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val)
/* retry till the transaction is complete */
while (i < 10) {
- if (R_REG(si->osh, &(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) {
+ if (R_REG(si->osh, &(pcieregs->mdiocontrol)) &
+ MDIOCTL_ACCESS_DONE) {
/* Disable mdio access to SERDES */
W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
return 0;
@@ -2801,48 +3835,45 @@ sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val)
SB_ERROR(("sb_pcie_mdiowrite: timed out\n"));
/* Disable mdio access to SERDES */
W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
- ASSERT(0);
return 1;
}
/* indirect way to read pcie config regs */
-uint
-sb_pcie_readreg(void *sb, void* arg1, uint offset)
+uint sb_pcie_readreg(void *sb, void *arg1, uint offset)
{
sb_info_t *si;
- sb_t *sbh;
+ sb_t *sbh;
uint retval = 0xFFFFFFFF;
sbpcieregs_t *pcieregs;
uint addrtype;
- sbh = (sb_t *)sb;
+ sbh = (sb_t *) sb;
si = SB_INFO(sbh);
ASSERT(PCIE(si));
- pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0);
+ pcieregs = (sbpcieregs_t *) sb_setcore(sbh, SB_PCIE, 0);
ASSERT(pcieregs);
- addrtype = (uint)((uintptr)arg1);
+ addrtype = (uint) ((uintptr) arg1);
switch (addrtype) {
- case PCIE_CONFIGREGS:
- W_REG(si->osh, (&pcieregs->configaddr), offset);
- retval = R_REG(si->osh, &(pcieregs->configdata));
- break;
- case PCIE_PCIEREGS:
- W_REG(si->osh, &(pcieregs->pcieaddr), offset);
- retval = R_REG(si->osh, &(pcieregs->pciedata));
- break;
- default:
- ASSERT(0);
- break;
+ case PCIE_CONFIGREGS:
+ W_REG(si->osh, (&pcieregs->configaddr), offset);
+ retval = R_REG(si->osh, &(pcieregs->configdata));
+ break;
+ case PCIE_PCIEREGS:
+ W_REG(si->osh, &(pcieregs->pcieindaddr), offset);
+ retval = R_REG(si->osh, &(pcieregs->pcieinddata));
+ break;
+ default:
+ ASSERT(0);
+ break;
}
return retval;
}
/* indirect way to write pcie config/mdio/pciecore regs */
-uint
-sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val)
+uint sb_pcie_writereg(sb_t * sbh, void *arg1, uint offset, uint val)
{
sb_info_t *si;
sbpcieregs_t *pcieregs;
@@ -2851,74 +3882,119 @@ sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val)
si = SB_INFO(sbh);
ASSERT(PCIE(si));
- pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0);
+ pcieregs = (sbpcieregs_t *) sb_setcore(sbh, SB_PCIE, 0);
ASSERT(pcieregs);
- addrtype = (uint)((uintptr)arg1);
+ addrtype = (uint) ((uintptr) arg1);
switch (addrtype) {
- case PCIE_CONFIGREGS:
- W_REG(si->osh, (&pcieregs->configaddr), offset);
- W_REG(si->osh, (&pcieregs->configdata), val);
- break;
- case PCIE_PCIEREGS:
- W_REG(si->osh, (&pcieregs->pcieaddr), offset);
- W_REG(si->osh, (&pcieregs->pciedata), val);
- break;
- default:
- ASSERT(0);
- break;
+ case PCIE_CONFIGREGS:
+ W_REG(si->osh, (&pcieregs->configaddr), offset);
+ W_REG(si->osh, (&pcieregs->configdata), val);
+ break;
+ case PCIE_PCIEREGS:
+ W_REG(si->osh, (&pcieregs->pcieindaddr), offset);
+ W_REG(si->osh, (&pcieregs->pcieinddata), val);
+ break;
+ default:
+ ASSERT(0);
+ break;
}
return 0;
}
/* Build device path. Support SB, PCI, and JTAG for now. */
-int
-sb_devpath(sb_t *sbh, char *path, int size)
-{
+int BCMINITFN(sb_devpath) (sb_t * sbh, char *path, int size) {
+ int slen;
ASSERT(path);
ASSERT(size >= SB_DEVPATH_BUFSZ);
+ if (!path || size <= 0)
+ return -1;
+
switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) {
case SB_BUS:
case JTAG_BUS:
- sprintf(path, "sb/%u/", sb_coreidx(sbh));
+ slen = snprintf(path, (size_t) size, "sb/%u/", sb_coreidx(sbh));
break;
case PCI_BUS:
ASSERT((SB_INFO(sbh))->osh);
- sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh),
- OSL_PCI_SLOT((SB_INFO(sbh))->osh));
+ slen = snprintf(path, (size_t) size, "pci/%u/%u/",
+ OSL_PCI_BUS((SB_INFO(sbh))->osh),
+ OSL_PCI_SLOT((SB_INFO(sbh))->osh));
break;
case PCMCIA_BUS:
SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n"));
SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n"));
- sprintf(path, "pc/%u/%u/", 1, 1);
- break;
- case SDIO_BUS:
- SB_ERROR(("sb_devpath: device 0 assumed\n"));
- sprintf(path, "sd/%u/", sb_coreidx(sbh));
+ slen = snprintf(path, (size_t) size, "pc/1/1/");
break;
default:
+ slen = -1;
ASSERT(0);
break;
}
+ if (slen < 0 || slen >= size) {
+ path[0] = '\0';
+ return -1;
+ }
+
return 0;
}
+/* Get a variable, but only if it has a devpath prefix */
+char *BCMINITFN(sb_getdevpathvar) (sb_t * sbh, const char *name) {
+ char varname[SB_DEVPATH_BUFSZ + 32];
+
+ sb_devpathvar(sbh, varname, sizeof(varname), name);
+
+ return (getvar(NULL, varname));
+}
+
+/* Get a variable, but only if it has a devpath prefix */
+int BCMINITFN(sb_getdevpathintvar) (sb_t * sbh, const char *name) {
+ char varname[SB_DEVPATH_BUFSZ + 32];
+
+ sb_devpathvar(sbh, varname, sizeof(varname), name);
+
+ return (getintvar(NULL, varname));
+}
+
+/* Concatenate the dev path with a varname into the given 'var' buffer
+ * and return the 'var' pointer.
+ * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
+ * On overflow, the first char will be set to '\0'.
+ */
+static char *BCMINITFN(sb_devpathvar) (sb_t * sbh, char *var, int len,
+ const char *name) {
+ uint path_len;
+
+ if (!var || len <= 0)
+ return var;
+
+ if (sb_devpath(sbh, var, len) == 0) {
+ path_len = strlen(var);
+
+ if (strlen(name) + 1 > (uint) (len - path_len))
+ var[0] = '\0';
+ else
+ strncpy(var + path_len, name, len - path_len - 1);
+ }
+
+ return var;
+}
+
/*
* Fixup SROMless PCI device's configuration.
* The current core may be changed upon return.
*/
-static int
-sb_pci_fixcfg(sb_info_t *si)
+static int sb_pci_fixcfg(sb_info_t * si)
{
uint origidx, pciidx;
sbpciregs_t *pciregs;
- sbpcieregs_t *pcieregs;
+ sbpcieregs_t *pcieregs = NULL;
uint16 val16, *reg16;
- char name[SB_DEVPATH_BUFSZ+16], *value;
- char devpath[SB_DEVPATH_BUFSZ];
+ uint32 w;
ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS);
@@ -2928,11 +4004,11 @@ sb_pci_fixcfg(sb_info_t *si)
/* check 'pi' is correct and fix it if not */
if (si->sb.buscoretype == SB_PCIE) {
- pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0);
+ pcieregs = (sbpcieregs_t *) sb_setcore(&si->sb, SB_PCIE, 0);
ASSERT(pcieregs);
reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
} else if (si->sb.buscoretype == SB_PCI) {
- pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0);
+ pciregs = (sbpciregs_t *) sb_setcore(&si->sb, SB_PCI, 0);
ASSERT(pciregs);
reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
} else {
@@ -2941,59 +4017,59 @@ sb_pci_fixcfg(sb_info_t *si)
}
pciidx = sb_coreidx(&si->sb);
val16 = R_REG(si->osh, reg16);
- if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) {
- val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK);
+ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16) pciidx) {
+ val16 =
+ (uint16) (pciidx << SRSH_PI_SHIFT) | (val16 &
+ ~SRSH_PI_MASK);
W_REG(si->osh, reg16, val16);
}
- /* restore the original index */
- sb_setcoreidx(&si->sb, origidx);
+ if (PCIE_ASPMWARS(si)) {
+ w = sb_pcie_readreg((void *)(uintptr) & si->sb,
+ (void *)PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
- /*
- * Fixup bar0window in PCI config space to make the core indicated
- * by the nvram variable the current core.
- * !Do it last, it may change the current core!
- */
- if (sb_devpath(&si->sb, devpath, sizeof(devpath)))
- return -1;
- sprintf(name, "%sb0w", devpath);
- if ((value = getvar(NULL, name))) {
- OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32),
- bcm_strtoul(value, NULL, 16));
- /* update curidx since the current core is changed */
- si->curidx = _sb_coreidx(si);
- if (si->curidx == BADIDX) {
- SB_ERROR(("sb_pci_fixcfg: bad core index\n"));
- return -1;
+ /* Detect the current polarity at attach and force that polarity and
+ * disable changing the polarity
+ */
+ if ((w & PCIE_PLP_POLARITYINV_STAT) == 0) {
+ si->pcie_polarity = (SERDES_RX_CTRL_FORCE);
+ } else {
+ si->pcie_polarity = (SERDES_RX_CTRL_FORCE |
+ SERDES_RX_CTRL_POLARITY);
}
- }
- return 0;
-}
+ w = OSL_PCI_READ_CONFIG(si->osh, si->pciecap_lcreg_offset,
+ sizeof(uint32));
+ if (w & PCIE_CLKREQ_ENAB) {
+ reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET];
+ val16 = R_REG(si->osh, reg16);
+ /* if clockreq is not advertized clkreq should not be enabled */
+ if (!(val16 & SRSH_CLKREQ_ENB))
+ SB_ERROR(("WARNING: CLK REQ enabled already 0x%x\n", w));
+ }
-static uint
-sb_chipc_capability(sb_t *sbh)
-{
- sb_info_t *si;
+ sb_war43448(&si->sb);
- si = SB_INFO(sbh);
+ sb_war42767(&si->sb);
+
+ }
+
+ /* restore the original index */
+ sb_setcoreidx(&si->sb, origidx);
- /* Make sure that there is ChipCommon core present */
- if (si->coreid[SB_CC_IDX] == SB_CC)
- return (sb_corereg(si, SB_CC_IDX, OFFSETOF(chipcregs_t, capabilities),
- 0, 0));
return 0;
}
/* Return ADDR64 capability of the backplane */
-bool
-sb_backplane64(sb_t *sbh)
+bool sb_backplane64(sb_t * sbh)
{
- return ((sb_chipc_capability(sbh) & CAP_BKPLN64) != 0);
+ sb_info_t *si;
+
+ si = SB_INFO(sbh);
+ return ((si->sb.cccaps & CC_CAP_BKPLN64) != 0);
}
-void
-sb_btcgpiowar(sb_t *sbh)
+void sb_btcgpiowar(sb_t * sbh)
{
sb_info_t *si;
uint origidx;
@@ -3004,7 +4080,7 @@ sb_btcgpiowar(sb_t *sbh)
/* Make sure that there is ChipCommon core present &&
* UART_TX is strapped to 1
*/
- if (!(sb_chipc_capability(sbh) & CAP_UARTGPIO))
+ if (!(si->sb.cccaps & CC_CAP_UARTGPIO))
return;
/* sb_corereg cannot be used as we have to guarantee 8-bit read/writes */
@@ -3012,13 +4088,11 @@ sb_btcgpiowar(sb_t *sbh)
origidx = sb_coreidx(sbh);
- cc = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0);
- if (cc == NULL)
- goto end;
+ cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
+ ASSERT(cc);
W_REG(si->osh, &cc->uart0mcr, R_REG(si->osh, &cc->uart0mcr) | 0x04);
-end:
/* restore the original index */
sb_setcoreidx(sbh, origidx);
@@ -3026,8 +4100,7 @@ end:
}
/* check if the device is removed */
-bool
-sb_deviceremoved(sb_t *sbh)
+bool sb_deviceremoved(sb_t * sbh)
{
uint32 w;
sb_info_t *si;
@@ -3048,10 +4121,9 @@ sb_deviceremoved(sb_t *sbh)
return FALSE;
}
+#if 0
/* Return the RAM size of the SOCRAM core */
-uint32
-sb_socram_size(sb_t *sbh)
-{
+uint32 BCMINITFN(sb_socram_size) (sb_t * sbh) {
sb_info_t *si;
uint origidx;
uint intr_val = 0;
@@ -3080,24 +4152,29 @@ sb_socram_size(sb_t *sbh)
coreinfo = R_REG(si->osh, &regs->coreinfo);
/* Calculate size from coreinfo based on rev */
- switch (corerev) {
- case 0:
+ if (corerev == 0)
memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
- break;
- default: /* rev >= 1 */
+ else if (corerev < 3) {
memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- break;
+ } else {
+ uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
+ uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
+ if (lss != 0)
+ nb--;
+ memsize = nb * (1 << (bsz + SR_BSZ_BASE));
+ if (lss != 0)
+ memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
}
-
/* Return to previous state and core */
if (!wasup)
sb_core_disable(sbh, 0);
sb_setcoreidx(sbh, origidx);
-done:
+ done:
INTR_RESTORE(si, intr_val);
return memsize;
}
-
+#endif
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/setup.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/setup.c
index 819a48d255..00c4d9054c 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/setup.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/setup.c
@@ -48,7 +48,6 @@
#include <typedefs.h>
#include <osl.h>
#include <sbutils.h>
-#include <bcmutils.h>
#include <bcmnvram.h>
#include <sbhndmips.h>
#include <hndmips.h>
@@ -170,7 +169,7 @@ brcm_setup(void)
char *value;
/* Get global SB handle */
- sbh = sb_kattach();
+ sbh = sb_kattach(SB_OSH);
/* Initialize clocks and interrupts */
sb_mips_init(sbh, SBMIPS_VIRTIRQ_BASE);
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c
deleted file mode 100644
index c1a5ed551e..0000000000
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sflash.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Broadcom SiliconBackplane chipcommon serial flash interface
- *
- * Copyright 2006, Broadcom Corporation
- * All Rights Reserved.
- *
- * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
- * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
- * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
- *
- * $Id: sflash.c,v 1.1.1.13 2006/02/27 03:43:16 honor Exp $
- */
-
-#include <osl.h>
-#include <typedefs.h>
-#include <sbconfig.h>
-#include <sbchipc.h>
-#include <mipsinc.h>
-#include <bcmutils.h>
-#include <bcmdevs.h>
-#include <sflash.h>
-
-/* Private global state */
-static struct sflash sflash;
-
-/* Issue a serial flash command */
-static INLINE void
-sflash_cmd(chipcregs_t *cc, uint opcode)
-{
- W_REG(NULL, &cc->flashcontrol, SFLASH_START | opcode);
- while (R_REG(NULL, &cc->flashcontrol) & SFLASH_BUSY);
-}
-
-/* Initialize serial flash access */
-struct sflash *
-sflash_init(chipcregs_t *cc)
-{
- uint32 id, id2;
-
- bzero(&sflash, sizeof(sflash));
-
- sflash.type = R_REG(NULL, &cc->capabilities) & CAP_FLASH_MASK;
-
- switch (sflash.type) {
- case SFLASH_ST:
- /* Probe for ST chips */
- sflash_cmd(cc, SFLASH_ST_DP);
- sflash_cmd(cc, SFLASH_ST_RES);
- id = R_REG(NULL, &cc->flashdata);
- switch (id) {
- case 0x11:
- /* ST M25P20 2 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 4;
- break;
- case 0x12:
- /* ST M25P40 4 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 8;
- break;
- case 0x13:
- /* ST M25P80 8 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 16;
- break;
- case 0x14:
- /* ST M25P16 16 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 32;
- break;
- case 0x15:
- /* ST M25P32 32 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 64;
- break;
- case 0x16:
- /* ST M25P64 64 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 128;
- break;
- case 0xbf:
- W_REG(NULL, &cc->flashaddress, 1);
- sflash_cmd(cc, SFLASH_ST_RES);
- id2 = R_REG(NULL, &cc->flashdata);
- if (id2 == 0x44) {
- /* SST M25VF80 4 Mbit Serial Flash */
- sflash.blocksize = 64 * 1024;
- sflash.numblocks = 8;
- }
- break;
- }
- break;
-
- case SFLASH_AT:
- /* Probe for Atmel chips */
- sflash_cmd(cc, SFLASH_AT_STATUS);
- id = R_REG(NULL, &cc->flashdata) & 0x3c;
- switch (id) {
- case 0xc:
- /* Atmel AT45DB011 1Mbit Serial Flash */
- sflash.blocksize = 256;
- sflash.numblocks = 512;
- break;
- case 0x14:
- /* Atmel AT45DB021 2Mbit Serial Flash */
- sflash.blocksize = 256;
- sflash.numblocks = 1024;
- break;
- case 0x1c:
- /* Atmel AT45DB041 4Mbit Serial Flash */
- sflash.blocksize = 256;
- sflash.numblocks = 2048;
- break;
- case 0x24:
- /* Atmel AT45DB081 8Mbit Serial Flash */
- sflash.blocksize = 256;
- sflash.numblocks = 4096;
- break;
- case 0x2c:
- /* Atmel AT45DB161 16Mbit Serial Flash */
- sflash.blocksize = 512;
- sflash.numblocks = 4096;
- break;
- case 0x34:
- /* Atmel AT45DB321 32Mbit Serial Flash */
- sflash.blocksize = 512;
- sflash.numblocks = 8192;
- break;
- case 0x3c:
- /* Atmel AT45DB642 64Mbit Serial Flash */
- sflash.blocksize = 1024;
- sflash.numblocks = 8192;
- break;
- }
- break;
- }
-
- sflash.size = sflash.blocksize * sflash.numblocks;
- return sflash.size ? &sflash : NULL;
-}
-
-/* Read len bytes starting at offset into buf. Returns number of bytes read. */
-int
-sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf)
-{
- int cnt;
- uint32 *from, *to;
-
- if (!len)
- return 0;
-
- if ((offset + len) > sflash.size)
- return -22;
-
- if ((len >= 4) && (offset & 3))
- cnt = 4 - (offset & 3);
- else if ((len >= 4) && ((uint32)buf & 3))
- cnt = 4 - ((uint32)buf & 3);
- else
- cnt = len;
-
- from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset);
- to = (uint32 *)buf;
-
- if (cnt < 4) {
- bcopy(from, to, cnt);
- return cnt;
- }
-
- while (cnt >= 4) {
- *to++ = *from++;
- cnt -= 4;
- }
-
- return (len - cnt);
-}
-
-/* Poll for command completion. Returns zero when complete. */
-int
-sflash_poll(chipcregs_t *cc, uint offset)
-{
- if (offset >= sflash.size)
- return -22;
-
- switch (sflash.type) {
- case SFLASH_ST:
- /* Check for ST Write In Progress bit */
- sflash_cmd(cc, SFLASH_ST_RDSR);
- return R_REG(NULL, &cc->flashdata) & SFLASH_ST_WIP;
- case SFLASH_AT:
- /* Check for Atmel Ready bit */
- sflash_cmd(cc, SFLASH_AT_STATUS);
- return !(R_REG(NULL, &cc->flashdata) & SFLASH_AT_READY);
- }
-
- return 0;
-}
-
-/* Write len bytes starting at offset into buf. Returns number of bytes
- * written. Caller should poll for completion.
- */
-int
-sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
-{
- struct sflash *sfl;
- int ret = 0;
- bool is4712b0;
- uint32 page, byte, mask;
-
- if (!len)
- return 0;
-
- if ((offset + len) > sflash.size)
- return -22;
-
- sfl = &sflash;
- switch (sfl->type) {
- case SFLASH_ST:
- mask = R_REG(NULL, &cc->chipid);
- is4712b0 = (((mask & CID_ID_MASK) == BCM4712_CHIP_ID) &&
- ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT)));
- /* Enable writes */
- sflash_cmd(cc, SFLASH_ST_WREN);
- if (is4712b0) {
- mask = 1 << 14;
- W_REG(NULL, &cc->flashaddress, offset);
- W_REG(NULL, &cc->flashdata, *buf++);
- /* Set chip select */
- OR_REG(NULL, &cc->gpioout, mask);
- /* Issue a page program with the first byte */
- sflash_cmd(cc, SFLASH_ST_PP);
- ret = 1;
- offset++;
- len--;
- while (len > 0) {
- if ((offset & 255) == 0) {
- /* Page boundary, drop cs and return */
- AND_REG(NULL, &cc->gpioout, ~mask);
- if (!sflash_poll(cc, offset)) {
- /* Flash rejected command */
- return -11;
- }
- return ret;
- } else {
- /* Write single byte */
- sflash_cmd(cc, *buf++);
- }
- ret++;
- offset++;
- len--;
- }
- /* All done, drop cs if needed */
- if ((offset & 255) != 1) {
- /* Drop cs */
- AND_REG(NULL, &cc->gpioout, ~mask);
- if (!sflash_poll(cc, offset)) {
- /* Flash rejected command */
- return -12;
- }
- }
- } else {
- ret = 1;
- W_REG(NULL, &cc->flashaddress, offset);
- W_REG(NULL, &cc->flashdata, *buf);
- /* Page program */
- sflash_cmd(cc, SFLASH_ST_PP);
- }
- break;
- case SFLASH_AT:
- mask = sfl->blocksize - 1;
- page = (offset & ~mask) << 1;
- byte = offset & mask;
- /* Read main memory page into buffer 1 */
- if (byte || (len < sfl->blocksize)) {
- W_REG(NULL, &cc->flashaddress, page);
- sflash_cmd(cc, SFLASH_AT_BUF1_LOAD);
- /* 250 us for AT45DB321B */
- SPINWAIT(sflash_poll(cc, offset), 1000);
- ASSERT(!sflash_poll(cc, offset));
- }
- /* Write into buffer 1 */
- for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) {
- W_REG(NULL, &cc->flashaddress, byte++);
- W_REG(NULL, &cc->flashdata, *buf++);
- sflash_cmd(cc, SFLASH_AT_BUF1_WRITE);
- }
- /* Write buffer 1 into main memory page */
- W_REG(NULL, &cc->flashaddress, page);
- sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM);
- break;
- }
-
- return ret;
-}
-
-/* Erase a region. Returns number of bytes scheduled for erasure.
- * Caller should poll for completion.
- */
-int
-sflash_erase(chipcregs_t *cc, uint offset)
-{
- struct sflash *sfl;
-
- if (offset >= sflash.size)
- return -22;
-
- sfl = &sflash;
- switch (sfl->type) {
- case SFLASH_ST:
- sflash_cmd(cc, SFLASH_ST_WREN);
- W_REG(NULL, &cc->flashaddress, offset);
- sflash_cmd(cc, SFLASH_ST_SE);
- return sfl->blocksize;
- case SFLASH_AT:
- W_REG(NULL, &cc->flashaddress, offset << 1);
- sflash_cmd(cc, SFLASH_AT_PAGE_ERASE);
- return sfl->blocksize;
- }
-
- return 0;
-}
-
-/*
- * writes the appropriate range of flash, a NULL buf simply erases
- * the region of flash
- */
-int
-sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
-{
- struct sflash *sfl;
- uchar *block = NULL, *cur_ptr, *blk_ptr;
- uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
- uint blk_offset, blk_len, copied;
- int bytes, ret = 0;
-
- /* Check address range */
- if (len <= 0)
- return 0;
-
- sfl = &sflash;
- if ((offset + len) > sfl->size)
- return -1;
-
- blocksize = sfl->blocksize;
- mask = blocksize - 1;
-
- /* Allocate a block of mem */
- if (!(block = MALLOC(NULL, blocksize)))
- return -1;
-
- while (len) {
- /* Align offset */
- cur_offset = offset & ~mask;
- cur_length = blocksize;
- cur_ptr = block;
-
- remainder = blocksize - (offset & mask);
- if (len < remainder)
- cur_retlen = len;
- else
- cur_retlen = remainder;
-
- /* buf == NULL means erase only */
- if (buf) {
- /* Copy existing data into holding block if necessary */
- if ((offset & mask) || (len < blocksize)) {
- blk_offset = cur_offset;
- blk_len = cur_length;
- blk_ptr = cur_ptr;
-
- /* Copy entire block */
- while (blk_len) {
- copied = sflash_read(cc, blk_offset, blk_len, blk_ptr);
- blk_offset += copied;
- blk_len -= copied;
- blk_ptr += copied;
- }
- }
-
- /* Copy input data into holding block */
- memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
- }
-
- /* Erase block */
- if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0)
- goto done;
- while (sflash_poll(cc, (uint) cur_offset));
-
- /* buf == NULL means erase only */
- if (!buf) {
- offset += cur_retlen;
- len -= cur_retlen;
- continue;
- }
-
- /* Write holding block */
- while (cur_length > 0) {
- if ((bytes = sflash_write(cc,
- (uint) cur_offset,
- (uint) cur_length,
- (uchar *) cur_ptr)) < 0) {
- ret = bytes;
- goto done;
- }
- while (sflash_poll(cc, (uint) cur_offset));
- cur_offset += bytes;
- cur_length -= bytes;
- cur_ptr += bytes;
- }
-
- offset += cur_retlen;
- len -= cur_retlen;
- buf += cur_retlen;
- }
-
- ret = len;
-done:
- if (block)
- MFREE(NULL, block, blocksize);
- return ret;
-}
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/time.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/time.c
index 9c502be580..03d5c85651 100644
--- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/time.c
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/time.c
@@ -23,11 +23,12 @@
#include <osl.h>
#include <bcmnvram.h>
#include <sbconfig.h>
-#include <sbextif.h>
#include <sbutils.h>
+#include <sbchipc.h>
#include <hndmips.h>
#include <mipsinc.h>
#include <hndcpu.h>
+#include <bcmdevs.h>
/* Global SB handle */
extern void *bcm947xx_sbh;
@@ -39,13 +40,11 @@ extern spinlock_t bcm947xx_sbh_lock;
extern int panic_timeout;
static int watchdog = 0;
-static u8 *mcr = NULL;
void __init
bcm947xx_time_init(void)
{
unsigned int hz;
- extifregs_t *eir;
/*
* Use deterministic values for initial counter interrupt
@@ -83,8 +82,13 @@ bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
timer_interrupt(irq, dev_id, regs);
/* Set the watchdog timer to reset after the specified number of ms */
- if (watchdog > 0)
- sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
+ if (watchdog > 0) {
+ if (sb_chip(sbh) == BCM5354_CHIP_ID)
+ sb_watchdog(sbh, WATCHDOG_CLOCK_5354 / 1000 * watchdog);
+ else
+ sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
+ }
+
}
static struct irqaction bcm947xx_timer_irqaction = {
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.c
new file mode 100644
index 0000000000..418671d7f3
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.c
@@ -0,0 +1,105 @@
+/*
+ * Driver O/S-independent utility routines
+ *
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <stdarg.h>
+#include <osl.h>
+#include <sbutils.h>
+#include <bcmendian.h>
+#include "utils.h"
+
+/*******************************************************************************
+ * crc8
+ *
+ * Computes a crc8 over the input data using the polynomial:
+ *
+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1
+ *
+ * The caller provides the initial value (either CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint8 crc8_table[256] = {
+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+};
+
+#define CRC_INNER_LOOP(n, c, x) \
+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
+
+
+uint8 hndcrc8 (uint8 * pdata, /* pointer to array of data to process */
+ uint nbytes, /* number of input data bytes to process */
+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */
+ )
+{
+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro
+ * to avoid the undefined and unnecessary (uint8 >> 8) operation.
+ */
+ while (nbytes-- > 0)
+ crc = crc8_table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
+
+char *
+bcm_ether_ntoa (struct ether_addr *ea, char *buf)
+{
+ snprintf (buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ ea->octet[0] & 0xff, ea->octet[1] & 0xff, ea->octet[2] & 0xff,
+ ea->octet[3] & 0xff, ea->octet[4] & 0xff, ea->octet[5] & 0xff);
+ return (buf);
+}
+
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.h b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.h
new file mode 100644
index 0000000000..907c82c70d
--- /dev/null
+++ b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/utils.h
@@ -0,0 +1,65 @@
+#ifndef __bcm_utils_h
+#define __bcm_utils_h
+
+#define BCME_STRLEN 64 /* Max string length for BCM errors */
+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
+
+/*
+ * error codes could be added but the defined ones shouldn't be changed/deleted
+ * these error codes are exposed to the user code
+ * when ever a new error code is added to this list
+ * please update errorstring table with the related error string and
+ * update osl files with os specific errorcode map
+*/
+
+#define BCME_OK 0 /* Success */
+#define BCME_ERROR -1 /* Error generic */
+#define BCME_BADARG -2 /* Bad Argument */
+#define BCME_BADOPTION -3 /* Bad option */
+#define BCME_NOTUP -4 /* Not up */
+#define BCME_NOTDOWN -5 /* Not down */
+#define BCME_NOTAP -6 /* Not AP */
+#define BCME_NOTSTA -7 /* Not STA */
+#define BCME_BADKEYIDX -8 /* BAD Key Index */
+#define BCME_RADIOOFF -9 /* Radio Off */
+#define BCME_NOTBANDLOCKED -10 /* Not band locked */
+#define BCME_NOCLK -11 /* No Clock */
+#define BCME_BADRATESET -12 /* BAD Rate valueset */
+#define BCME_BADBAND -13 /* BAD Band */
+#define BCME_BUFTOOSHORT -14 /* Buffer too short */
+#define BCME_BUFTOOLONG -15 /* Buffer too long */
+#define BCME_BUSY -16 /* Busy */
+#define BCME_NOTASSOCIATED -17 /* Not Associated */
+#define BCME_BADSSIDLEN -18 /* Bad SSID len */
+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
+#define BCME_BADCHAN -20 /* Bad Channel */
+#define BCME_BADADDR -21 /* Bad Address */
+#define BCME_NORESOURCE -22 /* Not Enough Resources */
+#define BCME_UNSUPPORTED -23 /* Unsupported */
+#define BCME_BADLEN -24 /* Bad length */
+#define BCME_NOTREADY -25 /* Not Ready */
+#define BCME_EPERM -26 /* Not Permitted */
+#define BCME_NOMEM -27 /* No Memory */
+#define BCME_ASSOCIATED -28 /* Associated */
+#define BCME_RANGE -29 /* Not In Range */
+#define BCME_NOTFOUND -30 /* Not Found */
+#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
+#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
+#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
+#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
+#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
+#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
+#define BCME_VERSION -37 /* Incorrect version */
+#define BCME_LAST BCME_VERSION
+
+/* buffer length for ethernet address from bcm_ether_ntoa() */
+#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
+
+struct ether_addr {
+ unsigned char octet[6];
+};
+
+extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
+
+#endif /* __bcm_utils_h */
+
diff --git a/target/linux/brcm-2.4/files/drivers/mtd/devices/sflash.c b/target/linux/brcm-2.4/files/drivers/mtd/devices/sflash.c
index a987388ab2..62c7802221 100644
--- a/target/linux/brcm-2.4/files/drivers/mtd/devices/sflash.c
+++ b/target/linux/brcm-2.4/files/drivers/mtd/devices/sflash.c
@@ -1,298 +1,531 @@
/*
* Broadcom SiliconBackplane chipcommon serial flash interface
*
- * Copyright 2001-2003, Broadcom Corporation
- * All Rights Reserved.
- *
- * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
- * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
- * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ * Copyright 2007, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
- * $Id: sflash.c,v 1.1.1.3 2003/11/10 17:43:38 hyin Exp $
+ * $Id$
*/
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/mtd/compatmac.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
-#include <linux/cramfs_fs.h>
-#include <linux/jffs2.h>
-#endif
-
#include <typedefs.h>
-#include <bcmdevs.h>
-#include <bcmutils.h>
#include <osl.h>
-#include <bcmutils.h>
-#include <bcmnvram.h>
+#include <sbutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
+#include <bcmdevs.h>
#include <sflash.h>
-#include <trxhdr.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
-extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
-#endif
-
-struct sflash_mtd {
- chipcregs_t *cc;
- struct semaphore lock;
- struct mtd_info mtd;
- struct mtd_erase_region_info regions[1];
-};
/* Private global state */
-static struct sflash_mtd sflash;
+static struct sflash sflash;
-static int
-sflash_mtd_poll(struct sflash_mtd *sflash, unsigned int offset, int timeout)
+/* Issue a serial flash command */
+static INLINE void
+sflash_cmd (osl_t * osh, chipcregs_t * cc, uint opcode)
{
- int now = jiffies;
- int ret = 0;
+ W_REG (osh, &cc->flashcontrol, SFLASH_START | opcode);
+ while (R_REG (osh, &cc->flashcontrol) & SFLASH_BUSY);
+}
- for (;;) {
- if (!sflash_poll(sflash->cc, offset)) {
- ret = 0;
- break;
- }
- if (time_after(jiffies, now + timeout)) {
- printk(KERN_ERR "sflash: timeout\n");
- ret = -ETIMEDOUT;
- break;
- }
- if (current->need_resched) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(timeout / 10);
- } else
- udelay(1);
+/* Initialize serial flash access */
+struct sflash *
+sflash_init (sb_t * sbh, chipcregs_t * cc)
+{
+ uint32 id, id2;
+ osl_t *osh;
+
+ ASSERT (sbh);
+
+ osh = sb_osh (sbh);
+
+ bzero (&sflash, sizeof (sflash));
+
+ sflash.type = sbh->cccaps & CC_CAP_FLASH_MASK;
+
+ switch (sflash.type)
+ {
+ case SFLASH_ST:
+ /* Probe for ST chips */
+ sflash_cmd (osh, cc, SFLASH_ST_DP);
+ sflash_cmd (osh, cc, SFLASH_ST_RES);
+ id = R_REG (osh, &cc->flashdata);
+ switch (id)
+ {
+ case 0x11:
+ /* ST M25P20 2 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 4;
+ break;
+ case 0x12:
+ /* ST M25P40 4 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 8;
+ break;
+ case 0x13:
+ /* ST M25P80 8 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 16;
+ break;
+ case 0x14:
+ /* ST M25P16 16 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 32;
+ break;
+ case 0x15:
+ /* ST M25P32 32 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 64;
+ break;
+ case 0x16:
+ /* ST M25P64 64 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 128;
+ break;
+ case 0xbf:
+ W_REG (osh, &cc->flashaddress, 1);
+ sflash_cmd (osh, cc, SFLASH_ST_RES);
+ id2 = R_REG (osh, &cc->flashdata);
+ if (id2 == 0x44)
+ {
+ /* SST M25VF80 4 Mbit Serial Flash */
+ sflash.blocksize = 64 * 1024;
+ sflash.numblocks = 8;
+ }
+ break;
}
+ break;
+
+ case SFLASH_AT:
+ /* Probe for Atmel chips */
+ sflash_cmd (osh, cc, SFLASH_AT_STATUS);
+ id = R_REG (osh, &cc->flashdata) & 0x3c;
+ switch (id)
+ {
+ case 0xc:
+ /* Atmel AT45DB011 1Mbit Serial Flash */
+ sflash.blocksize = 256;
+ sflash.numblocks = 512;
+ break;
+ case 0x14:
+ /* Atmel AT45DB021 2Mbit Serial Flash */
+ sflash.blocksize = 256;
+ sflash.numblocks = 1024;
+ break;
+ case 0x1c:
+ /* Atmel AT45DB041 4Mbit Serial Flash */
+ sflash.blocksize = 256;
+ sflash.numblocks = 2048;
+ break;
+ case 0x24:
+ /* Atmel AT45DB081 8Mbit Serial Flash */
+ sflash.blocksize = 256;
+ sflash.numblocks = 4096;
+ break;
+ case 0x2c:
+ /* Atmel AT45DB161 16Mbit Serial Flash */
+ sflash.blocksize = 512;
+ sflash.numblocks = 4096;
+ break;
+ case 0x34:
+ /* Atmel AT45DB321 32Mbit Serial Flash */
+ sflash.blocksize = 512;
+ sflash.numblocks = 8192;
+ break;
+ case 0x3c:
+ /* Atmel AT45DB642 64Mbit Serial Flash */
+ sflash.blocksize = 1024;
+ sflash.numblocks = 8192;
+ break;
+ }
+ break;
+ }
- return ret;
+ sflash.size = sflash.blocksize * sflash.numblocks;
+ return sflash.size ? &sflash : NULL;
}
-static int
-sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+/* Read len bytes starting at offset into buf. Returns number of bytes read. */
+int
+sflash_read (sb_t * sbh, chipcregs_t * cc, uint offset, uint len, uchar * buf)
{
- struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
- int bytes, ret = 0;
-
- /* Check address range */
- if (!len)
- return 0;
- if ((from + len) > mtd->size)
- return -EINVAL;
-
- down(&sflash->lock);
-
- *retlen = 0;
- while (len) {
- if ((bytes = sflash_read(sflash->cc, (uint) from, len, buf)) < 0) {
- ret = bytes;
- break;
- }
- from += (loff_t) bytes;
- len -= bytes;
- buf += bytes;
- *retlen += bytes;
- }
+ uint8 *from, *to;
+ int cnt, i;
+ osl_t *osh;
- up(&sflash->lock);
+ ASSERT (sbh);
- return ret;
-}
+ if (!len)
+ return 0;
-static int
-sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-{
- struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
- int bytes, ret = 0;
-
- /* Check address range */
- if (!len)
- return 0;
- if ((to + len) > mtd->size)
- return -EINVAL;
-
- down(&sflash->lock);
-
- *retlen = 0;
- while (len) {
- if ((bytes = sflash_write(sflash->cc, (uint) to, len, buf)) < 0) {
- ret = bytes;
- break;
- }
- if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10)))
- break;
- to += (loff_t) bytes;
- len -= bytes;
- buf += bytes;
- *retlen += bytes;
- }
+ if ((offset + len) > sflash.size)
+ return -22;
+
+ if ((len >= 4) && (offset & 3))
+ cnt = 4 - (offset & 3);
+ else if ((len >= 4) && ((uintptr) buf & 3))
+ cnt = 4 - ((uintptr) buf & 3);
+ else
+ cnt = len;
+
+ osh = sb_osh (sbh);
- up(&sflash->lock);
+ from = (uint8 *) (uintptr) OSL_UNCACHED (SB_FLASH2 + offset);
+ to = (uint8 *) buf;
- return ret;
+ if (cnt < 4)
+ {
+ for (i = 0; i < cnt; i++)
+ {
+ *to = R_REG (osh, from);
+ from++;
+ to++;
+ }
+ return cnt;
+ }
+
+ while (cnt >= 4)
+ {
+ *(uint32 *) to = R_REG (osh, (uint32 *) from);
+ from += 4;
+ to += 4;
+ cnt -= 4;
+ }
+
+ return (len - cnt);
}
-static int
-sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
+/* Poll for command completion. Returns zero when complete. */
+int
+sflash_poll (sb_t * sbh, chipcregs_t * cc, uint offset)
{
- struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
- int i, j, ret = 0;
- unsigned int addr, len;
-
- /* Check address range */
- if (!erase->len)
- return 0;
- if ((erase->addr + erase->len) > mtd->size)
- return -EINVAL;
-
- addr = erase->addr;
- len = erase->len;
-
- down(&sflash->lock);
-
- /* Ensure that requested region is aligned */
- for (i = 0; i < mtd->numeraseregions; i++) {
- for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
- if (addr == mtd->eraseregions[i].offset + mtd->eraseregions[i].erasesize * j &&
- len >= mtd->eraseregions[i].erasesize) {
- if ((ret = sflash_erase(sflash->cc, addr)) < 0)
- break;
- if ((ret = sflash_mtd_poll(sflash, addr, 10 * HZ)))
- break;
- addr += mtd->eraseregions[i].erasesize;
- len -= mtd->eraseregions[i].erasesize;
- }
- }
- if (ret)
- break;
- }
+ osl_t *osh;
- up(&sflash->lock);
+ ASSERT (sbh);
- /* Set erase status */
- if (ret)
- erase->state = MTD_ERASE_FAILED;
- else
- erase->state = MTD_ERASE_DONE;
+ osh = sb_osh (sbh);
- /* Call erase callback */
- if (erase->callback)
- erase->callback(erase);
+ if (offset >= sflash.size)
+ return -22;
- return ret;
-}
+ switch (sflash.type)
+ {
+ case SFLASH_ST:
+ /* Check for ST Write In Progress bit */
+ sflash_cmd (osh, cc, SFLASH_ST_RDSR);
+ return R_REG (osh, &cc->flashdata) & SFLASH_ST_WIP;
+ case SFLASH_AT:
+ /* Check for Atmel Ready bit */
+ sflash_cmd (osh, cc, SFLASH_AT_STATUS);
+ return !(R_REG (osh, &cc->flashdata) & SFLASH_AT_READY);
+ }
-#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-#define sflash_mtd_init init_module
-#define sflash_mtd_exit cleanup_module
-#endif
+ return 0;
+}
-mod_init_t
-sflash_mtd_init(void)
+/* Write len bytes starting at offset into buf. Returns number of bytes
+ * written. Caller should poll for completion.
+ */
+int
+sflash_write (sb_t * sbh, chipcregs_t * cc, uint offset, uint len,
+ const uchar * buf)
{
- struct pci_dev *pdev;
- int ret = 0;
- struct sflash *info;
- uint bank, i;
-#ifdef CONFIG_MTD_PARTITIONS
- struct mtd_partition *parts;
-#endif
-
- if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_CC, NULL))) {
- printk(KERN_ERR "sflash: chipcommon not found\n");
- return -ENODEV;
+ struct sflash *sfl;
+ int ret = 0;
+ bool is4712b0;
+ uint32 page, byte, mask;
+ osl_t *osh;
+
+ ASSERT (sbh);
+
+ osh = sb_osh (sbh);
+
+ if (!len)
+ return 0;
+
+ if ((offset + len) > sflash.size)
+ return -22;
+
+ sfl = &sflash;
+ switch (sfl->type)
+ {
+ case SFLASH_ST:
+ is4712b0 = (sbh->chip == BCM4712_CHIP_ID) && (sbh->chiprev == 3);
+ /* Enable writes */
+ sflash_cmd (osh, cc, SFLASH_ST_WREN);
+ if (is4712b0)
+ {
+ mask = 1 << 14;
+ W_REG (osh, &cc->flashaddress, offset);
+ W_REG (osh, &cc->flashdata, *buf++);
+ /* Set chip select */
+ OR_REG (osh, &cc->gpioout, mask);
+ /* Issue a page program with the first byte */
+ sflash_cmd (osh, cc, SFLASH_ST_PP);
+ ret = 1;
+ offset++;
+ len--;
+ while (len > 0)
+ {
+ if ((offset & 255) == 0)
+ {
+ /* Page boundary, drop cs and return */
+ AND_REG (osh, &cc->gpioout, ~mask);
+ if (!sflash_poll (sbh, cc, offset))
+ {
+ /* Flash rejected command */
+ return -11;
+ }
+ return ret;
+ }
+ else
+ {
+ /* Write single byte */
+ sflash_cmd (osh, cc, *buf++);
+ }
+ ret++;
+ offset++;
+ len--;
+ }
+ /* All done, drop cs if needed */
+ if ((offset & 255) != 1)
+ {
+ /* Drop cs */
+ AND_REG (osh, &cc->gpioout, ~mask);
+ if (!sflash_poll (sbh, cc, offset))
+ {
+ /* Flash rejected command */
+ return -12;
+ }
+ }
+ }
+ else if (sbh->ccrev >= 20)
+ {
+ W_REG (NULL, &cc->flashaddress, offset);
+ W_REG (NULL, &cc->flashdata, *buf++);
+ /* Issue a page program with CSA bit set */
+ sflash_cmd (osh, cc, SFLASH_ST_CSA | SFLASH_ST_PP);
+ ret = 1;
+ offset++;
+ len--;
+ while (len > 0)
+ {
+ if ((offset & 255) == 0)
+ {
+ /* Page boundary, poll droping cs and return */
+ W_REG (NULL, &cc->flashcontrol, 0);
+ if (!sflash_poll (sbh, cc, offset))
+ {
+ /* Flash rejected command */
+ return -11;
+ }
+ return ret;
+ }
+ else
+ {
+ /* Write single byte */
+ sflash_cmd (osh, cc, SFLASH_ST_CSA | *buf++);
+ }
+ ret++;
+ offset++;
+ len--;
+ }
+ /* All done, drop cs if needed */
+ if ((offset & 255) != 1)
+ {
+ /* Drop cs, poll */
+ W_REG (NULL, &cc->flashcontrol, 0);
+ if (!sflash_poll (sbh, cc, offset))
+ {
+ /* Flash rejected command */
+ return -12;
+ }
+ }
+ }
+ else
+ {
+ ret = 1;
+ W_REG (osh, &cc->flashaddress, offset);
+ W_REG (osh, &cc->flashdata, *buf);
+ /* Page program */
+ sflash_cmd (osh, cc, SFLASH_ST_PP);
+ }
+ break;
+ case SFLASH_AT:
+ mask = sfl->blocksize - 1;
+ page = (offset & ~mask) << 1;
+ byte = offset & mask;
+ /* Read main memory page into buffer 1 */
+ if (byte || (len < sfl->blocksize))
+ {
+ W_REG (osh, &cc->flashaddress, page);
+ sflash_cmd (osh, cc, SFLASH_AT_BUF1_LOAD);
+ /* 250 us for AT45DB321B */
+ SPINWAIT (sflash_poll (sbh, cc, offset), 1000);
+ ASSERT (!sflash_poll (sbh, cc, offset));
}
+ /* Write into buffer 1 */
+ for (ret = 0; (ret < (int) len) && (byte < sfl->blocksize); ret++)
+ {
+ W_REG (osh, &cc->flashaddress, byte++);
+ W_REG (osh, &cc->flashdata, *buf++);
+ sflash_cmd (osh, cc, SFLASH_AT_BUF1_WRITE);
+ }
+ /* Write buffer 1 into main memory page */
+ W_REG (osh, &cc->flashaddress, page);
+ sflash_cmd (osh, cc, SFLASH_AT_BUF1_PROGRAM);
+ break;
+ }
- memset(&sflash, 0, sizeof(struct sflash_mtd));
- init_MUTEX(&sflash.lock);
+ return ret;
+}
- /* Map registers and flash base */
- if (!(sflash.cc = ioremap_nocache(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0)))) {
- printk(KERN_ERR "sflash: error mapping registers\n");
- ret = -EIO;
- goto fail;
- }
+/* Erase a region. Returns number of bytes scheduled for erasure.
+ * Caller should poll for completion.
+ */
+int
+sflash_erase (sb_t * sbh, chipcregs_t * cc, uint offset)
+{
+ struct sflash *sfl;
+ osl_t *osh;
+
+ ASSERT (sbh);
+
+ osh = sb_osh (sbh);
+
+ if (offset >= sflash.size)
+ return -22;
+
+ sfl = &sflash;
+ switch (sfl->type)
+ {
+ case SFLASH_ST:
+ sflash_cmd (osh, cc, SFLASH_ST_WREN);
+ W_REG (osh, &cc->flashaddress, offset);
+ sflash_cmd (osh, cc, SFLASH_ST_SE);
+ return sfl->blocksize;
+ case SFLASH_AT:
+ W_REG (osh, &cc->flashaddress, offset << 1);
+ sflash_cmd (osh, cc, SFLASH_AT_PAGE_ERASE);
+ return sfl->blocksize;
+ }
+
+ return 0;
+}
- /* Initialize serial flash access */
- info = sflash_init(sflash.cc);
+/*
+ * writes the appropriate range of flash, a NULL buf simply erases
+ * the region of flash
+ */
+int
+sflash_commit (sb_t * sbh, chipcregs_t * cc, uint offset, uint len,
+ const uchar * buf)
+{
+ struct sflash *sfl;
+ uchar *block = NULL, *cur_ptr, *blk_ptr;
+ uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
+ uint blk_offset, blk_len, copied;
+ int bytes, ret = 0;
+ osl_t *osh;
+
+ ASSERT (sbh);
+
+ osh = sb_osh (sbh);
+
+ /* Check address range */
+ if (len <= 0)
+ return 0;
+
+ sfl = &sflash;
+ if ((offset + len) > sfl->size)
+ return -1;
+
+ blocksize = sfl->blocksize;
+ mask = blocksize - 1;
+
+ /* Allocate a block of mem */
+ if (!(block = MALLOC (osh, blocksize)))
+ return -1;
+
+ while (len)
+ {
+ /* Align offset */
+ cur_offset = offset & ~mask;
+ cur_length = blocksize;
+ cur_ptr = block;
+
+ remainder = blocksize - (offset & mask);
+ if (len < remainder)
+ cur_retlen = len;
+ else
+ cur_retlen = remainder;
+
+ /* buf == NULL means erase only */
+ if (buf)
+ {
+ /* Copy existing data into holding block if necessary */
+ if ((offset & mask) || (len < blocksize))
+ {
+ blk_offset = cur_offset;
+ blk_len = cur_length;
+ blk_ptr = cur_ptr;
+
+ /* Copy entire block */
+ while (blk_len)
+ {
+ copied =
+ sflash_read (sbh, cc, blk_offset, blk_len, blk_ptr);
+ blk_offset += copied;
+ blk_len -= copied;
+ blk_ptr += copied;
+ }
+ }
- if (!info) {
- printk(KERN_ERR "sflash: found no supported devices\n");
- ret = -ENODEV;
- goto fail;
+ /* Copy input data into holding block */
+ memcpy (cur_ptr + (offset & mask), buf, cur_retlen);
}
- /* Setup banks */
- sflash.regions[0].offset = 0;
- sflash.regions[0].erasesize = info->blocksize;
- sflash.regions[0].numblocks = info->numblocks;
- if (sflash.regions[0].erasesize > sflash.mtd.erasesize)
- sflash.mtd.erasesize = sflash.regions[0].erasesize;
- if (sflash.regions[0].erasesize * sflash.regions[0].numblocks) {
- sflash.mtd.size += sflash.regions[0].erasesize * sflash.regions[0].numblocks;
- }
- sflash.mtd.numeraseregions = 1;
- ASSERT(sflash.mtd.size == info->size);
-
- /* Register with MTD */
- sflash.mtd.name = "sflash";
- sflash.mtd.type = MTD_NORFLASH;
- sflash.mtd.flags = MTD_CAP_NORFLASH;
- sflash.mtd.eraseregions = sflash.regions;
- sflash.mtd.module = THIS_MODULE;
- sflash.mtd.erase = sflash_mtd_erase;
- sflash.mtd.read = sflash_mtd_read;
- sflash.mtd.write = sflash_mtd_write;
- sflash.mtd.priv = &sflash;
-
-#ifdef CONFIG_MTD_PARTITIONS
- parts = init_mtd_partitions(&sflash.mtd, sflash.mtd.size);
- for (i = 0; parts[i].name; i++);
- ret = add_mtd_partitions(&sflash.mtd, parts, i);
-#else
- ret = add_mtd_device(&sflash.mtd);
-#endif
- if (ret) {
- printk(KERN_ERR "sflash: add_mtd failed\n");
- goto fail;
+ /* Erase block */
+ if ((ret = sflash_erase (sbh, cc, (uint) cur_offset)) < 0)
+ goto done;
+ while (sflash_poll (sbh, cc, (uint) cur_offset));
+
+ /* buf == NULL means erase only */
+ if (!buf)
+ {
+ offset += cur_retlen;
+ len -= cur_retlen;
+ continue;
}
- return 0;
+ /* Write holding block */
+ while (cur_length > 0)
+ {
+ if ((bytes = sflash_write (sbh, cc,
+ (uint) cur_offset,
+ (uint) cur_length,
+ (uchar *) cur_ptr)) < 0)
+ {
+ ret = bytes;
+ goto done;
+ }
+ while (sflash_poll (sbh, cc, (uint) cur_offset));
+ cur_offset += bytes;
+ cur_length -= bytes;
+ cur_ptr += bytes;
+ }
- fail:
- if (sflash.cc)
- iounmap((void *) sflash.cc);
- return ret;
-}
+ offset += cur_retlen;
+ len -= cur_retlen;
+ buf += cur_retlen;
+ }
-mod_exit_t
-sflash_mtd_exit(void)
-{
-#ifdef CONFIG_MTD_PARTITIONS
- del_mtd_partitions(&sflash.mtd);
-#else
- del_mtd_device(&sflash.mtd);
-#endif
- iounmap((void *) sflash.cc);
+ ret = len;
+done:
+ if (block)
+ MFREE (osh, block, blocksize);
+ return ret;
}
-
-module_init(sflash_mtd_init);
-module_exit(sflash_mtd_exit);
diff --git a/target/linux/brcm-2.4/files/drivers/mtd/maps/bcm947xx-flash.c b/target/linux/brcm-2.4/files/drivers/mtd/maps/bcm947xx-flash.c
index 1641784681..eea7f137d7 100644
--- a/target/linux/brcm-2.4/files/drivers/mtd/maps/bcm947xx-flash.c
+++ b/target/linux/brcm-2.4/files/drivers/mtd/maps/bcm947xx-flash.c
@@ -56,7 +56,6 @@
#include <typedefs.h>
#include <osl.h>
#include <bcmnvram.h>
-#include <bcmutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sbutils.h>
@@ -470,7 +469,7 @@ mod_init_t init_bcm947xx_map(void)
/* Check strapping option if chipcommon exists */
if ((cc = sb_setcore(sbh, SB_CC, 0))) {
- fltype = readl(&cc->capabilities) & CAP_FLASH_MASK;
+ fltype = readl(&cc->capabilities) & CC_CAP_FLASH_MASK;
if (fltype == PFLASH) {
bcm947xx_map.map_priv_2 = 1;
window_addr = 0x1c000000;