diff options
Diffstat (limited to 'target/linux/linux-2.6/patches')
-rw-r--r-- | target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch (renamed from target/linux/linux-2.6/patches/brcm/001-bcm47xx.patch) | 9565 |
1 files changed, 4102 insertions, 5463 deletions
diff --git a/target/linux/linux-2.6/patches/brcm/001-bcm47xx.patch b/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch index 708aac75b..2e9bca7a1 100644 --- a/target/linux/linux-2.6/patches/brcm/001-bcm47xx.patch +++ b/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch @@ -1,24 +1,23 @@ diff -Nur linux-2.6.12.5/arch/mips/Kconfig linux-2.6.12.5-brcm/arch/mips/Kconfig --- linux-2.6.12.5/arch/mips/Kconfig 2005-08-15 02:20:18.000000000 +0200 -+++ linux-2.6.12.5-brcm/arch/mips/Kconfig 2005-08-28 11:12:20.404863104 +0200 -@@ -40,6 +40,16 @@ ++++ linux-2.6.12.5-brcm/arch/mips/Kconfig 2005-08-28 16:21:04.700803432 +0200 +@@ -40,6 +40,15 @@ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and Olivetti M700-10 workstations. -+config BCM47XX -+ bool "Support for BCM47xx based boards" ++config BCM947XX ++ bool "Support for BCM947xx based boards" + select DMA_NONCOHERENT + select HW_HAS_PCI + select IRQ_CPU -+# select SYS_SUPPORTS_32BIT_KERNEL + select CPU_LITTLE_ENDIAN + help -+ Support for BCM47xx based boards ++ Support for BCM947xx based boards + config ACER_PICA_61 bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)" depends on MACH_JAZZ && EXPERIMENTAL -@@ -974,7 +984,7 @@ +@@ -974,7 +983,7 @@ config CPU_LITTLE_ENDIAN bool "Generate little endian code" @@ -1695,7 +1694,7 @@ diff -Nur linux-2.6.12.5/arch/mips/Kconfig.orig linux-2.6.12.5-brcm/arch/mips/Kc + default y diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefile --- linux-2.6.12.5/arch/mips/Makefile 2005-08-15 02:20:18.000000000 +0200 -+++ linux-2.6.12.5-brcm/arch/mips/Makefile 2005-08-28 11:35:08.381898984 +0200 ++++ linux-2.6.12.5-brcm/arch/mips/Makefile 2005-08-28 16:39:59.077334424 +0200 @@ -79,7 +79,7 @@ cflags-y += -I $(TOPDIR)/include/asm/gcc cflags-y += -G 0 -mno-abicalls -fno-pic -pipe @@ -1725,31 +1724,16 @@ diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefi # +# Broadcom BCM47XX boards +# -+core-$(CONFIG_BCM47XX) += arch/mips/bcm47xx/ arch/mips/bcm47xx/broadcom/ -+cflags-$(CONFIG_BCM47XX) += -Iarch/mips/bcm47xx/broadcom/include -+load-$(CONFIG_BCM47XX) := 0xffffffff80001000 ++core-$(CONFIG_BCM947XX) += arch/mips/bcm947xx/ arch/mips/bcm947xx/broadcom/ ++cflags-$(CONFIG_BCM947XX) += -Iarch/mips/bcm947xx/include ++load-$(CONFIG_BCM947XX) := 0xffffffff80001000 + + +# # SNI RM200 PCI # core-$(CONFIG_SNI_RM200_PCI) += arch/mips/sni/ -@@ -715,6 +724,14 @@ - all: vmlinux.ecoff - endif - -+ifdef CONFIG_BCM47XX -+all: bzImage -+ -+zImage bzImage: vmlinux -+ @$(MAKE) -C arch/mips/bcm47xx/compressed vmlinux -+ -+endif -+ - vmlinux.ecoff vmlinux.rm200: $(vmlinux-32) - +@$(call makeboot,$@) - -@@ -729,6 +746,7 @@ +@@ -729,6 +738,7 @@ archclean: @$(MAKE) $(clean)=arch/mips/boot @$(MAKE) $(clean)=arch/mips/lasat @@ -1757,9 +1741,9 @@ diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefi # Generate <asm/offset.h # -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/Makefile linux-2.6.12.5-brcm/arch/mips/bcm47xx/Makefile ---- linux-2.6.12.5/arch/mips/bcm47xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/Makefile 2005-08-28 11:12:20.406862800 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile +--- linux-2.6.12.5/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile 2005-08-28 11:12:20.406862800 +0200 @@ -0,0 +1,6 @@ +# +# Makefile for the BCM47xx specific kernel interface routines @@ -1767,9 +1751,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/Makefile linux-2.6.12.5-brcm/arch/mip +# + +obj-y := irq.o int-handler.o prom.o setup.o time.o -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/Makefile linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/Makefile ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/Makefile 2005-08-28 11:12:20.407862648 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile 2005-08-28 11:12:20.407862648 +0200 @@ -0,0 +1,6 @@ +# +# Makefile for the BCM47xx specific kernel interface routines @@ -1777,9 +1761,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/Makefile linux-2.6.12.5-brcm +# + +obj-y := sbutils.o linux_osl.o bcmsrom.o bcmutils.o sbmips.o sbpci.o hnddma.o -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmsrom.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/bcmsrom.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/bcmsrom.c 2005-08-28 11:12:20.408862496 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c 2005-08-28 11:12:20.408862496 +0200 @@ -0,0 +1,685 @@ +/* + * Misc useful routines to access NIC SROM @@ -1791,7 +1775,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmsrom.c linux-2.6.12.5-brc + * 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$ ++ * $Id: bcmsrom.c,v 1.1 2005/02/28 13:33:32 jolt Exp $ + */ + +#include <typedefs.h> @@ -2466,9 +2450,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmsrom.c linux-2.6.12.5-brc + return (rc); +} + -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmutils.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/bcmutils.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/bcmutils.c 2005-08-28 11:12:20.428859456 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c 2005-08-28 11:12:20.428859456 +0200 @@ -0,0 +1,691 @@ +/* + * Misc useful OS-independent routines. @@ -2480,7 +2464,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmutils.c linux-2.6.12.5-br + * 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$ ++ * $Id: bcmutils.c,v 1.1 2005/02/28 13:33:32 jolt Exp $ + */ + +#include <typedefs.h> @@ -3161,9 +3145,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/bcmutils.c linux-2.6.12.5-br + + + -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/hnddma.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/hnddma.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/hnddma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/hnddma.c 2005-08-28 11:12:20.430859152 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c 2005-08-28 11:12:20.430859152 +0200 @@ -0,0 +1,763 @@ +/* + * Generic Broadcom Home Networking Division (HND) DMA module. @@ -3177,7 +3161,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/hnddma.c linux-2.6.12.5-brcm + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * $Id: hnddma.c,v 1.1 2005/02/28 13:33:32 jolt Exp $ + */ + +#include <typedefs.h> @@ -3928,9 +3912,3820 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/hnddma.c linux-2.6.12.5-brcm +{ + return (NTXDACTIVE(di->txin, di->txout)); +} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcm4710.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcm4710.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcm4710.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcm4710.h 2005-08-28 11:12:20.430859152 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c 2005-08-28 11:12:20.476852160 +0200 +@@ -0,0 +1,420 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * 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: linux_osl.c,v 1.2 2005/02/28 13:34:25 jolt Exp $ ++ */ ++ ++#define LINUX_OSL ++ ++#include <typedefs.h> ++#include <bcmendian.h> ++#include <linuxver.h> ++#include <linux_osl.h> ++#include <bcmutils.h> ++#include <linux/delay.h> ++#ifdef mips ++#include <asm/paccess.h> ++#endif ++#include <pcicfg.h> ++ ++#define PCI_CFG_RETRY 10 ++ ++void* ++osl_pktget(void *drv, uint len, bool send) ++{ ++ struct sk_buff *skb; ++ ++ if ((skb = dev_alloc_skb(len)) == NULL) ++ return (NULL); ++ ++ skb_put(skb, len); ++ ++ /* ensure the cookie field is cleared */ ++ PKTSETCOOKIE(skb, NULL); ++ ++ return ((void*) skb); ++} ++ ++void ++osl_pktfree(void *p) ++{ ++ struct sk_buff *skb, *nskb; ++ ++ skb = (struct sk_buff*) p; ++ ++ /* perversion: we use skb->next to chain multi-skb packets */ ++ while (skb) { ++ nskb = skb->next; ++ skb->next = NULL; ++ if (skb->destructor) { ++ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ ++ dev_kfree_skb_any(skb); ++ } else { ++ /* can free immediately (even in_irq()) if destructor does not exist */ ++ dev_kfree_skb(skb); ++ } ++ skb = nskb; ++ } ++} ++ ++uint32 ++osl_pci_read_config(void *loc, uint offset, uint size) ++{ ++ struct pci_dev *pdev; ++ uint val; ++ uint retry=PCI_CFG_RETRY; ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ pdev = (struct pci_dev*)loc; ++ do { ++ pci_read_config_dword(pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); ++ ++ ++ return (val); ++} ++ ++void ++osl_pci_write_config(void *loc, uint offset, uint size, uint val) ++{ ++ struct pci_dev *pdev; ++ uint retry=PCI_CFG_RETRY; ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ pdev = (struct pci_dev*)loc; ++ ++ do { ++ pci_write_config_dword(pdev, offset, val); ++ if (offset!=PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(loc,offset,size) == val) ++ break; ++ } while (retry--); ++ ++} ++ ++void ++osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size) ++{ ++ ASSERT(0); ++} ++ ++void ++osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size) ++{ ++ ASSERT(0); ++} ++ ++void ++osl_assert(char *exp, char *file, int line) ++{ ++ char tempbuf[255]; ++ ++ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); ++ panic(tempbuf); ++} ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ */ ++#ifdef BINOSL ++ ++int ++osl_printf(const char *format, ...) ++{ ++ va_list args; ++ char buf[1024]; ++ int len; ++ ++ /* sprintf into a local buffer because there *is* no "vprintk()".. */ ++ va_start(args, format); ++ len = vsprintf(buf, format, args); ++ va_end(args); ++ ++ if (len > sizeof (buf)) { ++ printk("osl_printf: buffer overrun\n"); ++ return (0); ++ } ++ ++ return (printk(buf)); ++} ++ ++int ++osl_sprintf(char *buf, const char *format, ...) ++{ ++ va_list args; ++ int rc; ++ ++ va_start(args, format); ++ rc = vsprintf(buf, format, args); ++ va_end(args); ++ return (rc); ++} ++ ++int ++osl_strcmp(const char *s1, const char *s2) ++{ ++ return (strcmp(s1, s2)); ++} ++ ++int ++osl_strncmp(const char *s1, const char *s2, uint n) ++{ ++ return (strncmp(s1, s2, n)); ++} ++ ++int ++osl_strlen(char *s) ++{ ++ return (strlen(s)); ++} ++ ++char* ++osl_strcpy(char *d, const char *s) ++{ ++ return (strcpy(d, s)); ++} ++ ++char* ++osl_strncpy(char *d, const char *s, uint n) ++{ ++ return (strncpy(d, s, n)); ++} ++ ++void ++bcopy(const void *src, void *dst, int len) ++{ ++ memcpy(dst, src, len); ++} ++ ++int ++bcmp(const void *b1, const void *b2, int len) ++{ ++ return (memcmp(b1, b2, len)); ++} ++ ++void ++bzero(void *b, int len) ++{ ++ memset(b, '\0', len); ++} ++ ++void* ++osl_malloc(uint size) ++{ ++ return (kmalloc(size, GFP_ATOMIC)); ++} ++ ++void ++osl_mfree(void *addr, uint size) ++{ ++ kfree(addr); ++} ++ ++uint32 ++osl_readl(volatile uint32 *r) ++{ ++ return (readl(r)); ++} ++ ++uint16 ++osl_readw(volatile uint16 *r) ++{ ++ return (readw(r)); ++} ++ ++uint8 ++osl_readb(volatile uint8 *r) ++{ ++ return (readb(r)); ++} ++ ++void ++osl_writel(uint32 v, volatile uint32 *r) ++{ ++ writel(v, r); ++} ++ ++void ++osl_writew(uint16 v, volatile uint16 *r) ++{ ++ writew(v, r); ++} ++ ++void ++osl_writeb(uint8 v, volatile uint8 *r) ++{ ++ writeb(v, r); ++} ++ ++void * ++osl_uncached(void *va) ++{ ++#ifdef mips ++ return ((void*)KSEG1ADDR(va)); ++#else ++ return ((void*)va); ++#endif ++} ++ ++uint ++osl_getcycles(void) ++{ ++ uint cycles; ++ ++#if defined(mips) ++ cycles = read_c0_count() * 2; ++#elif defined(__i386__) ++ rdtscl(cycles); ++#else ++ cycles = 0; ++#endif ++ return cycles; ++} ++ ++void * ++osl_reg_map(uint32 pa, uint size) ++{ ++ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); ++} ++ ++void ++osl_reg_unmap(void *va) ++{ ++ iounmap(va); ++} ++ ++int ++osl_busprobe(uint32 *val, uint32 addr) ++{ ++#ifdef mips ++ return get_dbe(*val, (uint32*)addr); ++#else ++ *val = readl(addr); ++ return 0; ++#endif ++} ++ ++void* ++osl_dma_alloc_consistent(void *dev, uint size, ulong *pap) ++{ ++ return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap)); ++} ++ ++void ++osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa) ++{ ++ pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa); ++} ++ ++uint ++osl_dma_map(void *dev, void *va, uint size, int direction) ++{ ++ int dir; ++ ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ return (pci_map_single(dev, va, size, dir)); ++} ++ ++void ++osl_dma_unmap(void *dev, uint pa, uint size, int direction) ++{ ++ int dir; ++ ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ pci_unmap_single(dev, (uint32)pa, size, dir); ++} ++ ++void ++osl_delay(uint usec) ++{ ++ udelay(usec); ++} ++ ++uchar* ++osl_pktdata(void *drv, void *skb) ++{ ++ return (((struct sk_buff*)skb)->data); ++} ++ ++uint ++osl_pktlen(void *drv, void *skb) ++{ ++ return (((struct sk_buff*)skb)->len); ++} ++ ++void* ++osl_pktnext(void *drv, void *skb) ++{ ++ return (((struct sk_buff*)skb)->next); ++} ++ ++void ++osl_pktsetnext(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; ++} ++ ++void ++osl_pktsetlen(void *drv, void *skb, uint len) ++{ ++ __skb_trim((struct sk_buff*)skb, len); ++} ++ ++uchar* ++osl_pktpush(void *drv, void *skb, int bytes) ++{ ++ return (skb_push((struct sk_buff*)skb, bytes)); ++} ++ ++uchar* ++osl_pktpull(void *drv, void *skb, int bytes) ++{ ++ return (skb_pull((struct sk_buff*)skb, bytes)); ++} ++ ++void* ++osl_pktdup(void *drv, void *skb) ++{ ++ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); ++} ++ ++void* ++osl_pktcookie(void *skb) ++{ ++ return ((void*)((struct sk_buff*)skb)->csum); ++} ++ ++void ++osl_pktsetcookie(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->csum = (uint)x; ++} ++ ++void* ++osl_pktlink(void *skb) ++{ ++ return (((struct sk_buff*)skb)->prev); ++} ++ ++void ++osl_pktsetlink(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; ++} ++ ++#endif +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c 2005-08-28 11:12:20.478851856 +0200 +@@ -0,0 +1,950 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane MIPS core routines ++ * ++ * 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: sbmips.c,v 1.1 2005/02/28 13:33:32 jolt Exp $ ++ */ ++ ++#include <typedefs.h> ++#include <osl.h> ++#include <sbutils.h> ++#include <bcmdevs.h> ++#include <bcmnvram.h> ++#include <bcmutils.h> ++#include <hndmips.h> ++#include <sbconfig.h> ++#include <sbextif.h> ++#include <sbchipc.h> ++#include <sbmemc.h> ++ ++/* ++ * Memory segments (32bit kernel mode addresses) ++ */ ++#undef KUSEG ++#undef KSEG0 ++#undef KSEG1 ++#undef KSEG2 ++#undef KSEG3 ++#define KUSEG 0x00000000 ++#define KSEG0 0x80000000 ++#define KSEG1 0xa0000000 ++#define KSEG2 0xc0000000 ++#define KSEG3 0xe0000000 ++ ++/* ++ * Map an address to a certain kernel segment ++ */ ++#undef KSEG0ADDR ++#undef KSEG1ADDR ++#undef KSEG2ADDR ++#undef KSEG3ADDR ++#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0) ++#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1) ++#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2) ++#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3) ++ ++/* ++ * The following macros are especially useful for __asm__ ++ * inline assembler. ++ */ ++#ifndef __STR ++#define __STR(x) #x ++#endif ++#ifndef STR ++#define STR(x) __STR(x) ++#endif ++ ++/* ********************************************************************* ++ * CP0 Registers ++ ********************************************************************* */ ++ ++#define C0_INX 0 /* CP0: TLB Index */ ++#define C0_RAND 1 /* CP0: TLB Random */ ++#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ ++#define C0_CTEXT 4 /* CP0: Context */ ++#define C0_PGMASK 5 /* CP0: TLB PageMask */ ++#define C0_WIRED 6 /* CP0: TLB Wired */ ++#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ ++#define C0_COUNT 9 /* CP0: Count */ ++#define C0_TLBHI 10 /* CP0: TLB EntryHi */ ++#define C0_COMPARE 11 /* CP0: Compare */ ++#define C0_SR 12 /* CP0: Processor Status */ ++#define C0_STATUS C0_SR /* CP0: Processor Status */ ++#define C0_CAUSE 13 /* CP0: Exception Cause */ ++#define C0_EPC 14 /* CP0: Exception PC */ ++#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ ++#define C0_CONFIG 16 /* CP0: Config */ ++#define C0_LLADDR 17 /* CP0: LLAddr */ ++#define C0_WATCHLO 18 /* CP0: WatchpointLo */ ++#define C0_WATCHHI 19 /* CP0: WatchpointHi */ ++#define C0_XCTEXT 20 /* CP0: XContext */ ++#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ ++#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ ++#define C0_ECC 26 /* CP0: ECC */ ++#define C0_CACHEERR 27 /* CP0: CacheErr */ ++#define C0_TAGLO 28 /* CP0: TagLo */ ++#define C0_TAGHI 29 /* CP0: TagHi */ ++#define C0_ERREPC 30 /* CP0: ErrorEPC */ ++ ++/* ++ * Macros to access the system control coprocessor ++ */ ++ ++#define MFC0(source, sel) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ ++ "move\t%0,$1\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res) \ ++ : \ ++ :"$1"); \ ++ __res; \ ++}) ++ ++#define MTC0(source, sel, value) \ ++do { \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "move\t$1,%z0\n\t" \ ++ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ : \ ++ :"Jr" (value) \ ++ :"$1"); \ ++} while (0) ++ ++/* ++ * R4x00 interrupt enable / cause bits ++ */ ++#undef IE_SW0 ++#undef IE_SW1 ++#undef IE_IRQ0 ++#undef IE_IRQ1 ++#undef IE_IRQ2 ++#undef IE_IRQ3 ++#undef IE_IRQ4 ++#undef IE_IRQ5 ++#define IE_SW0 (1<< 8) ++#define IE_SW1 (1<< 9) ++#define IE_IRQ0 (1<<10) ++#define IE_IRQ1 (1<<11) ++#define IE_IRQ2 (1<<12) ++#define IE_IRQ3 (1<<13) ++#define IE_IRQ4 (1<<14) ++#define IE_IRQ5 (1<<15) ++ ++/* ++ * Bitfields in the R4xx0 cp0 status register ++ */ ++#define ST0_IE 0x00000001 ++#define ST0_EXL 0x00000002 ++#define ST0_ERL 0x00000004 ++#define ST0_KSU 0x00000018 ++# define KSU_USER 0x00000010 ++# define KSU_SUPERVISOR 0x00000008 ++# define KSU_KERNEL 0x00000000 ++#define ST0_UX 0x00000020 ++#define ST0_SX 0x00000040 ++#define ST0_KX 0x00000080 ++#define ST0_DE 0x00010000 ++#define ST0_CE 0x00020000 ++ ++/* ++ * Status register bits available in all MIPS CPUs. ++ */ ++#define ST0_IM 0x0000ff00 ++#define ST0_CH 0x00040000 ++#define ST0_SR 0x00100000 ++#define ST0_TS 0x00200000 ++#define ST0_BEV 0x00400000 ++#define ST0_RE 0x02000000 ++#define ST0_FR 0x04000000 ++#define ST0_CU 0xf0000000 ++#define ST0_CU0 0x10000000 ++#define ST0_CU1 0x20000000 ++#define ST0_CU2 0x40000000 ++#define ST0_CU3 0x80000000 ++#define ST0_XX 0x80000000 /* MIPS IV naming */ ++ ++/* ++ * Cache Operations ++ */ ++ ++#ifndef Fill_I ++#define Fill_I 0x14 ++#endif ++ ++#define cache_unroll(base,op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). ++ */ ++ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++ ++/* ++ * Returns TRUE if an external UART exists at the given base ++ * register. ++ */ ++static bool ++serial_exists(uint8 *regs) ++{ ++ uint8 save_mcr, status1; ++ ++ save_mcr = R_REG(®s[UART_MCR]); ++ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a); ++ status1 = R_REG(®s[UART_MSR]) & 0xf0; ++ W_REG(®s[UART_MCR], save_mcr); ++ ++ return (status1 == 0x90); ++} ++ ++/* ++ * Initializes UART access. The callback function will be called once ++ * per found UART. ++*/ ++void ++sb_serial_init(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) ++{ ++ void *regs; ++ ulong base; ++ uint irq; ++ int i, n; ++ ++ 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(&sb->sbadmatch1))); ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ /* Disable GPIO interrupt initially */ ++ W_REG(&eir->gpiointpolarity, 0); ++ W_REG(&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(regs)) { ++ /* Set GPIO 1 to be the external UART IRQ */ ++ W_REG(&eir->gpiointmask, 2); ++ if (add) ++ add(regs, irq, 13500000, 0); ++ } ++ } ++ ++ /* Add internal UART if enabled */ ++ if (R_REG(&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; ++ ++ /* Determine core revision and capabilities */ ++ rev = sb_corerev(sbh); ++ cap = R_REG(&cc->capabilities); ++ pll = cap & CAP_PLL_MASK; ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ if (pll == PLL_TYPE1) { ++ /* PLL clock */ ++ baud_base = sb_clock_rate(pll, ++ R_REG(&cc->clockcontrol_n), ++ R_REG(&cc->clockcontrol_m2)); ++ div = 1; ++ } else if (rev >= 3) { ++ /* Internal backplane clock */ ++ baud_base = sb_clock_rate(pll, ++ R_REG(&cc->clockcontrol_n), ++ R_REG(&cc->clockcontrol_sb)); ++ div = 2; /* Minimum divisor */ ++ W_REG(&cc->uart_clkdiv, div); ++ } else { ++ /* Fixed internal backplane clock */ ++ baud_base = 88000000; ++ div = 48; ++ } ++ ++ /* Clock source depends on strapping if UartClkOverride is unset */ ++ if ((rev > 0) && ((R_REG(&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; ++ } ++ } ++ ++ /* 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)); ++ ++ if (add) ++ add(regs, irq, baud_base, 0); ++ } ++ } ++} ++ ++/* Returns the SB interrupt flag of the current core. */ ++uint32 ++sb_flag(void *sbh) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ regs = sb_coreregs(sbh); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK); ++} ++ ++static const uint32 sbips_int_mask[] = { ++ 0, ++ SBIPS_INT1_MASK, ++ SBIPS_INT2_MASK, ++ SBIPS_INT3_MASK, ++ SBIPS_INT4_MASK ++}; ++ ++static const uint32 sbips_int_shift[] = { ++ 0, ++ 0, ++ SBIPS_INT2_SHIFT, ++ SBIPS_INT3_SHIFT, ++ SBIPS_INT4_SHIFT ++}; ++ ++/* ++ * Returns the MIPS IRQ assignment of the current core. If unassigned, ++ * 0 is returned. ++ */ ++uint ++sb_irq(void *sbh) ++{ ++ uint idx; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag, sbipsflag; ++ uint irq = 0; ++ ++ flag = sb_flag(sbh); ++ ++ idx = sb_coreidx(sbh); ++ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ ++ sbipsflag = R_REG(&sb->sbipsflag); ++ for (irq = 1; irq <= 4; irq++) { ++ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) ++ break; ++ } ++ if (irq == 5) ++ irq = 0; ++ } ++ ++ sb_setcoreidx(sbh, idx); ++ ++ return irq; ++} ++ ++/* Clears the specified MIPS IRQ. */ ++static void ++sb_clearirq(void *sbh, uint irq) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ W_REG(&sb->sbintvec, 0); ++ else ++ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]); ++} ++ ++/* ++ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS ++ * IRQ 0 may be assigned more than once. ++ */ ++static void ++sb_setirq(void *sbh, uint irq, uint coreid, uint coreunit) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag; ++ ++ regs = sb_setcore(sbh, coreid, coreunit); ++ ASSERT(regs); ++ flag = sb_flag(sbh); ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ OR_REG(&sb->sbintvec, 1 << flag); ++ else { ++ flag <<= sbips_int_shift[irq]; ++ ASSERT(!(flag & ~sbips_int_mask[irq])); ++ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq]; ++ W_REG(&sb->sbipsflag, flag); ++ } ++} ++ ++/* ++ * Initializes clocks and interrupts. SB and NVRAM access must be ++ * initialized prior to calling. ++ */ ++void ++sb_mips_init(void *sbh) ++{ ++ ulong hz, ns, tmp; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ char *value; ++ uint irq; ++ ++ /* Figure out current SB clock speed */ ++ if ((hz = sb_clock(sbh)) == 0) ++ hz = 100000000; ++ ns = 1000000000 / hz; ++ ++ /* Setup external interface timing */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ /* Initialize extif so we can get to the LEDs and external UART */ ++ W_REG(&eir->prog_config, CF_EN); ++ ++ /* 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 */ ++ W_REG(&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 */ ++ W_REG(&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 */ ++ W_REG(&cc->parallelflashwaitcnt, tmp); ++ ++ W_REG(&cc->cs01memwaitcnt, tmp); ++ } ++ ++ /* Chip specific initialization */ ++ switch (sb_chip(sbh)) { ++ case BCM4710_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ sb_clearirq(sbh, irq); ++ sb_setirq(sbh, 0, SB_CODEC, 0); ++ sb_setirq(sbh, 0, SB_EXTIF, 0); ++ sb_setirq(sbh, 2, SB_ENET, 1); ++ sb_setirq(sbh, 3, SB_ILINE20, 0); ++ sb_setirq(sbh, 4, SB_PCI, 0); ++ ASSERT(eir); ++ value = nvram_get("et0phyaddr"); ++ if (value && !strcmp(value, "31")) { ++ /* Enable internal UART */ ++ W_REG(&eir->corecontrol, CC_UE); ++ /* Give USB its own interrupt */ ++ sb_setirq(sbh, 1, SB_USB, 0); ++ } else { ++ /* Disable internal UART */ ++ W_REG(&eir->corecontrol, 0); ++ /* Give Ethernet its own interrupt */ ++ sb_setirq(sbh, 1, SB_ENET, 0); ++ sb_setirq(sbh, 0, SB_USB, 0); ++ } ++ break; ++ case BCM4310_DEVICE_ID: ++ MTC0(C0_BROADCOM, 0, MFC0(C0_BROADCOM, 0) & ~(1 << 22)); ++ break; ++ } ++} ++ ++uint32 ++sb_mips_clock(void *sbh) ++{ ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate = 0; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ pll_type = PLL_TYPE1; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4)) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE3) { ++ rate = 200000000; ++ goto out; ++ } else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else ++ goto out; ++ ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return rate; ++} ++ ++static void ++icache_probe(int *size, int *lsize) ++{ ++ uint32 config1; ++ uint sets, ways; ++ ++ config1 = MFC0(C0_CONFIG, 1); ++ ++ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((*lsize = ((config1 >> 19) & 7))) ++ *lsize = 2 << *lsize; ++ sets = 64 << ((config1 >> 22) & 7); ++ ways = 1 + ((config1 >> 16) & 7); ++ *size = *lsize * sets * ways; ++} ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++ ++static void ++handler(void) ++{ ++ /* Step 11 */ ++ __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" ++ "and $15, $15, -31746\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 ++afterhandler(void) ++{ ++} ++ ++/* ++ * Set the MIPS, backplane and PCI clocks as closely as possible. ++ */ ++bool ++sb_mips_setclock(void *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; ++ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, new_ratio; ++ uint32 pll_type, sync_mode; ++ uint idx, i; ++ struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 pci25; ++ } type1_table[] = { ++ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */ ++ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */ ++ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */ ++ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */ ++ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */ ++ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */ ++ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */ ++ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */ ++ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */ ++ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */ ++ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */ ++ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */ ++ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */ ++ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */ ++ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */ ++ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */ ++ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */ ++ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */ ++ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */ ++ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */ ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint32 sbclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 m2; ++ uint32 m3; ++ uint32 ratio; ++ uint32 ratio_parm; ++ } n4m_table_t; ++ ++ n4m_table_t type2_table[] = { ++ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, ++ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0303, 0x01000000, 0x01000600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, ++ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, ++ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, ++ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, ++ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, ++ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, ++ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, ++ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, ++ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, ++ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, ++ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, ++ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, ++ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, ++ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 } ++ }; ++ ++ n4m_table_t type4_table[] = { ++ { 192000000, 96000000, 0x0702, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 }, ++ { 216000000, 108000000, 0x0211, 0x11020005, 0x11030303, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 }, ++ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x11030305, 0x04000005, 0x94, 0x012a00a9 }, ++ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 }, ++ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 0x21, 0x0aaa0555 }, ++ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 }, ++ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, ++ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, ++ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, ++ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 0x52, 0x02520129 } ++ }; ++ uint icache_size, ic_lsize; ++ ulong start, end, dst; ++ bool ret = FALSE; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ pll_type = PLL_TYPE1; ++ clockcontrol_n = &eir->clockcontrol_n; ++ clockcontrol_sb = &eir->clockcontrol_sb; ++ clockcontrol_pci = &eir->clockcontrol_pci; ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ clockcontrol_n = &cc->clockcontrol_n; ++ clockcontrol_sb = &cc->clockcontrol_sb; ++ clockcontrol_pci = &cc->clockcontrol_pci; ++ } else ++ goto done; ++ ++ /* Store the current clock register values */ ++ orig_n = R_REG(clockcontrol_n); ++ orig_sb = R_REG(clockcontrol_sb); ++ orig_pci = R_REG(clockcontrol_pci); ++ ++ if (pll_type == PLL_TYPE1) { ++ /* Keep the current PCI clock if not specified */ ++ if (pciclock == 0) { ++ pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci)); ++ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; ++ } ++ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ 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)); ++ if (type1_table[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(type1_table[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ if ((orig_n == type1_table[i].n) && ++ (orig_sb == type1_table[i].sb) && ++ (orig_pci == type1_table[i].pci33)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, type1_table[i].n); ++ W_REG(clockcontrol_sb, type1_table[i].sb); ++ if (pciclock == 25000000) ++ W_REG(clockcontrol_pci, type1_table[i].pci25); ++ else ++ W_REG(clockcontrol_pci, type1_table[i].pci33); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ while (1); ++ } else if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4)) { ++ n4m_table_t *table = (pll_type == PLL_TYPE2) ? type2_table : type4_table; ++ uint tabsz = (pll_type == PLL_TYPE2) ? ARRAYSIZE(type2_table) : ARRAYSIZE(type4_table); ++ ++ ASSERT(cc); ++ ++ /* Store the current clock register values */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ orig_mips = R_REG(&cc->clockcontrol_mips); ++ orig_ratio_parm = 0; ++ ++ /* Look up current ratio */ ++ for (i = 0; i < tabsz; i++) { ++ 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_ratio_parm = table[i].ratio_parm; ++ break; ++ } ++ } ++ ++ /* 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))) ++ break; ++ } ++ if (i == tabsz) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ } ++ ++ /* No PLL change */ ++ 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)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, table[i].n); ++ W_REG(clockcontrol_sb, table[i].sb); ++ W_REG(clockcontrol_pci, table[i].pci33); ++ W_REG(&cc->clockcontrol_m2, table[i].m2); ++ W_REG(&cc->clockcontrol_mips, table[i].m3); ++ ++ /* No ratio change */ ++ if (orig_ratio_parm == table[i].ratio_parm) ++ goto end_fill; ++ ++ new_ratio = table[i].ratio_parm; ++ ++ icache_probe(&icache_size, &ic_lsize); ++ ++ /* Preload the code into the cache */ ++ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); ++ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); ++ while (start < end) { ++ cache_unroll(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 handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_unroll(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(&mipsr->intmask, 1); ++ ++ start_fill: ++ /* step 1, set clock ratios */ ++ MTC0(C0_BROADCOM, 3, new_ratio); ++ MTC0(C0_BROADCOM, 1, 8); ++ ++ /* step 2: program timer intr */ ++ W_REG(&mipsr->timer, 100); ++ (void) R_REG(&mipsr->timer); ++ ++ /* step 3, switch to async */ ++ sync_mode = MFC0(C0_BROADCOM, 4); ++ MTC0(C0_BROADCOM, 4, 1 << 22); ++ ++ /* step 4, set cfg active */ ++ MTC0(C0_BROADCOM, 2, 0x9); ++ ++ ++ /* steps 5 & 6 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ ++ /* step 7, clear cfg_active */ ++ MTC0(C0_BROADCOM, 2, 0); ++ ++ /* Additional Step: set back to orig sync mode */ ++ MTC0(C0_BROADCOM, 4, sync_mode); ++ ++ /* step 8, fake soft reset */ ++ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4); ++ ++ end_fill: ++ /* step 9 set watchdog timer */ ++ sb_watchdog(sbh, 20); ++ (void) R_REG(&cc->chipid); ++ ++ /* step 11 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ while (1); ++ } ++ ++done: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ ++ ++/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ ++uint32 ++sb_memc_get_ncdl(void *sbh) ++{ ++ sbmemcregs_t *memc; ++ uint32 ret = 0; ++ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; ++ uint idx, rev; ++ ++ idx = sb_coreidx(sbh); ++ ++ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); ++ if (memc == 0) ++ goto out; ++ ++ rev = sb_corerev(sbh); ++ ++ config = R_REG(&memc->config); ++ wr = R_REG(&memc->wrncdlcor); ++ rd = R_REG(&memc->rdncdlcor); ++ misc = R_REG(&memc->miscdlyctl); ++ dqsg = R_REG(&memc->dqsgatencdl); ++ ++ rd &= MEMC_RDNCDLCOR_RD_MASK; ++ wr &= MEMC_WRNCDLCOR_WR_MASK; ++ dqsg &= MEMC_DQSGATENCDL_G_MASK; ++ ++ if (config & MEMC_CONFIG_DDR) { ++ ret = (wr << 16) | (rd << 8) | dqsg; ++ } else { ++ if (rev > 0) ++ cd = rd; ++ else ++ 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: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c 2005-08-28 11:12:20.479851704 +0200 +@@ -0,0 +1,530 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx ++ * ++ * 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: sbpci.c,v 1.2 2005/02/28 13:34:25 jolt Exp $ ++ */ ++ ++#include <typedefs.h> ++#include <pcicfg.h> ++#include <bcmdevs.h> ++#include <sbconfig.h> ++#include <sbpci.h> ++#include <osl.h> ++#include <bcmendian.h> ++#include <bcmutils.h> ++#include <sbutils.h> ++#include <bcmnvram.h> ++#include <hndmips.h> ++ ++/* Can free sbpci_init() memory after boot */ ++#ifndef linux ++#define __init ++#endif ++ ++/* Emulated configuration space */ ++static pci_config_regs sb_config_regs[SB_MAXCORES]; ++ ++/* Banned cores */ ++static uint16 pci_ban[32] = { 0 }; ++static uint pci_banned = 0; ++ ++/* CardBus mode */ ++static bool cardbus = FALSE; ++ ++/* ++ * Functions for accessing external PCI configuration space ++ */ ++ ++/* Assume one-hot slot wiring */ ++#define PCI_SLOT_MAX 16 ++ ++static uint32 ++config_cmd(void *sbh, uint bus, uint dev, uint func, uint off) ++{ ++ uint coreidx; ++ sbpciregs_t *regs; ++ uint32 addr = 0; ++ ++ /* CardBusMode supports only one device */ ++ if (cardbus && dev > 1) ++ return 0; ++ ++ coreidx = sb_coreidx(sbh); ++ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Type 0 transaction */ ++ if (bus == 1) { ++ /* Skip unwired slots */ ++ if (dev < PCI_SLOT_MAX) { ++ /* Slide the PCI window to the appropriate slot */ ++ W_REG(®s->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK)); ++ addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) | ++ (func << 8) | (off & ~3); ++ } ++ } ++ ++ /* Type 1 transaction */ ++ else { ++ W_REG(®s->sbtopci1, SBTOPCI_CFG1); ++ addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ ++ return addr; ++} ++ ++static int ++extpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (!(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ val = 0xffffffff; ++ ++ val >>= 8 * (off & 3); ++ if (len == 4) ++ *((uint32 *) buf) = val; ++ else if (len == 2) ++ *((uint16 *) buf) = (uint16) val; ++ else if (len == 1) ++ *((uint8 *) buf) = (uint8) val; ++ else ++ ret = -1; ++ ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++static int ++extpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (!(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ goto done; ++ ++ if (len == 4) ++ val = *((uint32 *) buf); ++ else if (len == 2) { ++ val &= ~(0xffff << (8 * (off & 3))); ++ val |= *((uint16 *) buf) << (8 * (off & 3)); ++ } else if (len == 1) { ++ val &= ~(0xff << (8 * (off & 3))); ++ val |= *((uint8 *) buf) << (8 * (off & 3)); ++ } else ++ ret = -1; ++ ++ W_REG(reg, val); ++ ++ done: ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++/* ++ * Functions for accessing translated SB configuration space ++ */ ++ ++static int ++sb_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED(buf, len)); ++ ++ if (len == 4) ++ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); ++ else if (len == 2) ++ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); ++ else if (len == 1) ++ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++static int ++sb_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint coreidx, n; ++ void *regs; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED(buf, len)); ++ ++ /* Emulate BAR sizing */ ++ if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) && ++ len == 4 && *((uint32 *) buf) == ~0) { ++ coreidx = sb_coreidx(sbh); ++ if ((regs = sb_setcoreidx(sbh, dev))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ /* Highest numbered address match register */ ++ n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; ++ if (off == OFFSETOF(pci_config_regs, base[0])) ++ cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1); ++ /*else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1) ++ cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2) ++ cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3) ++ cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1);*/ ++ } ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++ } ++ ++ if (len == 4) ++ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); ++ else if (len == 2) ++ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); ++ else if (len == 1) ++ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++int ++sbpci_read_config(void *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); ++ else ++ return extpci_read_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++int ++sbpci_write_config(void *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); ++ else ++ return extpci_write_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++void ++sbpci_ban(uint16 core) ++{ ++ if (pci_banned < ARRAYSIZE(pci_ban)) ++ pci_ban[pci_banned++] = core; ++} ++ ++int __init ++sbpci_init(void *sbh) ++{ ++ uint chip, chiprev, chippkg, coreidx, host, i; ++ sbpciregs_t *pci; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ void *regs; ++ char varname[8]; ++ uint wlidx = 0; ++ uint16 vendor, core; ++ uint8 class, subclass, progif; ++ uint32 val; ++ uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK }; ++ uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT }; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ coreidx = sb_coreidx(sbh); ++ ++ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) ++ return -1; ++ sb_core_reset(sbh, 0); ++ ++ if (((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) || ++ ((chip == BCM4712_DEVICE_ID) && (chippkg == BCM4712SMALL_PKG_ID))) ++ host = 0; ++ else ++ host = !BUSPROBE(val, &pci->control); ++ ++ if (!host) { ++ /* Disable PCI interrupts in client mode */ ++ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); ++ W_REG(&sb->sbintvec, 0); ++ ++ /* Disable the PCI bridge in client mode */ ++ sbpci_ban(SB_PCI); ++ printf("PCI: Disabled\n"); ++ } else { ++ /* Reset the external PCI bus and enable the clock */ ++ W_REG(&pci->control, 0x5); /* enable the tristate drivers */ ++ W_REG(&pci->control, 0xd); /* enable the PCI clock */ ++ OSL_DELAY(100); /* delay 100 us */ ++ W_REG(&pci->control, 0xf); /* deassert PCI reset */ ++ W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */ ++ OSL_DELAY(1); /* delay 1 us */ ++ ++ /* Enable CardBusMode */ ++ cardbus = nvram_match("cardbus", "1"); ++ if (cardbus) { ++ printf("PCI: Enabling CardBus\n"); ++ /* GPIO 1 resets the CardBus device on bcm94710ap */ ++ sb_gpioout(sbh, 1, 1); ++ sb_gpioouten(sbh, 1, 1); ++ W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400); ++ } ++ ++ /* 64 MB I/O access window */ ++ W_REG(&pci->sbtopci0, SBTOPCI_IO); ++ /* 64 MB configuration access window */ ++ W_REG(&pci->sbtopci1, SBTOPCI_CFG0); ++ /* 1 GB memory access window */ ++ W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); ++ ++ /* Enable PCI bridge BAR0 prefetch and burst */ ++ val = 6; ++ sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val)); ++ ++ /* Enable PCI interrupts */ ++ W_REG(&pci->intmask, PCI_INTA); ++ } ++ ++ /* Scan the SB bus */ ++ bzero(sb_config_regs, sizeof(sb_config_regs)); ++ for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) { ++ cfg->vendor = 0xffff; ++ if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs))) ++ continue; ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* Read ID register and parse vendor and core */ ++ val = R_REG(&sb->sbidhigh); ++ vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT; ++ core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; ++ progif = 0; ++ ++ /* Check if this core is banned */ ++ for (i = 0; i < pci_banned; i++) ++ if (core == pci_ban[i]) ++ break; ++ if (i < pci_banned) ++ continue; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ILINE100: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM4610_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ //break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", wlidx); ++ wlidx++; ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } else { ++ /* 4310 */ ++ core = BCM4310_D11B_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ /* Supported translations */ ++ cfg->vendor = htol16(vendor); ++ cfg->device = htol16(core); ++ cfg->rev_id = chiprev; ++ cfg->prog_if = progif; ++ cfg->sub_class = subclass; ++ cfg->base_class = class; ++ cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0))); ++ cfg->base[1] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch1)))*/; ++ cfg->base[2] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch2)))*/; ++ cfg->base[3] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch3)))*/; ++ cfg->base[4] = 0; ++ cfg->base[5] = 0; ++ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) ++ cfg->header_type = PCI_HEADER_BRIDGE; ++ else ++ cfg->header_type = PCI_HEADER_NORMAL; ++ /* Save core interrupt flag */ ++ cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ /* Default to MIPS shared interrupt 0 */ ++ cfg->int_line = 0; ++ /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ val = R_REG(&sb->sbipsflag); ++ for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) { ++ if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin) ++ break; ++ } ++ if (cfg->int_line > 4) ++ cfg->int_line = 0; ++ } ++ /* Emulated core */ ++ *((uint32 *) &cfg->sprom_control) = 0xffffffff; ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++} ++ ++void ++sbpci_check(void *sbh) ++{ ++ uint coreidx; ++ sbpciregs_t *pci; ++ uint32 sbtopci1; ++ uint32 buf[64], *ptr, i; ++ ulong pa; ++ volatile uint j; ++ ++ coreidx = sb_coreidx(sbh); ++ pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Clear the test array */ ++ pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL); ++ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); ++ memset(ptr, 0, sizeof(buf)); ++ ++ /* Point PCI window 1 to memory */ ++ sbtopci1 = R_REG(&pci->sbtopci1); ++ W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK)); ++ ++ /* Fill the test array via PCI window 1 */ ++ ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf)); ++ for (i = 0; i < ARRAYSIZE(buf); i++) { ++ for (j = 0; j < 2; j++); ++ W_REG(&ptr[i], i); ++ } ++ REG_UNMAP(ptr); ++ ++ /* Restore PCI window 1 */ ++ W_REG(&pci->sbtopci1, sbtopci1); ++ ++ /* Check the test array */ ++ DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL); ++ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); ++ for (i = 0; i < ARRAYSIZE(buf); i++) { ++ if (ptr[i] != i) ++ break; ++ } ++ ++ /* Change the clock if the test fails */ ++ if (i < ARRAYSIZE(buf)) { ++ uint32 req, cur; ++ ++ cur = sb_clock(sbh); ++ printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000); ++ for (req = 104000000; req < 176000000; req += 4000000) { ++ printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000); ++ /* This will only reset if the clocks are valid and have changed */ ++ sb_mips_setclock(sbh, req, 0, 0); ++ } ++ /* Should not reach here */ ++ ASSERT(0); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++} +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c +--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c 2005-08-28 11:12:20.482851248 +0200 +@@ -0,0 +1,1895 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * 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: sbutils.c,v 1.1 2005/02/28 13:33:32 jolt Exp $ ++ */ ++ ++#include <typedefs.h> ++#include <osl.h> ++#include <bcmutils.h> ++#include <bcmdevs.h> ++#include <sbconfig.h> ++#include <sbchipc.h> ++#include <sbpci.h> ++#include <pcicfg.h> ++#include <sbpcmcia.h> ++#include <sbextif.h> ++#include <sbutils.h> ++#include <bcmsrom.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); ++ ++/* misc sb info needed by some of the routines */ ++typedef struct sb_info { ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint chippkg; /* chip package option */ ++ uint boardtype; /* board type */ ++ uint boardvendor; /* board vendor id */ ++ uint bus; /* what bus type we are going through */ ++ ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ ++ ++ void *curmap; /* current regs va */ ++ void *regs[SB_MAXCORES]; /* other regs va */ ++ ++ uint curidx; /* current core index */ ++ uint dev_coreid; /* the core provides driver functions */ ++ uint pciidx; /* pci core index */ ++ uint pcirev; /* pci core rev */ ++ ++ uint pcmciaidx; /* pcmcia core index */ ++ uint pcmciarev; /* pcmcia core rev */ ++ bool memseg; /* flag to toggle MEM_SEG register */ ++ ++ uint ccrev; /* chipc core rev */ ++ ++ uint gpioidx; /* gpio control core index */ ++ uint gpioid; /* gpio control coretype */ ++ ++ uint numcores; /* # discovered cores */ ++ uint coreid[SB_MAXCORES]; /* id of each core */ ++ ++ void *intr_arg; /* interrupt callback function arg */ ++ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ ++ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ ++} sb_info_t; ++ ++/* local prototypes */ ++static void* sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); ++static void sb_scan(sb_info_t *si); ++static uint sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val); ++static uint _sb_coreidx(void *sbh); ++static uint sb_findcoreidx(void *sbh, uint coreid, uint coreunit); ++static uint sb_pcidev2chip(uint pcidev); ++static uint sb_chip2numcores(uint chip); ++ ++#define SB_INFO(sbh) (sb_info_t*)sbh ++#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) ++#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) \ ++ && ISALIGNED((x), SB_CORE_SIZE)) ++#define GOODREGS(regs) (regs && ISALIGNED(regs, SB_CORE_SIZE)) ++#define REGS2SB(va) (sbconfig_t*) ((uint)(va) + SBCONFIGOFF) ++#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) ++#define BADIDX (SB_MAXCORES+1) ++ ++#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) ++#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) ++#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) ++#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++ ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ ++/* power control defines */ ++#define PLL_DELAY 150 /* 150us pll on delay */ ++#define FREF_DELAY 15 /* 15us fref change delay */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20mhz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20mhz + 1% */ ++#define PCIMINFREQ 25000000 /* 25mhz */ ++#define PCIMAXFREQ 34000000 /* 33mhz + fudge */ ++ ++#define SCC_LOW2FAST_LIMIT 5000 /* turn on fast clock time, in unit of ms */ ++ ++ ++static uint32 ++sb_read_sbreg(void *sbh, volatile uint32 *sbr) ++{ ++ sb_info_t *si; ++ uint8 tmp; ++ uint32 val, intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* ++ * 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) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ (uint32)sbr &= ~(1 << 11); /* mask out bit 11*/ ++ } ++ ++ val = R_REG(sbr); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++ ++ return (val); ++} ++ ++static void ++sb_write_sbreg(void *sbh, volatile uint32 *sbr, uint32 v) ++{ ++ sb_info_t *si; ++ uint8 tmp; ++ volatile uint32 dummy; ++ uint32 intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* ++ * 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) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ (uint32)sbr &= ~(1 << 11); /* mask out bit 11 */ ++ } ++ ++ if ((si->bus == PCMCIA_BUS) || (si->bus == PCI_BUS)) { ++#ifdef IL_BIGENDIAN ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++#else ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff)); ++#endif ++ } else ++ W_REG(sbr, v); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++} ++ ++/* ++ * Allocate a sb handle. ++ * devid - pci device id (used to determine chip#) ++ * osh - opaque OS handle ++ * regs - virtual address of initial core registers ++ * bustype - pci/pcmcia/sb/sdio/etc ++ * vars - pointer to a pointer area for "environment" variables ++ * varsz - pointer to int to return the size of the vars ++ */ ++void* ++sb_attach(uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ sb_info_t *si; ++ ++ /* alloc sb_info_t */ ++ if ((si = MALLOC(sizeof (sb_info_t))) == NULL) { ++ SB_ERROR(("sb_attach: malloc failed!\n")); ++ return (NULL); ++ } ++ ++ return (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz)); ++} ++ ++/* global kernel resource */ ++static sb_info_t ksi; ++ ++/* generic kernel variant of sb_attach() */ ++void* ++sb_kattach() ++{ ++ uint32 *regs; ++ char *unused; ++ int varsz; ++ ++ if (ksi.curmap == NULL) { ++ uint32 cid; ++ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); ++ cid = R_REG((uint32 *)regs); ++ if ((cid == 0x08104712) || (cid == 0x08114712)) { ++ uint32 *scc, val; ++ ++ scc = (uint32 *)((uint32)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); ++ val = R_REG(scc); ++ SB_ERROR((" initial scc = 0x%x\n", val)); ++ val |= SCC_SS_XTAL; ++ W_REG(scc, val); ++ } ++ ++ sb_doattach(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, ++ SB_BUS, NULL, &unused, &varsz); ++ } ++ ++ return &ksi; ++} ++ ++static void* ++sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 w; ++ ++ ASSERT(GOODREGS(regs)); ++ ++ bzero((uchar*)si, sizeof (sb_info_t)); ++ ++ si->pciidx = si->gpioidx = BADIDX; ++ ++ si->osh = osh; ++ si->curmap = regs; ++ si->sdh = sdh; ++ ++ /* 4317A0 PCMCIA is no longer supported */ ++ if ((bustype == PCMCIA_BUS) && (R_REG((uint32 *)regs) == 0x04104317)) ++ return NULL; ++ ++ /* check to see if we are a sb core mimic'ing a pci core */ ++ if (bustype == PCI_BUS) { ++ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) ++ bustype = SB_BUS; ++ else ++ bustype = PCI_BUS; ++ } ++ ++ si->bus = bustype; ++ ++ /* kludge to enable the clock on the 4306 which lacks a slowclock */ ++ if (si->bus == PCI_BUS) ++ sb_pwrctl_xtal((void*)si, XTAL|PLL, ON); ++ ++ /* clear any previous epidiag-induced target abort */ ++ sb_taclear((void*)si); ++ ++ /* initialize current core index value */ ++ si->curidx = _sb_coreidx((void*)si); ++ ++ /* keep and reuse the initial register mapping */ ++ origidx = si->curidx; ++ if (si->bus == SB_BUS) ++ si->regs[origidx] = regs; ++ ++ /* initialize the vars */ ++ if (srom_var_init(si->bus, si->curmap, osh, vars, varsz)) { ++ SB_ERROR(("sb_attach: srom_var_init failed\n")); ++ goto bad; ++ } ++ ++ if (si->bus == PCMCIA_BUS) { ++ w = getintvar(*vars, "regwindowsz"); ++ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; ++ } ++ ++ /* is core-0 a chipcommon core? */ ++ si->numcores = 1; ++ cc = (chipcregs_t*) sb_setcoreidx((void*)si, 0); ++ if (sb_coreid((void*)si) != SB_CC) ++ cc = NULL; ++ ++ /* determine chip id and rev */ ++ if (cc) { ++ /* chip common core found! */ ++ si->chip = R_REG(&cc->chipid) & CID_ID_MASK; ++ si->chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; ++ si->chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ } else { ++ /* without chip common core, get devid for PCMCIA */ ++ if (si->bus == PCMCIA_BUS) ++ devid = getintvar(*vars, "devid"); ++ ++ /* no chip common core -- must convert device id to chip id */ ++ if ((si->chip = sb_pcidev2chip(devid)) == 0) { ++ SB_ERROR(("sb_attach: unrecognized device id 0x%04x\n", devid)); ++ goto bad; ++ } ++ ++ /* ++ * The chip revision number is hardwired into all ++ * of the pci function config rev fields and is ++ * independent from the individual core revision numbers. ++ * For example, the "A0" silicon of each chip is chip rev 0. ++ * For PCMCIA we get it from the CIS instead. ++ */ ++ if (si->bus == PCMCIA_BUS) { ++ ASSERT(vars); ++ si->chiprev = getintvar(*vars, "chiprev"); ++ } else if (si->bus == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); ++ si->chiprev = w & 0xff; ++ } else ++ si->chiprev = 0; ++ } ++ ++ /* get chipcommon rev */ ++ si->ccrev = cc? sb_corerev((void*)si) : 0; ++ ++ /* determine numcores */ ++ if ((si->ccrev == 4) || (si->ccrev >= 6)) ++ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; ++ else ++ si->numcores = sb_chip2numcores(si->chip); ++ ++ /* return to original core */ ++ sb_setcoreidx((void*)si, origidx); ++ ++ /* sanity checks */ ++ ASSERT(si->chip); ++ /* 4704A1 is chiprev 8 :-( */ ++ ASSERT((si->chiprev < 8) || ++ ((si->chip == BCM4704_DEVICE_ID) && ((si->chiprev == 8)))); ++ ++ /* scan for cores */ ++ sb_scan(si); ++ ++ /* pci core is required */ ++ if (!GOODIDX(si->pciidx)) { ++ SB_ERROR(("sb_attach: pci core not found\n")); ++ goto bad; ++ } ++ ++ /* gpio control core is required */ ++ if (!GOODIDX(si->gpioidx)) { ++ SB_ERROR(("sb_attach: gpio control core not found\n")); ++ goto bad; ++ } ++ ++ /* get boardtype and boardrev */ ++ switch (si->bus) { ++ case PCI_BUS: ++ /* do a pci config read to get subsystem id and subvendor id */ ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); ++ si->boardvendor = w & 0xffff; ++ si->boardtype = (w >> 16) & 0xffff; ++ break; ++ ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ si->boardvendor = getintvar(*vars, "manfid"); ++ si->boardtype = getintvar(*vars, "prodid"); ++ break; ++ ++ case SB_BUS: ++ si->boardvendor = VENDOR_BROADCOM; ++ si->boardtype = 0xffff; ++ break; ++ } ++ ++ if (si->boardtype == 0) { ++ SB_ERROR(("sb_attach: unknown board type\n")); ++ ASSERT(si->boardtype); ++ } ++ ++ return ((void*)si); ++ ++bad: ++ MFREE(si, sizeof (sb_info_t)); ++ return (NULL); ++} ++ ++uint ++sb_coreid(void *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++} ++ ++uint ++sb_coreidx(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->curidx); ++} ++ ++/* return current index of core */ ++static uint ++_sb_coreidx(void *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 sbaddr = 0; ++ ++ si = SB_INFO(sbh); ++ ASSERT(si); ++ ++ switch (si->bus) { ++ case SB_BUS: ++ sb = REGS2SB(si->curmap); ++ sbaddr = sb_base(R_SBREG(sbh, &sb->sbadmatch0)); ++ break; ++ ++ case PCI_BUS: ++ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); ++ break; ++ ++ case PCMCIA_BUS: { ++ uint8 tmp; ++ ++ 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; ++ } ++ default: ++ ASSERT(0); ++ } ++ ++ ASSERT(GOODCOREADDR(sbaddr)); ++ return ((sbaddr - SB_ENUM_BASE)/SB_CORE_SIZE); ++} ++ ++uint ++sb_corevendor(void *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); ++} ++ ++uint ++sb_corerev(void *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return (R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_RC_MASK); ++} ++ ++#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++ ++/* set/clear sbtmstatelow core-specific flags */ ++uint32 ++sb_coreflags(void *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); ++ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(sbh, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(sbh, &sb->sbtmstatelow, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_ALLOW); ++} ++ ++/* set/clear sbtmstatehigh core-specific flags */ ++uint32 ++sb_coreflagshi(void *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); ++ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(sbh, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(sbh, &sb->sbtmstatehigh, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++} ++ ++bool ++sb_iscoreup(void *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(sbh, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK); ++} ++ ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ */ ++static uint ++sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint32 *r; ++ uint w; ++ uint intr_val = 0; ++ ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SB_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); ++ ++ si = SB_INFO(sbh); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(sbh); ++ ++ /* switch core */ ++ INTR_OFF(si, intr_val); ++ r = (uint32*) ((uint) sb_setcoreidx(sbh, coreidx) + regoff); ++ ++ /* mask and set */ ++ if (mask || val) { ++ if (regoff >= SBCONFIGOFF) { ++ w = (R_SBREG(sbh, r) & ~mask) | val; ++ W_SBREG(sbh, r, w); ++ } else { ++ w = (R_REG(r) & ~mask) | val; ++ W_REG(r, w); ++ } ++ } ++ ++ /* readback */ ++ w = R_SBREG(sbh, r); ++ ++ /* restore core index */ ++ if (origidx != coreidx) ++ sb_setcoreidx(sbh, origidx); ++ ++ INTR_RESTORE(si, intr_val); ++ return (w); ++} ++ ++/* scan the sb enumerated space to identify all cores */ ++static void ++sb_scan(sb_info_t *si) ++{ ++ void *sbh; ++ uint origidx; ++ uint i; ++ ++ sbh = (void*) si; ++ ++ /* numcores should already be set */ ++ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(sbh); ++ ++ si->pciidx = si->gpioidx = BADIDX; ++ ++ for (i = 0; i < si->numcores; i++) { ++ sb_setcoreidx(sbh, i); ++ si->coreid[i] = sb_coreid(sbh); ++ ++ if (si->coreid[i] == SB_CC) ++ si->ccrev = sb_corerev(sbh); ++ ++ else if (si->coreid[i] == SB_PCI) { ++ si->pciidx = i; ++ si->pcirev = sb_corerev(sbh); ++ ++ }else if (si->coreid[i] == SB_PCMCIA){ ++ si->pcmciaidx = i; ++ si->pcmciarev = sb_corerev(sbh); ++ } ++ } ++ ++ /* ++ * Find the gpio "controlling core" type and index. ++ * Precedence: ++ * - if there's a chip common core - use that ++ * - 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(sbh, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0); ++ si->gpioid = SB_CC; ++ } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) { ++ si->gpioidx = si->pciidx; ++ si->gpioid = SB_PCI; ++ } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) { ++ si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0); ++ si->gpioid = SB_EXTIF; ++ } ++ ++ /* return to original core index */ ++ sb_setcoreidx(sbh, origidx); ++} ++ ++/* may be called with core in reset */ ++void ++sb_detach(void *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ if (si == NULL) ++ return; ++ ++ if (si->bus == SB_BUS) ++ for (idx = 0; idx < SB_MAXCORES; idx++) ++ if (si->regs[idx]) { ++ REG_UNMAP(si->regs[idx]); ++ si->regs[idx] = NULL; ++ } ++ ++ MFREE(si, sizeof (sb_info_t)); ++} ++ ++/* use pci dev id to determine chip id for chips not having a chipcommon core */ ++static uint ++sb_pcidev2chip(uint pcidev) ++{ ++ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) ++ return (BCM4710_DEVICE_ID); ++ if ((pcidev >= BCM4610_DEVICE_ID) && (pcidev <= BCM4610_USB_ID)) ++ return (BCM4610_DEVICE_ID); ++ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) ++ return (BCM4402_DEVICE_ID); ++ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) ++ return (BCM4307_DEVICE_ID); ++ if (pcidev == BCM4301_DEVICE_ID) ++ return (BCM4301_DEVICE_ID); ++ ++ return (0); ++} ++ ++/* convert chip number to number of i/o cores */ ++static uint ++sb_chip2numcores(uint chip) ++{ ++ if (chip == 0x4710) ++ return (9); ++ if (chip == 0x4610) ++ return (9); ++ if (chip == 0x4402) ++ return (3); ++ if ((chip == 0x4307) || (chip == 0x4301)) ++ return (5); ++ if (chip == 0x4310) ++ return (8); ++ if (chip == 0x4306) /* < 4306c0 */ ++ return (6); ++ if (chip == 0x4704) ++ return (9); ++ if (chip == 0x5365) ++ return (7); ++ ++ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); ++ ASSERT(0); ++ return (1); ++} ++ ++/* return index of coreid or BADIDX if not found */ ++static uint ++sb_findcoreidx(void *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++) ++ if (si->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } ++ ++ return (BADIDX); ++} ++ ++/* change logical "focus" to the indiciated core */ ++void* ++sb_setcoreidx(void *sbh, uint coreidx) ++{ ++ sb_info_t *si; ++ uint32 sbaddr; ++ uint8 tmp; ++ ++ si = SB_INFO(sbh); ++ ++ if (coreidx >= si->numcores) ++ return (NULL); ++ ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((si->imf == NULL) || !(*si->imf)(si->imfarg)); ++ ++ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++ ++ switch (si->bus) { ++ case SB_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++ ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); ++ break; ++ ++ case PCMCIA_BUS: ++ tmp = (sbaddr >> 12) & 0x0f; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ tmp = (sbaddr >> 16) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ tmp = (sbaddr >> 24) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ break; ++ } ++ ++ si->curidx = coreidx; ++ ++ return (si->curmap); ++} ++ ++/* change logical "focus" to the indicated core */ ++void* ++sb_setcore(void *sbh, uint coreid, uint coreunit) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ idx = sb_findcoreidx(sbh, coreid, coreunit); ++ if (!GOODIDX(idx)) ++ return (NULL); ++ ++ return (sb_setcoreidx(sbh, idx)); ++} ++ ++/* return chip number */ ++uint ++sb_chip(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->chip); ++} ++ ++/* return chip revision number */ ++uint ++sb_chiprev(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->chiprev); ++} ++ ++/* return chip package option */ ++uint ++sb_chippkg(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->chippkg); ++} ++ ++/* return board vendor id */ ++uint ++sb_boardvendor(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->boardvendor); ++} ++ ++/* return boardtype */ ++uint ++sb_boardtype(void *sbh) ++{ ++ sb_info_t *si; ++ char *var; ++ ++ si = SB_INFO(sbh); ++ ++ if (si->bus == SB_BUS && si->boardtype == 0xffff) { ++ /* boardtype format is a hex string */ ++ si->boardtype = getintvar(NULL, "boardtype"); ++ ++ /* backward compatibility for older boardtype string format */ ++ if ((si->boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if (!strcmp(var, "bcm94710dev")) ++ si->boardtype = BCM94710D_BOARD; ++ else if (!strcmp(var, "bcm94710ap")) ++ si->boardtype = BCM94710AP_BOARD; ++ else if (!strcmp(var, "bcm94310u")) ++ si->boardtype = BCM94310U_BOARD; ++ else if (!strcmp(var, "bu4711")) ++ si->boardtype = BU4711_BOARD; ++ else if (!strcmp(var, "bu4710")) ++ si->boardtype = BU4710_BOARD; ++ else if (!strcmp(var, "bcm94702mn")) ++ si->boardtype = BCM94702MN_BOARD; ++ else if (!strcmp(var, "bcm94710r1")) ++ si->boardtype = BCM94710R1_BOARD; ++ else if (!strcmp(var, "bcm94710r4")) ++ si->boardtype = BCM94710R4_BOARD; ++ else if (!strcmp(var, "bcm94702cpci")) ++ si->boardtype = BCM94702CPCI_BOARD; ++ else if (!strcmp(var, "bcm95380_rr")) ++ si->boardtype = BCM95380RR_BOARD; ++ } ++ } ++ ++ return (si->boardtype); ++} ++ ++/* return board bus style */ ++uint ++sb_boardstyle(void *sbh) ++{ ++ sb_info_t *si; ++ uint16 w; ++ ++ si = SB_INFO(sbh); ++ ++ if (si->bus == PCMCIA_BUS) ++ return (BOARDSTYLE_PCMCIA); ++ ++ if (si->bus == SB_BUS) ++ return (BOARDSTYLE_SOC); ++ ++ /* bus is PCI */ ++ ++ if (OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CIS, sizeof (uint32)) != 0) ++ return (BOARDSTYLE_CARDBUS); ++ ++ if ((srom_read(si->bus, si->curmap, si->osh, (SPROM_SIZE - 1) * 2, 2, &w) == 0) && ++ (w == 0x0313)) ++ return (BOARDSTYLE_CARDBUS); ++ ++ return (BOARDSTYLE_PCI); ++} ++ ++/* return boolean if sbh device is in pci hostmode or client mode */ ++uint ++sb_bus(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->bus); ++} ++ ++/* return list of found cores */ ++uint ++sb_corelist(void *sbh, uint coreid[]) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); ++ return (si->numcores); ++} ++ ++/* return current register mapping */ ++void * ++sb_coreregs(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ ++ return (si->curmap); ++} ++ ++/* Check if a target abort has happened and clear it */ ++bool ++sb_taclear(void *sbh) ++{ ++ sb_info_t *si; ++ bool rc = FALSE; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ if (si->bus == PCI_BUS) { ++ uint32 stcmd; ++ ++ stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(stcmd)); ++ rc = (stcmd & 0x08000000) != 0; ++ ++ if (rc) { ++ /* Target abort bit is set, clear it */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD, sizeof(stcmd), stcmd); ++ } ++ } else if (si->bus == PCMCIA_BUS) { ++ rc = FALSE; ++ } ++ else if (si->bus == SDIO_BUS) { ++ /* due to 4317 A0 HW bug, sdio core wedged on target abort, ++ just clear SBSErr bit blindly */ ++ if (0x0 != R_SBREG(sbh, &sb->sbtmerrlog)) { ++ SB_ERROR(("SDIO target abort, clean it")); ++ W_SBREG(sbh, &sb->sbtmstatehigh, 0); ++ } ++ rc = FALSE; ++ } ++ ++ return (rc); ++} ++ ++/* do buffered registers update */ ++void ++sb_commit(void *sbh) ++{ ++ sb_info_t *si; ++ sbpciregs_t *pciregs; ++ uint origidx; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ASSERT(GOODIDX(origidx)); ++ ++ INTR_OFF(si, intr_val); ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&pciregs->bcastaddr, SB_COMMIT); ++ W_REG(&pciregs->bcastdata, 0x0); ++ ++ /* restore core index */ ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++} ++ ++/* reset and re-enable a core */ ++void ++sb_core_reset(void *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ volatile uint32 dummy; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ sb_core_disable(sbh, bits); ++ ++ /* ++ * Now do the initialization sequence. ++ */ ++ ++ /* set reset while enabling the clock and forcing them on throughout the core */ ++ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); ++ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ ++ if (sb_coreid(sbh) == SB_ILINE100) { ++ bcm_mdelay(50); ++ } else { ++ OSL_DELAY(1); ++ } ++ ++ if (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(sbh, &sb->sbtmstatehigh, 0); ++ } ++ if ((dummy = R_SBREG(sbh, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { ++ AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ } ++ ++ /* clear reset and allow it to propagate throughout the core */ ++ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ /* leave clock enabled */ ++ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++} ++ ++void ++sb_core_tofixup(void *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if (si->pcirev >= 5) ++ return; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ if (si->bus == SB_BUS) { ++ SET_SBREG(sbh, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ } else { ++ if (sb_coreid(sbh) == SB_PCI) { ++ SET_SBREG(sbh, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ } else { ++ SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ } ++ } ++ ++ sb_commit(sbh); ++} ++ ++void ++sb_core_disable(void *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ volatile uint32 dummy; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* must return if core is already in reset */ ++ if (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_RESET) ++ return; ++ ++ /* put into reset and return if clocks are not enabled */ ++ if ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ goto disable; ++ ++ /* set the reject bit */ ++ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ)); ++ ++ /* spin until reject is set */ ++ while ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_REJ) == 0) ++ OSL_DELAY(1); ++ ++ /* spin until sbtmstatehigh.busy is clear */ ++ while (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_BUSY) ++ OSL_DELAY(1); ++ ++ /* set reset and reject while enabling the clocks */ ++ W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET)); ++ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ OSL_DELAY(10); ++ ++ disable: ++ /* leave reset and reject asserted */ ++ W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET)); ++ OSL_DELAY(1); ++} ++ ++void ++sb_watchdog(void *sbh, uint ticks) ++{ ++ sb_info_t *si = SB_INFO(sbh); ++ ++ /* instant NMI */ ++ switch (si->gpioid) { ++ case SB_CC: ++ sb_corereg(sbh, si->gpioidx, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ break; ++ case SB_EXTIF: ++ sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ break; ++ } ++} ++ ++/* initialize the pcmcia core */ ++void ++sb_pcmcia_init(void *sbh) ++{ ++ sb_info_t *si; ++ uint8 cor; ++ ++ si = SB_INFO(sbh); ++ ++ /* enable d11 mac interrupts */ ++ if (si->chip == BCM4301_DEVICE_ID) { ++ /* Have to use FCR2 in 4301 */ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ } else { ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ } ++ ++} ++ ++ ++/* ++ * Configure the pci core for pci client (NIC) action ++ * and get appropriate dma offset value. ++ * coremask is the bitvec of cores by index to be enabled. ++ */ ++void ++sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ sbpciregs_t *pciregs; ++ uint32 sbflag; ++ uint32 w; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ if (dmaoffset) ++ *dmaoffset = 0; ++ ++ /* if not pci bus, we're done */ ++ if (si->bus != PCI_BUS) ++ return; ++ ++ ASSERT(si->pciidx); ++ ++ /* get current core index */ ++ idx = si->curidx; ++ ++ /* we interrupt on this backplane flag number */ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ sbflag = R_SBREG(sbh, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx); ++ sb = REGS2SB(pciregs); ++ ++ /* ++ * Enable sb->pci interrupts. Assume ++ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. ++ */ ++ if (si->pcirev < 6) { ++ /* set sbintvec bit for our flag number */ ++ OR_SBREG(sbh, &sb->sbintvec, (1 << sbflag)); ++ } else { ++ /* pci config write to set this core bit in PCIIntMask */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); ++ w |= (coremask << PCI_SBIM_SHIFT); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); ++ } ++ ++ /* enable prefetch and bursts for sonics-to-pci translation 2 */ ++ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ ++ if (si->pcirev < 5) { ++ SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ sb_commit(sbh); ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ /* use large sb pci dma window */ ++ if (dmaoffset) ++ *dmaoffset = SB_PCI_DMA; ++} ++ ++uint32 ++sb_base(uint32 admatch) ++{ ++ uint32 base; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ base = 0; ++ ++ if (type == 0) { ++ base = admatch & SBAM_BASE0_MASK; ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE1_MASK; ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE2_MASK; ++ } ++ ++ return (base); ++} ++ ++uint32 ++sb_size(uint32 admatch) ++{ ++ uint32 size; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ size = 0; ++ ++ if (type == 0) { ++ 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); ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); ++ } ++ ++ return (size); ++} ++ ++/* return the core-type instantiation # of the current core */ ++uint ++sb_coreunit(void *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; ++ ++ si = SB_INFO(sbh); ++ coreunit = 0; ++ ++ idx = si->curidx; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ coreid = sb_coreid(sbh); ++ ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) ++ if (si->coreid[i] == coreid) ++ coreunit++; ++ ++ return (coreunit); ++} ++ ++static INLINE uint32 ++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; ++ } ++} ++ ++/* 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 n1, n2, clock, m1, m2, m3, mc; ++ ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE3) { ++ return (100000000); ++ } else ++ ASSERT((pll_type >= PLL_TYPE1) && (pll_type <= PLL_TYPE4)); ++ ++ clock = CC_CLOCK_BASE * n1 * n2; ++ ++ if (clock == 0) ++ return 0; ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { ++ m1 = factor6(m1); ++ if (pll_type == PLL_TYPE1) ++ m2 += CC_F5_BIAS; ++ else ++ m2 = factor6(m2); ++ 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); ++ } ++ } else { ++ ASSERT(pll_type == PLL_TYPE2); ++ ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); ++ ++ if ((mc & CC_T2MC_M1BYP) == 0) ++ clock /= m1; ++ if ((mc & CC_T2MC_M2BYP) == 0) ++ clock /= m2; ++ if ((mc & CC_T2MC_M3BYP) == 0) ++ clock /= m3; ++ ++ return(clock); ++ } ++} ++ ++/* returns the current speed the SB is running at */ ++uint32 ++sb_clock(void *sbh) ++{ ++ sb_info_t *si; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ idx = si->curidx; ++ pll_type = PLL_TYPE1; ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ m = R_REG(&cc->clockcontrol_sb); ++ } else { ++ INTR_RESTORE(si, intr_val); ++ return 0; ++ } ++ ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ INTR_RESTORE(si, intr_val); ++ ++ return rate; ++} ++ ++/* change logical "focus" to the gpio core for optimized access */ ++void* ++sb_gpiosetcore(void *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (sb_setcoreidx(sbh, si->gpioidx)); ++} ++ ++/* mask&set gpiocontrol bits */ ++uint32 ++sb_gpiocontrol(void *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiocontrol); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); ++ break; ++ ++ case SB_EXTIF: ++ return (0); ++ } ++ ++ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output enable bits */ ++uint32 ++sb_gpioouten(void *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioouten); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].outen); ++ break; ++ } ++ ++ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output bits */ ++uint32 ++sb_gpioout(void *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ break; ++ } ++ ++ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++} ++ ++/* return the current gpioin register value */ ++uint32 ++sb_gpioin(void *sbh) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioin); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioin); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpioin); ++ break; ++ } ++ ++ return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0)); ++} ++ ++/* mask&set gpio interrupt polarity bits */ ++uint32 ++sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt polarity */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ break; ++ } ++ ++ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio interrupt mask bits */ ++uint32 ++sb_gpiointmask(void *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt mask */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointmask); ++ break; ++ } ++ ++ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++} ++ ++ ++/* ++ * Return the slowclock min or max frequency. ++ * Three sources of SLOW CLOCK: ++ * 1. On Chip LPO - 32khz or 160khz ++ * 2. On Chip Xtal OSC - 20mhz/4*(divider+1) ++ * 3. External PCI clock - 66mhz/4*(divider+1) ++ */ ++static uint ++slowfreq(void *sbh, bool max) ++{ ++ sb_info_t *si; ++ chipcregs_t *cc; ++ uint32 v; ++ uint div; ++ ++ si = SB_INFO(sbh); ++ ++ ASSERT(sb_coreid(sbh) == SB_CC); ++ ++ cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx); ++ ++ /* shouldn't be here unless we've established the chip has dynamic power control */ ++ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); ++ ++ if (si->ccrev < 6) { ++ v = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); ++ ++ if (v & PCI_CFG_GPIO_SCS) ++ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); ++ else ++ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); ++ } else { ++ v = R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; ++ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1); ++ if (v == SCC_SS_LPO) ++ return (max? LPOMAXFREQ : LPOMINFREQ); ++ else if (v == SCC_SS_XTAL) ++ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); ++ else if (v == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); ++ else ++ ASSERT(0); ++ } ++ return (0); ++} ++ ++/* initialize power control delay registers */ ++void ++sb_pwrctl_init(void *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowmaxfreq; ++ uint pll_on_delay, fref_sel_delay; ++ ++ si = SB_INFO(sbh); ++ ++ if (si->bus == SB_BUS) ++ return; ++ ++ origidx = si->curidx; ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ return; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ slowmaxfreq = slowfreq(sbh, TRUE); ++ pll_on_delay = ((slowmaxfreq * PLL_DELAY) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ ++ W_REG(&cc->pll_on_delay, pll_on_delay); ++ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++ ++ /* 4317pc does not work with SlowClock less than 5Mhz */ ++ if (si->bus == PCMCIA_BUS) ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (0 << SCC_CD_SHF)); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++} ++ ++/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ ++uint16 ++sb_pwrctl_fast_pwrup_delay(void *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowminfreq; ++ uint16 fpdelay; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ fpdelay = 0; ++ origidx = si->curidx; ++ ++ if (si->bus == SB_BUS) ++ goto done; ++ ++ INTR_OFF(si, intr_val); ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ goto done; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ slowminfreq = slowfreq(sbh, FALSE); ++ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (fpdelay); ++} ++ ++/* turn primary xtal and/or pll off/on */ ++int ++sb_pwrctl_xtal(void *sbh, uint what, bool on) ++{ ++ sb_info_t *si; ++ uint32 in, out, outen; ++ ++ si = SB_INFO(sbh); ++ ++ ++ if (si->bus == PCMCIA_BUS) { ++ return (0); ++ } ++ ++ if (si->bus != PCI_BUS) ++ 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)); ++ ++ /* ++ * 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(200); ++ } ++ ++ /* 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); ++ } ++ ++ return (0); ++} ++ ++/* set dynamic power control mode (forceslow, forcefast, dynamic) */ ++/* returns true if ignore pll off is set and false if it is not */ ++bool ++sb_pwrctl_clk(void *sbh, uint mode) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 scc; ++ bool forcefastclk=FALSE; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ ++ if (si->ccrev < 6) ++ return (FALSE); ++ ++ INTR_OFF(si, intr_val); ++ ++ origidx = si->curidx; ++ ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ switch (mode) { ++ case CLK_FAST: /* force fast (pll) clock */ ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ sb_pwrctl_xtal(sbh, XTAL, ON); ++ ++ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ break; ++ ++ case CLK_SLOW: /* force slow clock */ ++ if ((si->bus == SDIO_BUS) || (si->bus == PCMCIA_BUS)) ++ return (-1); ++ ++ if (si->ccrev >= 6) ++ OR_REG(&cc->slow_clk_ctl, SCC_FS); ++ break; ++ ++ case CLK_DYNAMIC: /* enable dynamic power control */ ++ scc = R_REG(&cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) ++ scc |= SCC_XC; ++ W_REG(&cc->slow_clk_ctl, scc); ++ ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) ++ sb_pwrctl_xtal(sbh, XTAL, OFF); ++ break; ++ } ++ ++ /* Is the h/w forcing the use of the fast clk */ ++ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (forcefastclk); ++} ++ ++/* register driver interrupt disabling and restoring callback functions */ ++void ++sb_register_intr_callback(void *sbh, void *intrsoff_fn, void *intrsrestore_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; ++ /* 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]; ++} ++ ++ +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h 2005-08-28 11:12:20.430859152 +0200 @@ -0,0 +1,90 @@ +/* + * BCM4710 address space map and definitions @@ -4022,9 +7817,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcm4710.h linux-2.6. + } + +#endif /* _bcm4710_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmdevs.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmdevs.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmdevs.h 2005-08-28 11:12:20.431859000 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h 2005-08-28 11:12:20.431859000 +0200 @@ -0,0 +1,238 @@ +/* + * Broadcom device-specific manifest constants. @@ -4264,9 +8059,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmdevs.h linux-2.6. +#define CT4702AP_BOARD 0x0447 + +#endif /* _BCMDEVS_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmendian.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmendian.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmendian.h 2005-08-28 11:12:20.431859000 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-08-28 11:12:20.431859000 +0200 @@ -0,0 +1,125 @@ +/******************************************************************************* + * $Id$ @@ -4393,9 +8188,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmendian.h linux-2. +} + +#endif /* _BCMENDIAN_H_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenet47xx.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmenet47xx.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenet47xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmenet47xx.h 2005-08-28 11:12:20.432858848 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h 2005-08-28 11:12:20.432858848 +0200 @@ -0,0 +1,229 @@ +/* + * Hardware-specific definitions for @@ -4626,9 +8421,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenet47xx.h linux- +#include <bcmenetrxh.h> + +#endif /* _bcmenet_47xx_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenetmib.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmenetmib.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenetmib.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmenetmib.h 2005-08-28 11:12:20.432858848 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h 2005-08-28 11:12:20.432858848 +0200 @@ -0,0 +1,81 @@ +/* + * Hardware-specific MIB definition for @@ -4711,9 +8506,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenetmib.h linux-2 +} bcmenetmib_t; + +#endif /* _bcmenetmib_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenetrxh.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmenetrxh.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenetrxh.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmenetrxh.h 2005-08-28 11:12:20.433858696 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h 2005-08-28 11:12:20.433858696 +0200 @@ -0,0 +1,43 @@ +/* + * Hardware-specific Receive Data Header for the @@ -4758,16 +8553,16 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmenetrxh.h linux-2 +#define RXF_OV ((uint16)1 << 0) /* fifo overflow */ + +#endif /* _bcmenetrxh_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmnvram.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmnvram.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmnvram.h 2005-08-28 11:12:20.433858696 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-08-28 11:12:20.433858696 +0200 @@ -0,0 +1,131 @@ +/* + * NVRAM variable manipulation + * + * $Copyright Open Broadcom Corporation$ + * -+ * $Id$ ++ * $Id: bcmnvram.h,v 1.1.1.1 2004/01/21 03:50:44 gigis Exp $ + */ + +#ifndef _bcmnvram_h_ @@ -4893,9 +8688,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmnvram.h linux-2.6 +#define NVRAM_LAST_LOC (0xc0000000 - NVRAM_SPACE) + +#endif /* _bcmnvram_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmsrom.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmsrom.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmsrom.h 2005-08-28 11:12:20.433858696 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-08-28 11:12:20.433858696 +0200 @@ -0,0 +1,24 @@ +/* + * Misc useful routines to access NIC srom @@ -4921,9 +8716,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmsrom.h linux-2.6. +extern int srom_parsecis(uint8 *cis, char **vars, int *count); + +#endif /* _bcmsrom_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmutils.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmutils.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bcmutils.h 2005-08-28 11:12:20.435858392 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h 2005-08-28 11:12:20.435858392 +0200 @@ -0,0 +1,136 @@ +/* + * Misc useful os-independent macros and functions. @@ -5061,9 +8856,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bcmutils.h linux-2.6 +#define bcmdumplog(buf, size) *buf = '\0' + +#endif /* _bcmutils_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bitfuncs.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bitfuncs.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/bitfuncs.h 2005-08-28 11:12:20.435858392 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h 2005-08-28 11:12:20.435858392 +0200 @@ -0,0 +1,85 @@ +/* + * bit manipulation utility functions @@ -5150,9 +8945,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/bitfuncs.h linux-2.6 +#endif + +#endif /* _BITFUNCS_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/epivers.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/epivers.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/epivers.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/epivers.h 2005-08-28 11:12:20.435858392 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h 2005-08-28 11:12:20.435858392 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright 2001-2003, Broadcom Corporation @@ -5223,9 +9018,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/epivers.h linux-2.6. +#define EPI_ROUTER_VERSION_STR "1.1.2.0" + +#endif /* _epivers_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/epivers.h.in linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/epivers.h.in ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/epivers.h.in 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/epivers.h.in 2005-08-28 11:12:20.436858240 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in +--- linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in 2005-08-28 11:12:20.436858240 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright 2001-2003, Broadcom Corporation @@ -5296,9 +9091,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/epivers.h.in linux-2 +#define EPI_ROUTER_VERSION_STR "@EPI_ROUTER_VERSION_STR@" + +#endif /* _epivers_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/etsockio.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/etsockio.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/etsockio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/etsockio.h 2005-08-28 11:12:20.436858240 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h 2005-08-28 11:12:20.436858240 +0200 @@ -0,0 +1,60 @@ +/* + * Driver-specific socket ioctls @@ -5360,9 +9155,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/etsockio.h linux-2.6 +}; + +#endif -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/flash.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/flash.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/flash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/flash.h 2005-08-28 11:12:20.437858088 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h 2005-08-28 11:12:20.437858088 +0200 @@ -0,0 +1,184 @@ +/* + * flash.h: Common definitions for flash access. @@ -5548,9 +9343,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/flash.h linux-2.6.12 +extern flash_desc_t flashes[]; + +#endif -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/flashutl.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/flashutl.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/flashutl.h 2005-08-28 11:12:20.437858088 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h 2005-08-28 11:12:20.437858088 +0200 @@ -0,0 +1,34 @@ +/* + * BCM47XX FLASH driver interface @@ -5586,9 +9381,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/flashutl.h linux-2.6 +extern flash_cmds_t* flashutl_cmd; + +#endif /* _flashutl_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/hnddma.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/hnddma.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/hnddma.h 2005-08-28 11:12:20.438857936 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-08-28 11:12:20.438857936 +0200 @@ -0,0 +1,181 @@ +/* + * Generic Broadcom Home Networking Division (HND) DMA engine definitions. @@ -5771,9 +9566,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/hnddma.h linux-2.6.1 +extern uint dma_txactive(di_t *di); + +#endif /* _hnddma_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/hndmips.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/hndmips.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/hndmips.h 2005-08-28 11:12:20.439857784 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-08-28 11:12:20.439857784 +0200 @@ -0,0 +1,16 @@ +/* + * Alternate include file for HND sbmips.h since CFE also ships with @@ -5791,9 +9586,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/hndmips.h linux-2.6. + */ + +#include "sbmips.h" -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/linux_osl.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/linux_osl.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/linux_osl.h 2005-08-28 11:12:20.440857632 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-08-28 11:12:20.440857632 +0200 @@ -0,0 +1,313 @@ +/* + * Linux OS Independent Layer @@ -6108,9 +9903,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/linux_osl.h linux-2. +#endif /* BINOSL */ + +#endif /* _linux_osl_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/linuxver.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/linuxver.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/linuxver.h 2005-08-28 11:12:20.441857480 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-08-28 11:12:20.441857480 +0200 @@ -0,0 +1,326 @@ +/* + * Linux-specific abstractions to gain some independence from linux kernel versions. @@ -6438,9 +10233,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/linuxver.h linux-2.6 +#endif + +#endif /* _linuxver_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/nvports.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/nvports.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/nvports.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/nvports.h 2005-08-28 11:12:20.441857480 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h 2005-08-28 11:12:20.441857480 +0200 @@ -0,0 +1,62 @@ +/* + * Broadcom Home Gateway Reference Design @@ -6504,9 +10299,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/nvports.h linux-2.6. + + + -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/osl.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/osl.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/osl.h 2005-08-28 11:12:20.441857480 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h 2005-08-28 11:12:20.441857480 +0200 @@ -0,0 +1,38 @@ +/* + * OS Independent Layer @@ -6546,9 +10341,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/osl.h linux-2.6.12.5 +#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) + +#endif /* _osl_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/pcicfg.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/pcicfg.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/pcicfg.h 2005-08-28 11:12:20.442857328 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-08-28 11:12:20.442857328 +0200 @@ -0,0 +1,362 @@ +/* + * pcicfg.h: PCI configuration constants and structures. @@ -6912,9 +10707,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/pcicfg.h linux-2.6.1 +#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ + +#endif -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/proto/802.11.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/proto/802.11.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/proto/802.11.h 2005-08-28 11:12:20.450856112 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h 2005-08-28 11:12:20.450856112 +0200 @@ -0,0 +1,679 @@ +/* + * Copyright 2001-2003, Broadcom Corporation @@ -7595,9 +11390,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/proto/802.11.h linux +#endif + +#endif /* _802_11_H_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/proto/ethernet.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/proto/ethernet.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/proto/ethernet.h 2005-08-28 11:12:20.450856112 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h 2005-08-28 11:12:20.450856112 +0200 @@ -0,0 +1,145 @@ +/******************************************************************************* + * $Id$ @@ -7744,9 +11539,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/proto/ethernet.h lin +#undef PACKED + +#endif /* _NET_ETHERNET_H_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/rts/crc.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/rts/crc.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/rts/crc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/rts/crc.h 2005-08-28 11:12:20.451855960 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h 2005-08-28 11:12:20.451855960 +0200 @@ -0,0 +1,69 @@ +/******************************************************************************* + * $Id$ @@ -7817,9 +11612,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/rts/crc.h linux-2.6. +#endif + +#endif /* _RTS_CRC_H_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/s5.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/s5.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/s5.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/s5.h 2005-08-28 11:12:20.451855960 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h 2005-08-28 11:12:20.451855960 +0200 @@ -0,0 +1,103 @@ +#ifndef _S5_H_ +#define _S5_H_ @@ -7835,7 +11630,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/s5.h linux-2.6.12.5- + * published by the Free Software Foundation, located in the file + * LICENSE. + * -+ * $Id$ ++ * $Id: s5.h,v 1.3 2003/06/10 18:54:51 jfd Exp $ + * + */ + @@ -7924,9 +11719,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/s5.h linux-2.6.12.5- + + +#endif /*!_S5_H_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbchipc.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbchipc.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbchipc.h 2005-08-28 11:12:20.468853376 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-08-28 11:12:20.468853376 +0200 @@ -0,0 +1,281 @@ +/* + * SiliconBackplane Chipcommon core hardware definitions. @@ -8209,9 +12004,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbchipc.h linux-2.6. +#define SFLASH_AT_ID_SHIFT 3 + +#endif /* _SBCHIPC_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbconfig.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbconfig.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbconfig.h 2005-08-28 11:12:20.469853224 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h 2005-08-28 11:12:20.469853224 +0200 @@ -0,0 +1,296 @@ +/* + * Broadcom SiliconBackplane hardware register definitions. @@ -8509,9 +12304,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbconfig.h linux-2.6 +#define SB_ROBO 0x81C /* robo switch core */ + +#endif /* _SBCONFIG_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbextif.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbextif.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbextif.h 2005-08-28 11:12:20.470853072 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h 2005-08-28 11:12:20.470853072 +0200 @@ -0,0 +1,242 @@ +/* + * Hardware-specific External Interface I/O core definitions @@ -8755,9 +12550,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbextif.h linux-2.6. +#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ + +#endif /* _SBEXTIF_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbmemc.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbmemc.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbmemc.h 2005-08-28 11:12:20.471852920 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h 2005-08-28 11:12:20.471852920 +0200 @@ -0,0 +1,144 @@ +/* + * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. @@ -8903,9 +12698,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbmemc.h linux-2.6.1 +#define MEMC_CONFIG_DDR 0x00000001 + +#endif /* _SBMEMC_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbmips.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbmips.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbmips.h 2005-08-28 11:12:20.471852920 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h 2005-08-28 11:12:20.471852920 +0200 @@ -0,0 +1,56 @@ +/* + * Broadcom SiliconBackplane MIPS definitions @@ -8963,9 +12758,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbmips.h linux-2.6.1 +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* _SBMIPS_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbpci.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbpci.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbpci.h 2005-08-28 11:12:20.471852920 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h 2005-08-28 11:12:20.471852920 +0200 @@ -0,0 +1,113 @@ +/* + * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. @@ -9080,9 +12875,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbpci.h linux-2.6.12 +#endif /* !_LANGUAGE_ASSEMBLY */ + +#endif /* _SBPCI_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbpcmcia.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbpcmcia.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbpcmcia.h 2005-08-28 11:12:20.472852768 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h 2005-08-28 11:12:20.472852768 +0200 @@ -0,0 +1,131 @@ +/* + * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. @@ -9215,9 +13010,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbpcmcia.h linux-2.6 +#define HNBU_LED 0x09 /* LED set */ + +#endif /* _SBPCMCIA_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbsdram.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbsdram.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbsdram.h 2005-08-28 11:12:20.472852768 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h 2005-08-28 11:12:20.472852768 +0200 @@ -0,0 +1,75 @@ +/* + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. @@ -9294,9 +13089,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbsdram.h linux-2.6. +#define MEM8MX16X2 0xc29 /* 32 MB */ + +#endif /* _SBSDRAM_H */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbutils.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbutils.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sbutils.h 2005-08-28 11:12:20.473852616 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h 2005-08-28 11:12:20.473852616 +0200 @@ -0,0 +1,90 @@ +/* + * Misc utility routines for accessing chip-specific features @@ -9388,9 +13183,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sbutils.h linux-2.6. +#define CLK_DYNAMIC 2 /* enable dynamic power control */ + +#endif /* _sbutils_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sflash.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sflash.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/sflash.h 2005-08-28 11:12:20.473852616 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sflash.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sflash.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sflash.h 2005-08-28 11:12:20.473852616 +0200 @@ -0,0 +1,46 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface @@ -9438,9 +13233,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/sflash.h linux-2.6.1 +extern struct sflash * sflash_init(chipcregs_t *cc); + +#endif /* _sflash_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/trxhdr.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/trxhdr.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/trxhdr.h 2005-08-28 11:12:20.474852464 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h 2005-08-28 11:12:20.474852464 +0200 @@ -0,0 +1,31 @@ +/* + * TRX image file header format. @@ -9473,9 +13268,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/trxhdr.h linux-2.6.1 + +/* Compatibility */ +typedef struct trx_header TRXHDR, *PTRXHDR; -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/typedefs.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/typedefs.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/typedefs.h 2005-08-28 11:12:20.474852464 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h 2005-08-28 11:12:20.474852464 +0200 @@ -0,0 +1,162 @@ +/* + * Copyright 2001-2003, Broadcom Corporation @@ -9639,9 +13434,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/typedefs.h linux-2.6 +#endif /* INLINE */ + +#endif /* _TYPEDEFS_H_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/wlioctl.h linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/wlioctl.h ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/wlioctl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/include/wlioctl.h 2005-08-28 11:12:20.475852312 +0200 +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h +--- linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h 2005-08-28 11:12:20.475852312 +0200 @@ -0,0 +1,690 @@ +/* + * Custom OID/ioctl definitions for @@ -10333,5230 +14128,34 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/include/wlioctl.h linux-2.6. +#undef PACKED + +#endif /* _wlioctl_h_ */ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/linux_osl.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/linux_osl.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/linux_osl.c 2005-08-28 11:12:20.476852160 +0200 -@@ -0,0 +1,420 @@ +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S +--- linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S 2005-08-28 16:58:08.027788792 +0200 +@@ -0,0 +1,48 @@ +/* -+ * Linux OS Independent Layer ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) + * -+ * 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. ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. + * -+ * $Id$ -+ */ -+ -+#define LINUX_OSL -+ -+#include <typedefs.h> -+#include <bcmendian.h> -+#include <linuxver.h> -+#include <linux_osl.h> -+#include <bcmutils.h> -+#include <linux/delay.h> -+#ifdef mips -+#include <asm/paccess.h> -+#endif -+#include <pcicfg.h> -+ -+#define PCI_CFG_RETRY 10 -+ -+void* -+osl_pktget(void *drv, uint len, bool send) -+{ -+ struct sk_buff *skb; -+ -+ if ((skb = dev_alloc_skb(len)) == NULL) -+ return (NULL); -+ -+ skb_put(skb, len); -+ -+ /* ensure the cookie field is cleared */ -+ PKTSETCOOKIE(skb, NULL); -+ -+ return ((void*) skb); -+} -+ -+void -+osl_pktfree(void *p) -+{ -+ struct sk_buff *skb, *nskb; -+ -+ skb = (struct sk_buff*) p; -+ -+ /* perversion: we use skb->next to chain multi-skb packets */ -+ while (skb) { -+ nskb = skb->next; -+ skb->next = NULL; -+ if (skb->destructor) { -+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ -+ dev_kfree_skb_any(skb); -+ } else { -+ /* can free immediately (even in_irq()) if destructor does not exist */ -+ dev_kfree_skb(skb); -+ } -+ skb = nskb; -+ } -+} -+ -+uint32 -+osl_pci_read_config(void *loc, uint offset, uint size) -+{ -+ struct pci_dev *pdev; -+ uint val; -+ uint retry=PCI_CFG_RETRY; -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ pdev = (struct pci_dev*)loc; -+ do { -+ pci_read_config_dword(pdev, offset, &val); -+ if (val != 0xffffffff) -+ break; -+ } while (retry--); -+ -+ -+ return (val); -+} -+ -+void -+osl_pci_write_config(void *loc, uint offset, uint size, uint val) -+{ -+ struct pci_dev *pdev; -+ uint retry=PCI_CFG_RETRY; -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ pdev = (struct pci_dev*)loc; -+ -+ do { -+ pci_write_config_dword(pdev, offset, val); -+ if (offset!=PCI_BAR0_WIN) -+ break; -+ if (osl_pci_read_config(loc,offset,size) == val) -+ break; -+ } while (retry--); -+ -+} -+ -+void -+osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size) -+{ -+ ASSERT(0); -+} -+ -+void -+osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size) -+{ -+ ASSERT(0); -+} -+ -+void -+osl_assert(char *exp, char *file, int line) -+{ -+ char tempbuf[255]; -+ -+ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); -+ panic(tempbuf); -+} -+ -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ */ -+#ifdef BINOSL -+ -+int -+osl_printf(const char *format, ...) -+{ -+ va_list args; -+ char buf[1024]; -+ int len; -+ -+ /* sprintf into a local buffer because there *is* no "vprintk()".. */ -+ va_start(args, format); -+ len = vsprintf(buf, format, args); -+ va_end(args); -+ -+ if (len > sizeof (buf)) { -+ printk("osl_printf: buffer overrun\n"); -+ return (0); -+ } -+ -+ return (printk(buf)); -+} -+ -+int -+osl_sprintf(char *buf, const char *format, ...) -+{ -+ va_list args; -+ int rc; -+ -+ va_start(args, format); -+ rc = vsprintf(buf, format, args); -+ va_end(args); -+ return (rc); -+} -+ -+int -+osl_strcmp(const char *s1, const char *s2) -+{ -+ return (strcmp(s1, s2)); -+} -+ -+int -+osl_strncmp(const char *s1, const char *s2, uint n) -+{ -+ return (strncmp(s1, s2, n)); -+} -+ -+int -+osl_strlen(char *s) -+{ -+ return (strlen(s)); -+} -+ -+char* -+osl_strcpy(char *d, const char *s) -+{ -+ return (strcpy(d, s)); -+} -+ -+char* -+osl_strncpy(char *d, const char *s, uint n) -+{ -+ return (strncpy(d, s, n)); -+} -+ -+void -+bcopy(const void *src, void *dst, int len) -+{ -+ memcpy(dst, src, len); -+} -+ -+int -+bcmp(const void *b1, const void *b2, int len) -+{ -+ return (memcmp(b1, b2, len)); -+} -+ -+void -+bzero(void *b, int len) -+{ -+ memset(b, '\0', len); -+} -+ -+void* -+osl_malloc(uint size) -+{ -+ return (kmalloc(size, GFP_ATOMIC)); -+} -+ -+void -+osl_mfree(void *addr, uint size) -+{ -+ kfree(addr); -+} -+ -+uint32 -+osl_readl(volatile uint32 *r) -+{ -+ return (readl(r)); -+} -+ -+uint16 -+osl_readw(volatile uint16 *r) -+{ -+ return (readw(r)); -+} -+ -+uint8 -+osl_readb(volatile uint8 *r) -+{ -+ return (readb(r)); -+} -+ -+void -+osl_writel(uint32 v, volatile uint32 *r) -+{ -+ writel(v, r); -+} -+ -+void -+osl_writew(uint16 v, volatile uint16 *r) -+{ -+ writew(v, r); -+} -+ -+void -+osl_writeb(uint8 v, volatile uint8 *r) -+{ -+ writeb(v, r); -+} -+ -+void * -+osl_uncached(void *va) -+{ -+#ifdef mips -+ return ((void*)KSEG1ADDR(va)); -+#else -+ return ((void*)va); -+#endif -+} -+ -+uint -+osl_getcycles(void) -+{ -+ uint cycles; -+ -+#if defined(mips) -+ cycles = read_c0_count() * 2; -+#elif defined(__i386__) -+ rdtscl(cycles); -+#else -+ cycles = 0; -+#endif -+ return cycles; -+} -+ -+void * -+osl_reg_map(uint32 pa, uint size) -+{ -+ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); -+} -+ -+void -+osl_reg_unmap(void *va) -+{ -+ iounmap(va); -+} -+ -+int -+osl_busprobe(uint32 *val, uint32 addr) -+{ -+#ifdef mips -+ return get_dbe(*val, (uint32*)addr); -+#else -+ *val = readl(addr); -+ return 0; -+#endif -+} -+ -+void* -+osl_dma_alloc_consistent(void *dev, uint size, ulong *pap) -+{ -+ return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap)); -+} -+ -+void -+osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa) -+{ -+ pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa); -+} -+ -+uint -+osl_dma_map(void *dev, void *va, uint size, int direction) -+{ -+ int dir; -+ -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ return (pci_map_single(dev, va, size, dir)); -+} -+ -+void -+osl_dma_unmap(void *dev, uint pa, uint size, int direction) -+{ -+ int dir; -+ -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ pci_unmap_single(dev, (uint32)pa, size, dir); -+} -+ -+void -+osl_delay(uint usec) -+{ -+ udelay(usec); -+} -+ -+uchar* -+osl_pktdata(void *drv, void *skb) -+{ -+ return (((struct sk_buff*)skb)->data); -+} -+ -+uint -+osl_pktlen(void *drv, void *skb) -+{ -+ return (((struct sk_buff*)skb)->len); -+} -+ -+void* -+osl_pktnext(void *drv, void *skb) -+{ -+ return (((struct sk_buff*)skb)->next); -+} -+ -+void -+osl_pktsetnext(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; -+} -+ -+void -+osl_pktsetlen(void *drv, void *skb, uint len) -+{ -+ __skb_trim((struct sk_buff*)skb, len); -+} -+ -+uchar* -+osl_pktpush(void *drv, void *skb, int bytes) -+{ -+ return (skb_push((struct sk_buff*)skb, bytes)); -+} -+ -+uchar* -+osl_pktpull(void *drv, void *skb, int bytes) -+{ -+ return (skb_pull((struct sk_buff*)skb, bytes)); -+} -+ -+void* -+osl_pktdup(void *drv, void *skb) -+{ -+ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); -+} -+ -+void* -+osl_pktcookie(void *skb) -+{ -+ return ((void*)((struct sk_buff*)skb)->csum); -+} -+ -+void -+osl_pktsetcookie(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->csum = (uint)x; -+} -+ -+void* -+osl_pktlink(void *skb) -+{ -+ return (((struct sk_buff*)skb)->prev); -+} -+ -+void -+osl_pktsetlink(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; -+} -+ -+#endif -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/sbmips.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/sbmips.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/sbmips.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/sbmips.c 2005-08-28 11:12:20.478851856 +0200 -@@ -0,0 +1,950 @@ -+/* -+ * BCM47XX Sonics SiliconBackplane MIPS core routines -+ * -+ * 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. ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * -+ * $Id$ -+ */ -+ -+#include <typedefs.h> -+#include <osl.h> -+#include <sbutils.h> -+#include <bcmdevs.h> -+#include <bcmnvram.h> -+#include <bcmutils.h> -+#include <hndmips.h> -+#include <sbconfig.h> -+#include <sbextif.h> -+#include <sbchipc.h> -+#include <sbmemc.h> -+ -+/* -+ * Memory segments (32bit kernel mode addresses) -+ */ -+#undef KUSEG -+#undef KSEG0 -+#undef KSEG1 -+#undef KSEG2 -+#undef KSEG3 -+#define KUSEG 0x00000000 -+#define KSEG0 0x80000000 -+#define KSEG1 0xa0000000 -+#define KSEG2 0xc0000000 -+#define KSEG3 0xe0000000 -+ -+/* -+ * Map an address to a certain kernel segment -+ */ -+#undef KSEG0ADDR -+#undef KSEG1ADDR -+#undef KSEG2ADDR -+#undef KSEG3ADDR -+#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0) -+#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1) -+#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2) -+#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3) -+ -+/* -+ * The following macros are especially useful for __asm__ -+ * inline assembler. -+ */ -+#ifndef __STR -+#define __STR(x) #x -+#endif -+#ifndef STR -+#define STR(x) __STR(x) -+#endif -+ -+/* ********************************************************************* -+ * CP0 Registers -+ ********************************************************************* */ -+ -+#define C0_INX 0 /* CP0: TLB Index */ -+#define C0_RAND 1 /* CP0: TLB Random */ -+#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ -+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ -+#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ -+#define C0_CTEXT 4 /* CP0: Context */ -+#define C0_PGMASK 5 /* CP0: TLB PageMask */ -+#define C0_WIRED 6 /* CP0: TLB Wired */ -+#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ -+#define C0_COUNT 9 /* CP0: Count */ -+#define C0_TLBHI 10 /* CP0: TLB EntryHi */ -+#define C0_COMPARE 11 /* CP0: Compare */ -+#define C0_SR 12 /* CP0: Processor Status */ -+#define C0_STATUS C0_SR /* CP0: Processor Status */ -+#define C0_CAUSE 13 /* CP0: Exception Cause */ -+#define C0_EPC 14 /* CP0: Exception PC */ -+#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ -+#define C0_CONFIG 16 /* CP0: Config */ -+#define C0_LLADDR 17 /* CP0: LLAddr */ -+#define C0_WATCHLO 18 /* CP0: WatchpointLo */ -+#define C0_WATCHHI 19 /* CP0: WatchpointHi */ -+#define C0_XCTEXT 20 /* CP0: XContext */ -+#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ -+#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ -+#define C0_ECC 26 /* CP0: ECC */ -+#define C0_CACHEERR 27 /* CP0: CacheErr */ -+#define C0_TAGLO 28 /* CP0: TagLo */ -+#define C0_TAGHI 29 /* CP0: TagHi */ -+#define C0_ERREPC 30 /* CP0: ErrorEPC */ -+ -+/* -+ * Macros to access the system control coprocessor ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + -+#define MFC0(source, sel) \ -+({ \ -+ int __res; \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ -+ "move\t%0,$1\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ :"=r" (__res) \ -+ : \ -+ :"$1"); \ -+ __res; \ -+}) -+ -+#define MTC0(source, sel, value) \ -+do { \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ "move\t$1,%z0\n\t" \ -+ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ : \ -+ :"Jr" (value) \ -+ :"$1"); \ -+} while (0) -+ -+/* -+ * R4x00 interrupt enable / cause bits -+ */ -+#undef IE_SW0 -+#undef IE_SW1 -+#undef IE_IRQ0 -+#undef IE_IRQ1 -+#undef IE_IRQ2 -+#undef IE_IRQ3 -+#undef IE_IRQ4 -+#undef IE_IRQ5 -+#define IE_SW0 (1<< 8) -+#define IE_SW1 (1<< 9) -+#define IE_IRQ0 (1<<10) -+#define IE_IRQ1 (1<<11) -+#define IE_IRQ2 (1<<12) -+#define IE_IRQ3 (1<<13) -+#define IE_IRQ4 (1<<14) -+#define IE_IRQ5 (1<<15) -+ -+/* -+ * Bitfields in the R4xx0 cp0 status register -+ */ -+#define ST0_IE 0x00000001 -+#define ST0_EXL 0x00000002 -+#define ST0_ERL 0x00000004 -+#define ST0_KSU 0x00000018 -+# define KSU_USER 0x00000010 -+# define KSU_SUPERVISOR 0x00000008 -+# define KSU_KERNEL 0x00000000 -+#define ST0_UX 0x00000020 -+#define ST0_SX 0x00000040 -+#define ST0_KX 0x00000080 -+#define ST0_DE 0x00010000 -+#define ST0_CE 0x00020000 -+ -+/* -+ * Status register bits available in all MIPS CPUs. -+ */ -+#define ST0_IM 0x0000ff00 -+#define ST0_CH 0x00040000 -+#define ST0_SR 0x00100000 -+#define ST0_TS 0x00200000 -+#define ST0_BEV 0x00400000 -+#define ST0_RE 0x02000000 -+#define ST0_FR 0x04000000 -+#define ST0_CU 0xf0000000 -+#define ST0_CU0 0x10000000 -+#define ST0_CU1 0x20000000 -+#define ST0_CU2 0x40000000 -+#define ST0_CU3 0x80000000 -+#define ST0_XX 0x80000000 /* MIPS IV naming */ -+ -+/* -+ * Cache Operations -+ */ -+ -+#ifndef Fill_I -+#define Fill_I 0x14 -+#endif -+ -+#define cache_unroll(base,op) \ -+ __asm__ __volatile__(" \ -+ .set noreorder; \ -+ .set mips3; \ -+ cache %1, (%0); \ -+ .set mips0; \ -+ .set reorder" \ -+ : \ -+ : "r" (base), \ -+ "i" (op)); -+ -+/* -+ * These are the UART port assignments, expressed as offsets from the base -+ * register. These assignments should hold for any serial port based on -+ * a 8250, 16450, or 16550(A). -+ */ -+ -+#define UART_MCR 4 /* Out: Modem Control Register */ -+#define UART_MSR 6 /* In: Modem Status Register */ -+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -+ -+/* -+ * Returns TRUE if an external UART exists at the given base -+ * register. -+ */ -+static bool -+serial_exists(uint8 *regs) -+{ -+ uint8 save_mcr, status1; -+ -+ save_mcr = R_REG(®s[UART_MCR]); -+ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a); -+ status1 = R_REG(®s[UART_MSR]) & 0xf0; -+ W_REG(®s[UART_MCR], save_mcr); -+ -+ return (status1 == 0x90); -+} -+ -+/* -+ * Initializes UART access. The callback function will be called once -+ * per found UART. -+*/ -+void -+sb_serial_init(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) -+{ -+ void *regs; -+ ulong base; -+ uint irq; -+ int i, n; -+ -+ 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(&sb->sbadmatch1))); -+ -+ /* Determine IRQ */ -+ irq = sb_irq(sbh); -+ -+ /* Disable GPIO interrupt initially */ -+ W_REG(&eir->gpiointpolarity, 0); -+ W_REG(&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(regs)) { -+ /* Set GPIO 1 to be the external UART IRQ */ -+ W_REG(&eir->gpiointmask, 2); -+ if (add) -+ add(regs, irq, 13500000, 0); -+ } -+ } -+ -+ /* Add internal UART if enabled */ -+ if (R_REG(&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; -+ -+ /* Determine core revision and capabilities */ -+ rev = sb_corerev(sbh); -+ cap = R_REG(&cc->capabilities); -+ pll = cap & CAP_PLL_MASK; -+ -+ /* Determine IRQ */ -+ irq = sb_irq(sbh); -+ -+ if (pll == PLL_TYPE1) { -+ /* PLL clock */ -+ baud_base = sb_clock_rate(pll, -+ R_REG(&cc->clockcontrol_n), -+ R_REG(&cc->clockcontrol_m2)); -+ div = 1; -+ } else if (rev >= 3) { -+ /* Internal backplane clock */ -+ baud_base = sb_clock_rate(pll, -+ R_REG(&cc->clockcontrol_n), -+ R_REG(&cc->clockcontrol_sb)); -+ div = 2; /* Minimum divisor */ -+ W_REG(&cc->uart_clkdiv, div); -+ } else { -+ /* Fixed internal backplane clock */ -+ baud_base = 88000000; -+ div = 48; -+ } -+ -+ /* Clock source depends on strapping if UartClkOverride is unset */ -+ if ((rev > 0) && ((R_REG(&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; -+ } -+ } -+ -+ /* 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)); -+ -+ if (add) -+ add(regs, irq, baud_base, 0); -+ } -+ } -+} -+ -+/* Returns the SB interrupt flag of the current core. */ -+uint32 -+sb_flag(void *sbh) -+{ -+ void *regs; -+ sbconfig_t *sb; -+ -+ regs = sb_coreregs(sbh); -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ -+ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK); -+} -+ -+static const uint32 sbips_int_mask[] = { -+ 0, -+ SBIPS_INT1_MASK, -+ SBIPS_INT2_MASK, -+ SBIPS_INT3_MASK, -+ SBIPS_INT4_MASK -+}; -+ -+static const uint32 sbips_int_shift[] = { -+ 0, -+ 0, -+ SBIPS_INT2_SHIFT, -+ SBIPS_INT3_SHIFT, -+ SBIPS_INT4_SHIFT -+}; -+ -+/* -+ * Returns the MIPS IRQ assignment of the current core. If unassigned, -+ * 0 is returned. -+ */ -+uint -+sb_irq(void *sbh) -+{ -+ uint idx; -+ void *regs; -+ sbconfig_t *sb; -+ uint32 flag, sbipsflag; -+ uint irq = 0; -+ -+ flag = sb_flag(sbh); -+ -+ idx = sb_coreidx(sbh); -+ -+ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || -+ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ -+ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ -+ sbipsflag = R_REG(&sb->sbipsflag); -+ for (irq = 1; irq <= 4; irq++) { -+ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) -+ break; -+ } -+ if (irq == 5) -+ irq = 0; -+ } -+ -+ sb_setcoreidx(sbh, idx); -+ -+ return irq; -+} -+ -+/* Clears the specified MIPS IRQ. */ -+static void -+sb_clearirq(void *sbh, uint irq) -+{ -+ void *regs; -+ sbconfig_t *sb; -+ -+ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && -+ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) -+ ASSERT(regs); -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ -+ if (irq == 0) -+ W_REG(&sb->sbintvec, 0); -+ else -+ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]); -+} -+ -+/* -+ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS -+ * IRQ 0 may be assigned more than once. -+ */ -+static void -+sb_setirq(void *sbh, uint irq, uint coreid, uint coreunit) -+{ -+ void *regs; -+ sbconfig_t *sb; -+ uint32 flag; -+ -+ regs = sb_setcore(sbh, coreid, coreunit); -+ ASSERT(regs); -+ flag = sb_flag(sbh); -+ -+ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && -+ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) -+ ASSERT(regs); -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ -+ if (irq == 0) -+ OR_REG(&sb->sbintvec, 1 << flag); -+ else { -+ flag <<= sbips_int_shift[irq]; -+ ASSERT(!(flag & ~sbips_int_mask[irq])); -+ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq]; -+ W_REG(&sb->sbipsflag, flag); -+ } -+} -+ -+/* -+ * Initializes clocks and interrupts. SB and NVRAM access must be -+ * initialized prior to calling. -+ */ -+void -+sb_mips_init(void *sbh) -+{ -+ ulong hz, ns, tmp; -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ char *value; -+ uint irq; -+ -+ /* Figure out current SB clock speed */ -+ if ((hz = sb_clock(sbh)) == 0) -+ hz = 100000000; -+ ns = 1000000000 / hz; -+ -+ /* Setup external interface timing */ -+ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { -+ /* Initialize extif so we can get to the LEDs and external UART */ -+ W_REG(&eir->prog_config, CF_EN); -+ -+ /* 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 */ -+ W_REG(&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 */ -+ W_REG(&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 */ -+ W_REG(&cc->parallelflashwaitcnt, tmp); -+ -+ W_REG(&cc->cs01memwaitcnt, tmp); -+ } -+ -+ /* Chip specific initialization */ -+ switch (sb_chip(sbh)) { -+ case BCM4710_DEVICE_ID: -+ /* Clear interrupt map */ -+ for (irq = 0; irq <= 4; irq++) -+ sb_clearirq(sbh, irq); -+ sb_setirq(sbh, 0, SB_CODEC, 0); -+ sb_setirq(sbh, 0, SB_EXTIF, 0); -+ sb_setirq(sbh, 2, SB_ENET, 1); -+ sb_setirq(sbh, 3, SB_ILINE20, 0); -+ sb_setirq(sbh, 4, SB_PCI, 0); -+ ASSERT(eir); -+ value = nvram_get("et0phyaddr"); -+ if (value && !strcmp(value, "31")) { -+ /* Enable internal UART */ -+ W_REG(&eir->corecontrol, CC_UE); -+ /* Give USB its own interrupt */ -+ sb_setirq(sbh, 1, SB_USB, 0); -+ } else { -+ /* Disable internal UART */ -+ W_REG(&eir->corecontrol, 0); -+ /* Give Ethernet its own interrupt */ -+ sb_setirq(sbh, 1, SB_ENET, 0); -+ sb_setirq(sbh, 0, SB_USB, 0); -+ } -+ break; -+ case BCM4310_DEVICE_ID: -+ MTC0(C0_BROADCOM, 0, MFC0(C0_BROADCOM, 0) & ~(1 << 22)); -+ break; -+ } -+} -+ -+uint32 -+sb_mips_clock(void *sbh) -+{ -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ uint32 n, m; -+ uint idx; -+ uint32 pll_type, rate = 0; -+ -+ /* get index of the current core */ -+ idx = sb_coreidx(sbh); -+ pll_type = PLL_TYPE1; -+ -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ n = R_REG(&eir->clockcontrol_n); -+ m = R_REG(&eir->clockcontrol_sb); -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ n = R_REG(&cc->clockcontrol_n); -+ if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4)) -+ m = R_REG(&cc->clockcontrol_mips); -+ else if (pll_type == PLL_TYPE3) { -+ rate = 200000000; -+ goto out; -+ } else -+ m = R_REG(&cc->clockcontrol_sb); -+ } else -+ goto out; -+ -+ /* calculate rate */ -+ rate = sb_clock_rate(pll_type, n, m); -+ -+out: -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); -+ -+ return rate; -+} -+ -+static void -+icache_probe(int *size, int *lsize) -+{ -+ uint32 config1; -+ uint sets, ways; -+ -+ config1 = MFC0(C0_CONFIG, 1); -+ -+ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((*lsize = ((config1 >> 19) & 7))) -+ *lsize = 2 << *lsize; -+ sets = 64 << ((config1 >> 22) & 7); -+ ways = 1 + ((config1 >> 16) & 7); -+ *size = *lsize * sets * ways; -+} -+ -+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) -+ -+static void -+handler(void) -+{ -+ /* Step 11 */ -+ __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" -+ "and $15, $15, -31746\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 -+afterhandler(void) -+{ -+} -+ -+/* -+ * Set the MIPS, backplane and PCI clocks as closely as possible. -+ */ -+bool -+sb_mips_setclock(void *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; -+ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, new_ratio; -+ uint32 pll_type, sync_mode; -+ uint idx, i; -+ struct { -+ uint32 mipsclock; -+ uint16 n; -+ uint32 sb; -+ uint32 pci33; -+ uint32 pci25; -+ } type1_table[] = { -+ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */ -+ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */ -+ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */ -+ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */ -+ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */ -+ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */ -+ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */ -+ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */ -+ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */ -+ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */ -+ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */ -+ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */ -+ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */ -+ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */ -+ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */ -+ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */ -+ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */ -+ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */ -+ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */ -+ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */ -+ }; -+ typedef struct { -+ uint32 mipsclock; -+ uint32 sbclock; -+ uint16 n; -+ uint32 sb; -+ uint32 pci33; -+ uint32 m2; -+ uint32 m3; -+ uint32 ratio; -+ uint32 ratio_parm; -+ } n4m_table_t; -+ -+ n4m_table_t type2_table[] = { -+ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, -+ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }, -+ { 200000000, 100000000, 0x0303, 0x01000000, 0x01000600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, -+ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, -+ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, -+ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, -+ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, -+ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, -+ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }, -+ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 }, -+ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, -+ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, -+ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, -+ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, -+ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 }, -+ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 0x94, 0x012a0115 }, -+ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 } -+ }; -+ -+ n4m_table_t type4_table[] = { -+ { 192000000, 96000000, 0x0702, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 }, -+ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 }, -+ { 216000000, 108000000, 0x0211, 0x11020005, 0x11030303, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 }, -+ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x11030305, 0x04000005, 0x94, 0x012a00a9 }, -+ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 }, -+ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 0x21, 0x0aaa0555 }, -+ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 }, -+ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 }, -+ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, -+ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, -+ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 }, -+ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 0x52, 0x02520129 } -+ }; -+ uint icache_size, ic_lsize; -+ ulong start, end, dst; -+ bool ret = FALSE; -+ -+ /* get index of the current core */ -+ idx = sb_coreidx(sbh); -+ -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ pll_type = PLL_TYPE1; -+ clockcontrol_n = &eir->clockcontrol_n; -+ clockcontrol_sb = &eir->clockcontrol_sb; -+ clockcontrol_pci = &eir->clockcontrol_pci; -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ clockcontrol_n = &cc->clockcontrol_n; -+ clockcontrol_sb = &cc->clockcontrol_sb; -+ clockcontrol_pci = &cc->clockcontrol_pci; -+ } else -+ goto done; -+ -+ /* Store the current clock register values */ -+ orig_n = R_REG(clockcontrol_n); -+ orig_sb = R_REG(clockcontrol_sb); -+ orig_pci = R_REG(clockcontrol_pci); -+ -+ if (pll_type == PLL_TYPE1) { -+ /* Keep the current PCI clock if not specified */ -+ if (pciclock == 0) { -+ pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci)); -+ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; -+ } -+ -+ /* Search for the closest MIPS clock less than or equal to a preferred value */ -+ 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)); -+ if (type1_table[i].mipsclock > mipsclock) -+ break; -+ } -+ if (i == 0) { -+ ret = FALSE; -+ goto done; -+ } else { -+ ret = TRUE; -+ i--; -+ } -+ ASSERT(type1_table[i].mipsclock <= mipsclock); -+ -+ /* No PLL change */ -+ if ((orig_n == type1_table[i].n) && -+ (orig_sb == type1_table[i].sb) && -+ (orig_pci == type1_table[i].pci33)) -+ goto done; -+ -+ /* Set the PLL controls */ -+ W_REG(clockcontrol_n, type1_table[i].n); -+ W_REG(clockcontrol_sb, type1_table[i].sb); -+ if (pciclock == 25000000) -+ W_REG(clockcontrol_pci, type1_table[i].pci25); -+ else -+ W_REG(clockcontrol_pci, type1_table[i].pci33); -+ -+ /* Reset */ -+ sb_watchdog(sbh, 1); -+ while (1); -+ } else if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4)) { -+ n4m_table_t *table = (pll_type == PLL_TYPE2) ? type2_table : type4_table; -+ uint tabsz = (pll_type == PLL_TYPE2) ? ARRAYSIZE(type2_table) : ARRAYSIZE(type4_table); -+ -+ ASSERT(cc); -+ -+ /* Store the current clock register values */ -+ orig_m2 = R_REG(&cc->clockcontrol_m2); -+ orig_mips = R_REG(&cc->clockcontrol_mips); -+ orig_ratio_parm = 0; -+ -+ /* Look up current ratio */ -+ for (i = 0; i < tabsz; i++) { -+ 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_ratio_parm = table[i].ratio_parm; -+ break; -+ } -+ } -+ -+ /* 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))) -+ break; -+ } -+ if (i == tabsz) { -+ ret = FALSE; -+ goto done; -+ } else { -+ ret = TRUE; -+ } -+ -+ /* No PLL change */ -+ 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)) -+ goto done; -+ -+ /* Set the PLL controls */ -+ W_REG(clockcontrol_n, table[i].n); -+ W_REG(clockcontrol_sb, table[i].sb); -+ W_REG(clockcontrol_pci, table[i].pci33); -+ W_REG(&cc->clockcontrol_m2, table[i].m2); -+ W_REG(&cc->clockcontrol_mips, table[i].m3); -+ -+ /* No ratio change */ -+ if (orig_ratio_parm == table[i].ratio_parm) -+ goto end_fill; -+ -+ new_ratio = table[i].ratio_parm; -+ -+ icache_probe(&icache_size, &ic_lsize); -+ -+ /* Preload the code into the cache */ -+ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); -+ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); -+ while (start < end) { -+ cache_unroll(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 handler into the cache one line at a time */ -+ for (i = 0; i < (end - start); i += 4) -+ cache_unroll(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(&mipsr->intmask, 1); -+ -+ start_fill: -+ /* step 1, set clock ratios */ -+ MTC0(C0_BROADCOM, 3, new_ratio); -+ MTC0(C0_BROADCOM, 1, 8); -+ -+ /* step 2: program timer intr */ -+ W_REG(&mipsr->timer, 100); -+ (void) R_REG(&mipsr->timer); -+ -+ /* step 3, switch to async */ -+ sync_mode = MFC0(C0_BROADCOM, 4); -+ MTC0(C0_BROADCOM, 4, 1 << 22); -+ -+ /* step 4, set cfg active */ -+ MTC0(C0_BROADCOM, 2, 0x9); -+ -+ -+ /* steps 5 & 6 */ -+ __asm__ __volatile__ ( -+ ".set\tmips3\n\t" -+ "wait\n\t" -+ ".set\tmips0" -+ ); -+ -+ /* step 7, clear cfg_active */ -+ MTC0(C0_BROADCOM, 2, 0); -+ -+ /* Additional Step: set back to orig sync mode */ -+ MTC0(C0_BROADCOM, 4, sync_mode); -+ -+ /* step 8, fake soft reset */ -+ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4); -+ -+ end_fill: -+ /* step 9 set watchdog timer */ -+ sb_watchdog(sbh, 20); -+ (void) R_REG(&cc->chipid); -+ -+ /* step 11 */ -+ __asm__ __volatile__ ( -+ ".set\tmips3\n\t" -+ "sync\n\t" -+ "wait\n\t" -+ ".set\tmips0" -+ ); -+ while (1); -+ } -+ -+done: -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); -+ -+ return ret; -+} -+ -+ -+/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ -+uint32 -+sb_memc_get_ncdl(void *sbh) -+{ -+ sbmemcregs_t *memc; -+ uint32 ret = 0; -+ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; -+ uint idx, rev; -+ -+ idx = sb_coreidx(sbh); -+ -+ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); -+ if (memc == 0) -+ goto out; -+ -+ rev = sb_corerev(sbh); -+ -+ config = R_REG(&memc->config); -+ wr = R_REG(&memc->wrncdlcor); -+ rd = R_REG(&memc->rdncdlcor); -+ misc = R_REG(&memc->miscdlyctl); -+ dqsg = R_REG(&memc->dqsgatencdl); -+ -+ rd &= MEMC_RDNCDLCOR_RD_MASK; -+ wr &= MEMC_WRNCDLCOR_WR_MASK; -+ dqsg &= MEMC_DQSGATENCDL_G_MASK; -+ -+ if (config & MEMC_CONFIG_DDR) { -+ ret = (wr << 16) | (rd << 8) | dqsg; -+ } else { -+ if (rev > 0) -+ cd = rd; -+ else -+ 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: -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); -+ -+ return ret; -+} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/sbpci.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/sbpci.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/sbpci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/sbpci.c 2005-08-28 11:12:20.479851704 +0200 -@@ -0,0 +1,530 @@ -+/* -+ * Low-Level PCI and SB support for BCM47xx -+ * -+ * 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 <typedefs.h> -+#include <pcicfg.h> -+#include <bcmdevs.h> -+#include <sbconfig.h> -+#include <sbpci.h> -+#include <osl.h> -+#include <bcmendian.h> -+#include <bcmutils.h> -+#include <sbutils.h> -+#include <bcmnvram.h> -+#include <hndmips.h> -+ -+/* Can free sbpci_init() memory after boot */ -+#ifndef linux -+#define __init -+#endif -+ -+/* Emulated configuration space */ -+static pci_config_regs sb_config_regs[SB_MAXCORES]; -+ -+/* Banned cores */ -+static uint16 pci_ban[32] = { 0 }; -+static uint pci_banned = 0; -+ -+/* CardBus mode */ -+static bool cardbus = FALSE; -+ -+/* -+ * Functions for accessing external PCI configuration space -+ */ -+ -+/* Assume one-hot slot wiring */ -+#define PCI_SLOT_MAX 16 -+ -+static uint32 -+config_cmd(void *sbh, uint bus, uint dev, uint func, uint off) -+{ -+ uint coreidx; -+ sbpciregs_t *regs; -+ uint32 addr = 0; -+ -+ /* CardBusMode supports only one device */ -+ if (cardbus && dev > 1) -+ return 0; -+ -+ coreidx = sb_coreidx(sbh); -+ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); -+ -+ /* Type 0 transaction */ -+ if (bus == 1) { -+ /* Skip unwired slots */ -+ if (dev < PCI_SLOT_MAX) { -+ /* Slide the PCI window to the appropriate slot */ -+ W_REG(®s->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK)); -+ addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) | -+ (func << 8) | (off & ~3); -+ } -+ } -+ -+ /* Type 1 transaction */ -+ else { -+ W_REG(®s->sbtopci1, SBTOPCI_CFG1); -+ addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3); -+ } -+ -+ sb_setcoreidx(sbh, coreidx); -+ -+ return addr; -+} -+ -+static int -+extpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ uint32 addr, *reg = NULL, val; -+ int ret = 0; -+ -+ if (!(addr = config_cmd(sbh, bus, dev, func, off)) || -+ !(reg = (uint32 *) REG_MAP(addr, len)) || -+ BUSPROBE(val, reg)) -+ val = 0xffffffff; -+ -+ val >>= 8 * (off & 3); -+ if (len == 4) -+ *((uint32 *) buf) = val; -+ else if (len == 2) -+ *((uint16 *) buf) = (uint16) val; -+ else if (len == 1) -+ *((uint8 *) buf) = (uint8) val; -+ else -+ ret = -1; -+ -+ if (reg) -+ REG_UNMAP(reg); -+ -+ return ret; -+} -+ -+static int -+extpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ uint32 addr, *reg = NULL, val; -+ int ret = 0; -+ -+ if (!(addr = config_cmd(sbh, bus, dev, func, off)) || -+ !(reg = (uint32 *) REG_MAP(addr, len)) || -+ BUSPROBE(val, reg)) -+ goto done; -+ -+ if (len == 4) -+ val = *((uint32 *) buf); -+ else if (len == 2) { -+ val &= ~(0xffff << (8 * (off & 3))); -+ val |= *((uint16 *) buf) << (8 * (off & 3)); -+ } else if (len == 1) { -+ val &= ~(0xff << (8 * (off & 3))); -+ val |= *((uint8 *) buf) << (8 * (off & 3)); -+ } else -+ ret = -1; -+ -+ W_REG(reg, val); -+ -+ done: -+ if (reg) -+ REG_UNMAP(reg); -+ -+ return ret; -+} -+ -+/* -+ * Functions for accessing translated SB configuration space -+ */ -+ -+static int -+sb_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ pci_config_regs *cfg; -+ -+ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) -+ return -1; -+ cfg = &sb_config_regs[dev]; -+ -+ ASSERT(ISALIGNED(off, len)); -+ ASSERT(ISALIGNED(buf, len)); -+ -+ if (len == 4) -+ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); -+ else if (len == 2) -+ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); -+ else if (len == 1) -+ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); -+ else -+ return -1; -+ -+ return 0; -+} -+ -+static int -+sb_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ uint coreidx, n; -+ void *regs; -+ sbconfig_t *sb; -+ pci_config_regs *cfg; -+ -+ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) -+ return -1; -+ cfg = &sb_config_regs[dev]; -+ -+ ASSERT(ISALIGNED(off, len)); -+ ASSERT(ISALIGNED(buf, len)); -+ -+ /* Emulate BAR sizing */ -+ if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) && -+ len == 4 && *((uint32 *) buf) == ~0) { -+ coreidx = sb_coreidx(sbh); -+ if ((regs = sb_setcoreidx(sbh, dev))) { -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ /* Highest numbered address match register */ -+ n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; -+ if (off == OFFSETOF(pci_config_regs, base[0])) -+ cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1); -+ /*else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1) -+ cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1); -+ else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2) -+ cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1); -+ else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3) -+ cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1);*/ -+ } -+ sb_setcoreidx(sbh, coreidx); -+ return 0; -+ } -+ -+ if (len == 4) -+ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); -+ else if (len == 2) -+ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); -+ else if (len == 1) -+ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); -+ else -+ return -1; -+ -+ return 0; -+} -+ -+int -+sbpci_read_config(void *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); -+ else -+ return extpci_read_config(sbh, bus, dev, func, off, buf, len); -+} -+ -+int -+sbpci_write_config(void *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); -+ else -+ return extpci_write_config(sbh, bus, dev, func, off, buf, len); -+} -+ -+void -+sbpci_ban(uint16 core) -+{ -+ if (pci_banned < ARRAYSIZE(pci_ban)) -+ pci_ban[pci_banned++] = core; -+} -+ -+int __init -+sbpci_init(void *sbh) -+{ -+ uint chip, chiprev, chippkg, coreidx, host, i; -+ sbpciregs_t *pci; -+ sbconfig_t *sb; -+ pci_config_regs *cfg; -+ void *regs; -+ char varname[8]; -+ uint wlidx = 0; -+ uint16 vendor, core; -+ uint8 class, subclass, progif; -+ uint32 val; -+ uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK }; -+ uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT }; -+ -+ chip = sb_chip(sbh); -+ chiprev = sb_chiprev(sbh); -+ chippkg = sb_chippkg(sbh); -+ coreidx = sb_coreidx(sbh); -+ -+ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) -+ return -1; -+ sb_core_reset(sbh, 0); -+ -+ if (((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) || -+ ((chip == BCM4712_DEVICE_ID) && (chippkg == BCM4712SMALL_PKG_ID))) -+ host = 0; -+ else -+ host = !BUSPROBE(val, &pci->control); -+ -+ if (!host) { -+ /* Disable PCI interrupts in client mode */ -+ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); -+ W_REG(&sb->sbintvec, 0); -+ -+ /* Disable the PCI bridge in client mode */ -+ sbpci_ban(SB_PCI); -+ printf("PCI: Disabled\n"); -+ } else { -+ /* Reset the external PCI bus and enable the clock */ -+ W_REG(&pci->control, 0x5); /* enable the tristate drivers */ -+ W_REG(&pci->control, 0xd); /* enable the PCI clock */ -+ OSL_DELAY(100); /* delay 100 us */ -+ W_REG(&pci->control, 0xf); /* deassert PCI reset */ -+ W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */ -+ OSL_DELAY(1); /* delay 1 us */ -+ -+ /* Enable CardBusMode */ -+ cardbus = nvram_match("cardbus", "1"); -+ if (cardbus) { -+ printf("PCI: Enabling CardBus\n"); -+ /* GPIO 1 resets the CardBus device on bcm94710ap */ -+ sb_gpioout(sbh, 1, 1); -+ sb_gpioouten(sbh, 1, 1); -+ W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400); -+ } -+ -+ /* 64 MB I/O access window */ -+ W_REG(&pci->sbtopci0, SBTOPCI_IO); -+ /* 64 MB configuration access window */ -+ W_REG(&pci->sbtopci1, SBTOPCI_CFG0); -+ /* 1 GB memory access window */ -+ W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); -+ -+ /* Enable PCI bridge BAR0 prefetch and burst */ -+ val = 6; -+ sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val)); -+ -+ /* Enable PCI interrupts */ -+ W_REG(&pci->intmask, PCI_INTA); -+ } -+ -+ /* Scan the SB bus */ -+ bzero(sb_config_regs, sizeof(sb_config_regs)); -+ for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) { -+ cfg->vendor = 0xffff; -+ if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs))) -+ continue; -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ -+ /* Read ID register and parse vendor and core */ -+ val = R_REG(&sb->sbidhigh); -+ vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT; -+ core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; -+ progif = 0; -+ -+ /* Check if this core is banned */ -+ for (i = 0; i < pci_banned; i++) -+ if (core == pci_ban[i]) -+ break; -+ if (i < pci_banned) -+ continue; -+ -+ /* Known vendor translations */ -+ switch (vendor) { -+ case SB_VEND_BCM: -+ vendor = VENDOR_BROADCOM; -+ break; -+ } -+ -+ /* Determine class based on known core codes */ -+ switch (core) { -+ case SB_ILINE20: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ILINE_ID; -+ break; -+ case SB_ILINE100: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM4610_ILINE_ID; -+ break; -+ case SB_ENET: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ENET_ID; -+ break; -+ case SB_SDRAM: -+ case SB_MEMC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_RAM; -+ break; -+ case SB_PCI: -+ class = PCI_CLASS_BRIDGE; -+ subclass = PCI_BRIDGE_PCI; -+ //break; -+ case SB_MIPS: -+ case SB_MIPS33: -+ class = PCI_CLASS_CPU; -+ subclass = PCI_CPU_MIPS; -+ break; -+ case SB_CODEC: -+ class = PCI_CLASS_COMM; -+ subclass = PCI_COMM_MODEM; -+ core = BCM47XX_V90_ID; -+ break; -+ case SB_USB: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USB_ID; -+ break; -+ case SB_USB11H: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USBH_ID; -+ break; -+ case SB_USB11D: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ core = BCM47XX_USBD_ID; -+ break; -+ case SB_IPSEC: -+ class = PCI_CLASS_CRYPT; -+ subclass = PCI_CRYPT_NETWORK; -+ core = BCM47XX_IPSEC_ID; -+ break; -+ case SB_EXTIF: -+ case SB_CC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_FLASH; -+ break; -+ case SB_D11: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ /* Let an nvram variable override this */ -+ sprintf(varname, "wl%did", wlidx); -+ wlidx++; -+ if ((core = getintvar(NULL, varname)) == 0) { -+ if (chip == BCM4712_DEVICE_ID) { -+ if (chippkg == BCM4712SMALL_PKG_ID) -+ core = BCM4306_D11G_ID; -+ else -+ core = BCM4306_D11DUAL_ID; -+ } else { -+ /* 4310 */ -+ core = BCM4310_D11B_ID; -+ } -+ } -+ break; -+ -+ default: -+ class = subclass = progif = 0xff; -+ break; -+ } -+ -+ /* Supported translations */ -+ cfg->vendor = htol16(vendor); -+ cfg->device = htol16(core); -+ cfg->rev_id = chiprev; -+ cfg->prog_if = progif; -+ cfg->sub_class = subclass; -+ cfg->base_class = class; -+ cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0))); -+ cfg->base[1] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch1)))*/; -+ cfg->base[2] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch2)))*/; -+ cfg->base[3] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch3)))*/; -+ cfg->base[4] = 0; -+ cfg->base[5] = 0; -+ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) -+ cfg->header_type = PCI_HEADER_BRIDGE; -+ else -+ cfg->header_type = PCI_HEADER_NORMAL; -+ /* Save core interrupt flag */ -+ cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK; -+ /* Default to MIPS shared interrupt 0 */ -+ cfg->int_line = 0; -+ /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */ -+ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || -+ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ val = R_REG(&sb->sbipsflag); -+ for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) { -+ if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin) -+ break; -+ } -+ if (cfg->int_line > 4) -+ cfg->int_line = 0; -+ } -+ /* Emulated core */ -+ *((uint32 *) &cfg->sprom_control) = 0xffffffff; -+ } -+ -+ sb_setcoreidx(sbh, coreidx); -+ return 0; -+} -+ -+void -+sbpci_check(void *sbh) -+{ -+ uint coreidx; -+ sbpciregs_t *pci; -+ uint32 sbtopci1; -+ uint32 buf[64], *ptr, i; -+ ulong pa; -+ volatile uint j; -+ -+ coreidx = sb_coreidx(sbh); -+ pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); -+ -+ /* Clear the test array */ -+ pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL); -+ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); -+ memset(ptr, 0, sizeof(buf)); -+ -+ /* Point PCI window 1 to memory */ -+ sbtopci1 = R_REG(&pci->sbtopci1); -+ W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK)); -+ -+ /* Fill the test array via PCI window 1 */ -+ ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf)); -+ for (i = 0; i < ARRAYSIZE(buf); i++) { -+ for (j = 0; j < 2; j++); -+ W_REG(&ptr[i], i); -+ } -+ REG_UNMAP(ptr); -+ -+ /* Restore PCI window 1 */ -+ W_REG(&pci->sbtopci1, sbtopci1); -+ -+ /* Check the test array */ -+ DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL); -+ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); -+ for (i = 0; i < ARRAYSIZE(buf); i++) { -+ if (ptr[i] != i) -+ break; -+ } -+ -+ /* Change the clock if the test fails */ -+ if (i < ARRAYSIZE(buf)) { -+ uint32 req, cur; -+ -+ cur = sb_clock(sbh); -+ printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000); -+ for (req = 104000000; req < 176000000; req += 4000000) { -+ printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000); -+ /* This will only reset if the clocks are valid and have changed */ -+ sb_mips_setclock(sbh, req, 0, 0); -+ } -+ /* Should not reach here */ -+ ASSERT(0); -+ } -+ -+ sb_setcoreidx(sbh, coreidx); -+} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/broadcom/sbutils.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/sbutils.c ---- linux-2.6.12.5/arch/mips/bcm47xx/broadcom/sbutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/broadcom/sbutils.c 2005-08-28 11:12:20.482851248 +0200 -@@ -0,0 +1,1895 @@ -+/* -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. -+ * -+ * 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 <typedefs.h> -+#include <osl.h> -+#include <bcmutils.h> -+#include <bcmdevs.h> -+#include <sbconfig.h> -+#include <sbchipc.h> -+#include <sbpci.h> -+#include <pcicfg.h> -+#include <sbpcmcia.h> -+#include <sbextif.h> -+#include <sbutils.h> -+#include <bcmsrom.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); -+ -+/* misc sb info needed by some of the routines */ -+typedef struct sb_info { -+ uint chip; /* chip number */ -+ uint chiprev; /* chip revision */ -+ uint chippkg; /* chip package option */ -+ uint boardtype; /* board type */ -+ uint boardvendor; /* board vendor id */ -+ uint bus; /* what bus type we are going through */ -+ -+ void *osh; /* osl os handle */ -+ void *sdh; /* bcmsdh handle */ -+ -+ void *curmap; /* current regs va */ -+ void *regs[SB_MAXCORES]; /* other regs va */ -+ -+ uint curidx; /* current core index */ -+ uint dev_coreid; /* the core provides driver functions */ -+ uint pciidx; /* pci core index */ -+ uint pcirev; /* pci core rev */ -+ -+ uint pcmciaidx; /* pcmcia core index */ -+ uint pcmciarev; /* pcmcia core rev */ -+ bool memseg; /* flag to toggle MEM_SEG register */ -+ -+ uint ccrev; /* chipc core rev */ -+ -+ uint gpioidx; /* gpio control core index */ -+ uint gpioid; /* gpio control coretype */ -+ -+ uint numcores; /* # discovered cores */ -+ uint coreid[SB_MAXCORES]; /* id of each core */ -+ -+ void *intr_arg; /* interrupt callback function arg */ -+ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ -+ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ -+} sb_info_t; -+ -+/* local prototypes */ -+static void* sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); -+static void sb_scan(sb_info_t *si); -+static uint sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val); -+static uint _sb_coreidx(void *sbh); -+static uint sb_findcoreidx(void *sbh, uint coreid, uint coreunit); -+static uint sb_pcidev2chip(uint pcidev); -+static uint sb_chip2numcores(uint chip); -+ -+#define SB_INFO(sbh) (sb_info_t*)sbh -+#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) -+#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) \ -+ && ISALIGNED((x), SB_CORE_SIZE)) -+#define GOODREGS(regs) (regs && ISALIGNED(regs, SB_CORE_SIZE)) -+#define REGS2SB(va) (sbconfig_t*) ((uint)(va) + SBCONFIGOFF) -+#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) -+#define BADIDX (SB_MAXCORES+1) -+ -+#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) -+#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) -+#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) -+#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) -+ -+/* -+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ -+ * after core switching to avoid invalid register accesss inside ISR. -+ */ -+#define INTR_OFF(si, intr_val) \ -+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -+#define INTR_RESTORE(si, intr_val) \ -+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } -+ -+/* power control defines */ -+#define PLL_DELAY 150 /* 150us pll on delay */ -+#define FREF_DELAY 15 /* 15us fref change delay */ -+#define LPOMINFREQ 25000 /* low power oscillator min */ -+#define LPOMAXFREQ 43000 /* low power oscillator max */ -+#define XTALMINFREQ 19800000 /* 20mhz - 1% */ -+#define XTALMAXFREQ 20200000 /* 20mhz + 1% */ -+#define PCIMINFREQ 25000000 /* 25mhz */ -+#define PCIMAXFREQ 34000000 /* 33mhz + fudge */ -+ -+#define SCC_LOW2FAST_LIMIT 5000 /* turn on fast clock time, in unit of ms */ -+ -+ -+static uint32 -+sb_read_sbreg(void *sbh, volatile uint32 *sbr) -+{ -+ sb_info_t *si; -+ uint8 tmp; -+ uint32 val, intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ -+ /* -+ * 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) { -+ INTR_OFF(si, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ (uint32)sbr &= ~(1 << 11); /* mask out bit 11*/ -+ } -+ -+ val = R_REG(sbr); -+ -+ if(si->memseg) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(si, intr_val); -+ } -+ -+ return (val); -+} -+ -+static void -+sb_write_sbreg(void *sbh, volatile uint32 *sbr, uint32 v) -+{ -+ sb_info_t *si; -+ uint8 tmp; -+ volatile uint32 dummy; -+ uint32 intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ -+ /* -+ * 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) { -+ INTR_OFF(si, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ (uint32)sbr &= ~(1 << 11); /* mask out bit 11 */ -+ } -+ -+ if ((si->bus == PCMCIA_BUS) || (si->bus == PCI_BUS)) { -+#ifdef IL_BIGENDIAN -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff)); -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+#else -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff)); -+#endif -+ } else -+ W_REG(sbr, v); -+ -+ if(si->memseg) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(si, intr_val); -+ } -+} -+ -+/* -+ * Allocate a sb handle. -+ * devid - pci device id (used to determine chip#) -+ * osh - opaque OS handle -+ * regs - virtual address of initial core registers -+ * bustype - pci/pcmcia/sb/sdio/etc -+ * vars - pointer to a pointer area for "environment" variables -+ * varsz - pointer to int to return the size of the vars -+ */ -+void* -+sb_attach(uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) -+{ -+ sb_info_t *si; -+ -+ /* alloc sb_info_t */ -+ if ((si = MALLOC(sizeof (sb_info_t))) == NULL) { -+ SB_ERROR(("sb_attach: malloc failed!\n")); -+ return (NULL); -+ } -+ -+ return (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz)); -+} -+ -+/* global kernel resource */ -+static sb_info_t ksi; -+ -+/* generic kernel variant of sb_attach() */ -+void* -+sb_kattach() -+{ -+ uint32 *regs; -+ char *unused; -+ int varsz; -+ -+ if (ksi.curmap == NULL) { -+ uint32 cid; -+ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); -+ cid = R_REG((uint32 *)regs); -+ if ((cid == 0x08104712) || (cid == 0x08114712)) { -+ uint32 *scc, val; -+ -+ scc = (uint32 *)((uint32)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); -+ val = R_REG(scc); -+ SB_ERROR((" initial scc = 0x%x\n", val)); -+ val |= SCC_SS_XTAL; -+ W_REG(scc, val); -+ } -+ -+ sb_doattach(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, -+ SB_BUS, NULL, &unused, &varsz); -+ } -+ -+ return &ksi; -+} -+ -+static void* -+sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) -+{ -+ uint origidx; -+ chipcregs_t *cc; -+ uint32 w; -+ -+ ASSERT(GOODREGS(regs)); -+ -+ bzero((uchar*)si, sizeof (sb_info_t)); -+ -+ si->pciidx = si->gpioidx = BADIDX; -+ -+ si->osh = osh; -+ si->curmap = regs; -+ si->sdh = sdh; -+ -+ /* 4317A0 PCMCIA is no longer supported */ -+ if ((bustype == PCMCIA_BUS) && (R_REG((uint32 *)regs) == 0x04104317)) -+ return NULL; -+ -+ /* check to see if we are a sb core mimic'ing a pci core */ -+ if (bustype == PCI_BUS) { -+ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) -+ bustype = SB_BUS; -+ else -+ bustype = PCI_BUS; -+ } -+ -+ si->bus = bustype; -+ -+ /* kludge to enable the clock on the 4306 which lacks a slowclock */ -+ if (si->bus == PCI_BUS) -+ sb_pwrctl_xtal((void*)si, XTAL|PLL, ON); -+ -+ /* clear any previous epidiag-induced target abort */ -+ sb_taclear((void*)si); -+ -+ /* initialize current core index value */ -+ si->curidx = _sb_coreidx((void*)si); -+ -+ /* keep and reuse the initial register mapping */ -+ origidx = si->curidx; -+ if (si->bus == SB_BUS) -+ si->regs[origidx] = regs; -+ -+ /* initialize the vars */ -+ if (srom_var_init(si->bus, si->curmap, osh, vars, varsz)) { -+ SB_ERROR(("sb_attach: srom_var_init failed\n")); -+ goto bad; -+ } -+ -+ if (si->bus == PCMCIA_BUS) { -+ w = getintvar(*vars, "regwindowsz"); -+ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; -+ } -+ -+ /* is core-0 a chipcommon core? */ -+ si->numcores = 1; -+ cc = (chipcregs_t*) sb_setcoreidx((void*)si, 0); -+ if (sb_coreid((void*)si) != SB_CC) -+ cc = NULL; -+ -+ /* determine chip id and rev */ -+ if (cc) { -+ /* chip common core found! */ -+ si->chip = R_REG(&cc->chipid) & CID_ID_MASK; -+ si->chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; -+ si->chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; -+ } else { -+ /* without chip common core, get devid for PCMCIA */ -+ if (si->bus == PCMCIA_BUS) -+ devid = getintvar(*vars, "devid"); -+ -+ /* no chip common core -- must convert device id to chip id */ -+ if ((si->chip = sb_pcidev2chip(devid)) == 0) { -+ SB_ERROR(("sb_attach: unrecognized device id 0x%04x\n", devid)); -+ goto bad; -+ } -+ -+ /* -+ * The chip revision number is hardwired into all -+ * of the pci function config rev fields and is -+ * independent from the individual core revision numbers. -+ * For example, the "A0" silicon of each chip is chip rev 0. -+ * For PCMCIA we get it from the CIS instead. -+ */ -+ if (si->bus == PCMCIA_BUS) { -+ ASSERT(vars); -+ si->chiprev = getintvar(*vars, "chiprev"); -+ } else if (si->bus == PCI_BUS) { -+ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); -+ si->chiprev = w & 0xff; -+ } else -+ si->chiprev = 0; -+ } -+ -+ /* get chipcommon rev */ -+ si->ccrev = cc? sb_corerev((void*)si) : 0; -+ -+ /* determine numcores */ -+ if ((si->ccrev == 4) || (si->ccrev >= 6)) -+ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; -+ else -+ si->numcores = sb_chip2numcores(si->chip); -+ -+ /* return to original core */ -+ sb_setcoreidx((void*)si, origidx); -+ -+ /* sanity checks */ -+ ASSERT(si->chip); -+ /* 4704A1 is chiprev 8 :-( */ -+ ASSERT((si->chiprev < 8) || -+ ((si->chip == BCM4704_DEVICE_ID) && ((si->chiprev == 8)))); -+ -+ /* scan for cores */ -+ sb_scan(si); -+ -+ /* pci core is required */ -+ if (!GOODIDX(si->pciidx)) { -+ SB_ERROR(("sb_attach: pci core not found\n")); -+ goto bad; -+ } -+ -+ /* gpio control core is required */ -+ if (!GOODIDX(si->gpioidx)) { -+ SB_ERROR(("sb_attach: gpio control core not found\n")); -+ goto bad; -+ } -+ -+ /* get boardtype and boardrev */ -+ switch (si->bus) { -+ case PCI_BUS: -+ /* do a pci config read to get subsystem id and subvendor id */ -+ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); -+ si->boardvendor = w & 0xffff; -+ si->boardtype = (w >> 16) & 0xffff; -+ break; -+ -+ case PCMCIA_BUS: -+ case SDIO_BUS: -+ si->boardvendor = getintvar(*vars, "manfid"); -+ si->boardtype = getintvar(*vars, "prodid"); -+ break; -+ -+ case SB_BUS: -+ si->boardvendor = VENDOR_BROADCOM; -+ si->boardtype = 0xffff; -+ break; -+ } -+ -+ if (si->boardtype == 0) { -+ SB_ERROR(("sb_attach: unknown board type\n")); -+ ASSERT(si->boardtype); -+ } -+ -+ return ((void*)si); -+ -+bad: -+ MFREE(si, sizeof (sb_info_t)); -+ return (NULL); -+} -+ -+uint -+sb_coreid(void *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ -+ return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); -+} -+ -+uint -+sb_coreidx(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->curidx); -+} -+ -+/* return current index of core */ -+static uint -+_sb_coreidx(void *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint32 sbaddr = 0; -+ -+ si = SB_INFO(sbh); -+ ASSERT(si); -+ -+ switch (si->bus) { -+ case SB_BUS: -+ sb = REGS2SB(si->curmap); -+ sbaddr = sb_base(R_SBREG(sbh, &sb->sbadmatch0)); -+ break; -+ -+ case PCI_BUS: -+ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); -+ break; -+ -+ case PCMCIA_BUS: { -+ uint8 tmp; -+ -+ 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; -+ } -+ default: -+ ASSERT(0); -+ } -+ -+ ASSERT(GOODCOREADDR(sbaddr)); -+ return ((sbaddr - SB_ENUM_BASE)/SB_CORE_SIZE); -+} -+ -+uint -+sb_corevendor(void *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ -+ return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -+} -+ -+uint -+sb_corerev(void *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ -+ return (R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_RC_MASK); -+} -+ -+#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) -+ -+/* set/clear sbtmstatelow core-specific flags */ -+uint32 -+sb_coreflags(void *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); -+ ASSERT((mask & ~SBTML_ALLOW) == 0); -+ -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(sbh, &sb->sbtmstatelow) & ~mask) | val; -+ W_SBREG(sbh, &sb->sbtmstatelow, w); -+ } -+ -+ /* return the new value */ -+ return (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_ALLOW); -+} -+ -+/* set/clear sbtmstatehigh core-specific flags */ -+uint32 -+sb_coreflagshi(void *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); -+ ASSERT((mask & ~SBTMH_FL_MASK) == 0); -+ -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(sbh, &sb->sbtmstatehigh) & ~mask) | val; -+ W_SBREG(sbh, &sb->sbtmstatehigh, w); -+ } -+ -+ /* return the new value */ -+ return (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_FL_MASK); -+} -+ -+bool -+sb_iscoreup(void *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ -+ return ((R_SBREG(sbh, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK); -+} -+ -+/* -+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, -+ * switch back to the original core, and return the new value. -+ */ -+static uint -+sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ sb_info_t *si; -+ uint origidx; -+ uint32 *r; -+ uint w; -+ uint intr_val = 0; -+ -+ ASSERT(GOODIDX(coreidx)); -+ ASSERT(regoff < SB_CORE_SIZE); -+ ASSERT((val & ~mask) == 0); -+ -+ si = SB_INFO(sbh); -+ -+ /* save current core index */ -+ origidx = sb_coreidx(sbh); -+ -+ /* switch core */ -+ INTR_OFF(si, intr_val); -+ r = (uint32*) ((uint) sb_setcoreidx(sbh, coreidx) + regoff); -+ -+ /* mask and set */ -+ if (mask || val) { -+ if (regoff >= SBCONFIGOFF) { -+ w = (R_SBREG(sbh, r) & ~mask) | val; -+ W_SBREG(sbh, r, w); -+ } else { -+ w = (R_REG(r) & ~mask) | val; -+ W_REG(r, w); -+ } -+ } -+ -+ /* readback */ -+ w = R_SBREG(sbh, r); -+ -+ /* restore core index */ -+ if (origidx != coreidx) -+ sb_setcoreidx(sbh, origidx); -+ -+ INTR_RESTORE(si, intr_val); -+ return (w); -+} -+ -+/* scan the sb enumerated space to identify all cores */ -+static void -+sb_scan(sb_info_t *si) -+{ -+ void *sbh; -+ uint origidx; -+ uint i; -+ -+ sbh = (void*) si; -+ -+ /* numcores should already be set */ -+ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); -+ -+ /* save current core index */ -+ origidx = sb_coreidx(sbh); -+ -+ si->pciidx = si->gpioidx = BADIDX; -+ -+ for (i = 0; i < si->numcores; i++) { -+ sb_setcoreidx(sbh, i); -+ si->coreid[i] = sb_coreid(sbh); -+ -+ if (si->coreid[i] == SB_CC) -+ si->ccrev = sb_corerev(sbh); -+ -+ else if (si->coreid[i] == SB_PCI) { -+ si->pciidx = i; -+ si->pcirev = sb_corerev(sbh); -+ -+ }else if (si->coreid[i] == SB_PCMCIA){ -+ si->pcmciaidx = i; -+ si->pcmciarev = sb_corerev(sbh); -+ } -+ } -+ -+ /* -+ * Find the gpio "controlling core" type and index. -+ * Precedence: -+ * - if there's a chip common core - use that -+ * - 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(sbh, SB_CC, 0))) { -+ si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0); -+ si->gpioid = SB_CC; -+ } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) { -+ si->gpioidx = si->pciidx; -+ si->gpioid = SB_PCI; -+ } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) { -+ si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0); -+ si->gpioid = SB_EXTIF; -+ } -+ -+ /* return to original core index */ -+ sb_setcoreidx(sbh, origidx); -+} -+ -+/* may be called with core in reset */ -+void -+sb_detach(void *sbh) -+{ -+ sb_info_t *si; -+ uint idx; -+ -+ si = SB_INFO(sbh); -+ -+ if (si == NULL) -+ return; -+ -+ if (si->bus == SB_BUS) -+ for (idx = 0; idx < SB_MAXCORES; idx++) -+ if (si->regs[idx]) { -+ REG_UNMAP(si->regs[idx]); -+ si->regs[idx] = NULL; -+ } -+ -+ MFREE(si, sizeof (sb_info_t)); -+} -+ -+/* use pci dev id to determine chip id for chips not having a chipcommon core */ -+static uint -+sb_pcidev2chip(uint pcidev) -+{ -+ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) -+ return (BCM4710_DEVICE_ID); -+ if ((pcidev >= BCM4610_DEVICE_ID) && (pcidev <= BCM4610_USB_ID)) -+ return (BCM4610_DEVICE_ID); -+ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) -+ return (BCM4402_DEVICE_ID); -+ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) -+ return (BCM4307_DEVICE_ID); -+ if (pcidev == BCM4301_DEVICE_ID) -+ return (BCM4301_DEVICE_ID); -+ -+ return (0); -+} -+ -+/* convert chip number to number of i/o cores */ -+static uint -+sb_chip2numcores(uint chip) -+{ -+ if (chip == 0x4710) -+ return (9); -+ if (chip == 0x4610) -+ return (9); -+ if (chip == 0x4402) -+ return (3); -+ if ((chip == 0x4307) || (chip == 0x4301)) -+ return (5); -+ if (chip == 0x4310) -+ return (8); -+ if (chip == 0x4306) /* < 4306c0 */ -+ return (6); -+ if (chip == 0x4704) -+ return (9); -+ if (chip == 0x5365) -+ return (7); -+ -+ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); -+ ASSERT(0); -+ return (1); -+} -+ -+/* return index of coreid or BADIDX if not found */ -+static uint -+sb_findcoreidx(void *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++) -+ if (si->coreid[i] == coreid) { -+ if (found == coreunit) -+ return (i); -+ found++; -+ } -+ -+ return (BADIDX); -+} -+ -+/* change logical "focus" to the indiciated core */ -+void* -+sb_setcoreidx(void *sbh, uint coreidx) -+{ -+ sb_info_t *si; -+ uint32 sbaddr; -+ uint8 tmp; -+ -+ si = SB_INFO(sbh); -+ -+ if (coreidx >= si->numcores) -+ return (NULL); -+ -+ /* -+ * If the user has provided an interrupt mask enabled function, -+ * then assert interrupts are disabled before switching the core. -+ */ -+ ASSERT((si->imf == NULL) || !(*si->imf)(si->imfarg)); -+ -+ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); -+ -+ switch (si->bus) { -+ case SB_BUS: -+ /* map new one */ -+ if (!si->regs[coreidx]) { -+ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); -+ ASSERT(GOODREGS(si->regs[coreidx])); -+ } -+ si->curmap = si->regs[coreidx]; -+ break; -+ -+ case PCI_BUS: -+ /* point bar0 window */ -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); -+ break; -+ -+ case PCMCIA_BUS: -+ tmp = (sbaddr >> 12) & 0x0f; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); -+ tmp = (sbaddr >> 16) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); -+ tmp = (sbaddr >> 24) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); -+ break; -+ } -+ -+ si->curidx = coreidx; -+ -+ return (si->curmap); -+} -+ -+/* change logical "focus" to the indicated core */ -+void* -+sb_setcore(void *sbh, uint coreid, uint coreunit) -+{ -+ sb_info_t *si; -+ uint idx; -+ -+ si = SB_INFO(sbh); -+ -+ idx = sb_findcoreidx(sbh, coreid, coreunit); -+ if (!GOODIDX(idx)) -+ return (NULL); -+ -+ return (sb_setcoreidx(sbh, idx)); -+} -+ -+/* return chip number */ -+uint -+sb_chip(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->chip); -+} -+ -+/* return chip revision number */ -+uint -+sb_chiprev(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->chiprev); -+} -+ -+/* return chip package option */ -+uint -+sb_chippkg(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->chippkg); -+} -+ -+/* return board vendor id */ -+uint -+sb_boardvendor(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->boardvendor); -+} -+ -+/* return boardtype */ -+uint -+sb_boardtype(void *sbh) -+{ -+ sb_info_t *si; -+ char *var; -+ -+ si = SB_INFO(sbh); -+ -+ if (si->bus == SB_BUS && si->boardtype == 0xffff) { -+ /* boardtype format is a hex string */ -+ si->boardtype = getintvar(NULL, "boardtype"); -+ -+ /* backward compatibility for older boardtype string format */ -+ if ((si->boardtype == 0) && (var = getvar(NULL, "boardtype"))) { -+ if (!strcmp(var, "bcm94710dev")) -+ si->boardtype = BCM94710D_BOARD; -+ else if (!strcmp(var, "bcm94710ap")) -+ si->boardtype = BCM94710AP_BOARD; -+ else if (!strcmp(var, "bcm94310u")) -+ si->boardtype = BCM94310U_BOARD; -+ else if (!strcmp(var, "bu4711")) -+ si->boardtype = BU4711_BOARD; -+ else if (!strcmp(var, "bu4710")) -+ si->boardtype = BU4710_BOARD; -+ else if (!strcmp(var, "bcm94702mn")) -+ si->boardtype = BCM94702MN_BOARD; -+ else if (!strcmp(var, "bcm94710r1")) -+ si->boardtype = BCM94710R1_BOARD; -+ else if (!strcmp(var, "bcm94710r4")) -+ si->boardtype = BCM94710R4_BOARD; -+ else if (!strcmp(var, "bcm94702cpci")) -+ si->boardtype = BCM94702CPCI_BOARD; -+ else if (!strcmp(var, "bcm95380_rr")) -+ si->boardtype = BCM95380RR_BOARD; -+ } -+ } -+ -+ return (si->boardtype); -+} -+ -+/* return board bus style */ -+uint -+sb_boardstyle(void *sbh) -+{ -+ sb_info_t *si; -+ uint16 w; -+ -+ si = SB_INFO(sbh); -+ -+ if (si->bus == PCMCIA_BUS) -+ return (BOARDSTYLE_PCMCIA); -+ -+ if (si->bus == SB_BUS) -+ return (BOARDSTYLE_SOC); -+ -+ /* bus is PCI */ -+ -+ if (OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CIS, sizeof (uint32)) != 0) -+ return (BOARDSTYLE_CARDBUS); -+ -+ if ((srom_read(si->bus, si->curmap, si->osh, (SPROM_SIZE - 1) * 2, 2, &w) == 0) && -+ (w == 0x0313)) -+ return (BOARDSTYLE_CARDBUS); -+ -+ return (BOARDSTYLE_PCI); -+} -+ -+/* return boolean if sbh device is in pci hostmode or client mode */ -+uint -+sb_bus(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->bus); -+} -+ -+/* return list of found cores */ -+uint -+sb_corelist(void *sbh, uint coreid[]) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ -+ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); -+ return (si->numcores); -+} -+ -+/* return current register mapping */ -+void * -+sb_coreregs(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ ASSERT(GOODREGS(si->curmap)); -+ -+ return (si->curmap); -+} -+ -+/* Check if a target abort has happened and clear it */ -+bool -+sb_taclear(void *sbh) -+{ -+ sb_info_t *si; -+ bool rc = FALSE; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ -+ if (si->bus == PCI_BUS) { -+ uint32 stcmd; -+ -+ stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(stcmd)); -+ rc = (stcmd & 0x08000000) != 0; -+ -+ if (rc) { -+ /* Target abort bit is set, clear it */ -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD, sizeof(stcmd), stcmd); -+ } -+ } else if (si->bus == PCMCIA_BUS) { -+ rc = FALSE; -+ } -+ else if (si->bus == SDIO_BUS) { -+ /* due to 4317 A0 HW bug, sdio core wedged on target abort, -+ just clear SBSErr bit blindly */ -+ if (0x0 != R_SBREG(sbh, &sb->sbtmerrlog)) { -+ SB_ERROR(("SDIO target abort, clean it")); -+ W_SBREG(sbh, &sb->sbtmstatehigh, 0); -+ } -+ rc = FALSE; -+ } -+ -+ return (rc); -+} -+ -+/* do buffered registers update */ -+void -+sb_commit(void *sbh) -+{ -+ sb_info_t *si; -+ sbpciregs_t *pciregs; -+ uint origidx; -+ uint intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ -+ origidx = si->curidx; -+ ASSERT(GOODIDX(origidx)); -+ -+ INTR_OFF(si, intr_val); -+ /* switch over to pci core */ -+ pciregs = (sbpciregs_t*) sb_setcore(sbh, SB_PCI, 0); -+ -+ /* do the buffer registers update */ -+ W_REG(&pciregs->bcastaddr, SB_COMMIT); -+ W_REG(&pciregs->bcastdata, 0x0); -+ -+ /* restore core index */ -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+} -+ -+/* reset and re-enable a core */ -+void -+sb_core_reset(void *sbh, uint32 bits) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ volatile uint32 dummy; -+ -+ si = SB_INFO(sbh); -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ -+ /* -+ * Must do the disable sequence first to work for arbitrary current core state. -+ */ -+ sb_core_disable(sbh, bits); -+ -+ /* -+ * Now do the initialization sequence. -+ */ -+ -+ /* set reset while enabling the clock and forcing them on throughout the core */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); -+ -+ if (sb_coreid(sbh) == SB_ILINE100) { -+ bcm_mdelay(50); -+ } else { -+ OSL_DELAY(1); -+ } -+ -+ if (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_SERR) { -+ W_SBREG(sbh, &sb->sbtmstatehigh, 0); -+ } -+ if ((dummy = R_SBREG(sbh, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { -+ AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); -+ } -+ -+ /* clear reset and allow it to propagate throughout the core */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); -+ OSL_DELAY(1); -+ -+ /* leave clock enabled */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); -+ OSL_DELAY(1); -+} -+ -+void -+sb_core_tofixup(void *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ -+ if (si->pcirev >= 5) -+ return; -+ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ -+ if (si->bus == SB_BUS) { -+ SET_SBREG(sbh, &sb->sbimconfiglow, -+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); -+ } else { -+ if (sb_coreid(sbh) == SB_PCI) { -+ SET_SBREG(sbh, &sb->sbimconfiglow, -+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ } else { -+ SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); -+ } -+ } -+ -+ sb_commit(sbh); -+} -+ -+void -+sb_core_disable(void *sbh, uint32 bits) -+{ -+ sb_info_t *si; -+ volatile uint32 dummy; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ -+ /* must return if core is already in reset */ -+ if (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_RESET) -+ return; -+ -+ /* put into reset and return if clocks are not enabled */ -+ if ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_CLK) == 0) -+ goto disable; -+ -+ /* set the reject bit */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ)); -+ -+ /* spin until reject is set */ -+ while ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_REJ) == 0) -+ OSL_DELAY(1); -+ -+ /* spin until sbtmstatehigh.busy is clear */ -+ while (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_BUSY) -+ OSL_DELAY(1); -+ -+ /* set reset and reject while enabling the clocks */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); -+ OSL_DELAY(10); -+ -+ disable: -+ /* leave reset and reject asserted */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET)); -+ OSL_DELAY(1); -+} -+ -+void -+sb_watchdog(void *sbh, uint ticks) -+{ -+ sb_info_t *si = SB_INFO(sbh); -+ -+ /* instant NMI */ -+ switch (si->gpioid) { -+ case SB_CC: -+ sb_corereg(sbh, si->gpioidx, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); -+ break; -+ case SB_EXTIF: -+ sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); -+ break; -+ } -+} -+ -+/* initialize the pcmcia core */ -+void -+sb_pcmcia_init(void *sbh) -+{ -+ sb_info_t *si; -+ uint8 cor; -+ -+ si = SB_INFO(sbh); -+ -+ /* enable d11 mac interrupts */ -+ if (si->chip == BCM4301_DEVICE_ID) { -+ /* Have to use FCR2 in 4301 */ -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); -+ cor |= COR_IRQEN | COR_FUNEN; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); -+ } else { -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); -+ cor |= COR_IRQEN | COR_FUNEN; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); -+ } -+ -+} -+ -+ -+/* -+ * Configure the pci core for pci client (NIC) action -+ * and get appropriate dma offset value. -+ * coremask is the bitvec of cores by index to be enabled. -+ */ -+void -+sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ sbpciregs_t *pciregs; -+ uint32 sbflag; -+ uint32 w; -+ uint idx; -+ -+ si = SB_INFO(sbh); -+ -+ if (dmaoffset) -+ *dmaoffset = 0; -+ -+ /* if not pci bus, we're done */ -+ if (si->bus != PCI_BUS) -+ return; -+ -+ ASSERT(si->pciidx); -+ -+ /* get current core index */ -+ idx = si->curidx; -+ -+ /* we interrupt on this backplane flag number */ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ sbflag = R_SBREG(sbh, &sb->sbtpsflag) & SBTPS_NUM0_MASK; -+ -+ /* switch over to pci core */ -+ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx); -+ sb = REGS2SB(pciregs); -+ -+ /* -+ * Enable sb->pci interrupts. Assume -+ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. -+ */ -+ if (si->pcirev < 6) { -+ /* set sbintvec bit for our flag number */ -+ OR_SBREG(sbh, &sb->sbintvec, (1 << sbflag)); -+ } else { -+ /* pci config write to set this core bit in PCIIntMask */ -+ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); -+ w |= (coremask << PCI_SBIM_SHIFT); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); -+ } -+ -+ /* enable prefetch and bursts for sonics-to-pci translation 2 */ -+ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); -+ -+ if (si->pcirev < 5) { -+ SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ sb_commit(sbh); -+ } -+ -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); -+ -+ /* use large sb pci dma window */ -+ if (dmaoffset) -+ *dmaoffset = SB_PCI_DMA; -+} -+ -+uint32 -+sb_base(uint32 admatch) -+{ -+ uint32 base; -+ uint type; -+ -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); -+ -+ base = 0; -+ -+ if (type == 0) { -+ base = admatch & SBAM_BASE0_MASK; -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE1_MASK; -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE2_MASK; -+ } -+ -+ return (base); -+} -+ -+uint32 -+sb_size(uint32 admatch) -+{ -+ uint32 size; -+ uint type; -+ -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); -+ -+ size = 0; -+ -+ if (type == 0) { -+ 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); -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); -+ } -+ -+ return (size); -+} -+ -+/* return the core-type instantiation # of the current core */ -+uint -+sb_coreunit(void *sbh) -+{ -+ sb_info_t *si; -+ uint idx; -+ uint coreid; -+ uint coreunit; -+ uint i; -+ -+ si = SB_INFO(sbh); -+ coreunit = 0; -+ -+ idx = si->curidx; -+ -+ ASSERT(GOODREGS(si->curmap)); -+ coreid = sb_coreid(sbh); -+ -+ /* count the cores of our type */ -+ for (i = 0; i < idx; i++) -+ if (si->coreid[i] == coreid) -+ coreunit++; -+ -+ return (coreunit); -+} -+ -+static INLINE uint32 -+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; -+ } -+} -+ -+/* 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 n1, n2, clock, m1, m2, m3, mc; -+ -+ n1 = n & CN_N1_MASK; -+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { -+ n1 = factor6(n1); -+ n2 += CC_F5_BIAS; -+ } else if (pll_type == PLL_TYPE2) { -+ n1 += CC_T2_BIAS; -+ n2 += CC_T2_BIAS; -+ ASSERT((n1 >= 2) && (n1 <= 7)); -+ ASSERT((n2 >= 5) && (n2 <= 23)); -+ } else if (pll_type == PLL_TYPE3) { -+ return (100000000); -+ } else -+ ASSERT((pll_type >= PLL_TYPE1) && (pll_type <= PLL_TYPE4)); -+ -+ clock = CC_CLOCK_BASE * n1 * n2; -+ -+ if (clock == 0) -+ return 0; -+ -+ m1 = m & CC_M1_MASK; -+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; -+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; -+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { -+ m1 = factor6(m1); -+ if (pll_type == PLL_TYPE1) -+ m2 += CC_F5_BIAS; -+ else -+ m2 = factor6(m2); -+ 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); -+ } -+ } else { -+ ASSERT(pll_type == PLL_TYPE2); -+ -+ m1 += CC_T2_BIAS; -+ m2 += CC_T2M2_BIAS; -+ m3 += CC_T2_BIAS; -+ ASSERT((m1 >= 2) && (m1 <= 7)); -+ ASSERT((m2 >= 3) && (m2 <= 10)); -+ ASSERT((m3 >= 2) && (m3 <= 7)); -+ -+ if ((mc & CC_T2MC_M1BYP) == 0) -+ clock /= m1; -+ if ((mc & CC_T2MC_M2BYP) == 0) -+ clock /= m2; -+ if ((mc & CC_T2MC_M3BYP) == 0) -+ clock /= m3; -+ -+ return(clock); -+ } -+} -+ -+/* returns the current speed the SB is running at */ -+uint32 -+sb_clock(void *sbh) -+{ -+ sb_info_t *si; -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ uint32 n, m; -+ uint idx; -+ uint32 pll_type, rate; -+ uint intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ idx = si->curidx; -+ pll_type = PLL_TYPE1; -+ -+ INTR_OFF(si, intr_val); -+ -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ n = R_REG(&eir->clockcontrol_n); -+ m = R_REG(&eir->clockcontrol_sb); -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ n = R_REG(&cc->clockcontrol_n); -+ m = R_REG(&cc->clockcontrol_sb); -+ } else { -+ INTR_RESTORE(si, intr_val); -+ return 0; -+ } -+ -+ /* calculate rate */ -+ rate = sb_clock_rate(pll_type, n, m); -+ -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); -+ -+ INTR_RESTORE(si, intr_val); -+ -+ return rate; -+} -+ -+/* change logical "focus" to the gpio core for optimized access */ -+void* -+sb_gpiosetcore(void *sbh) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ -+ return (sb_setcoreidx(sbh, si->gpioidx)); -+} -+ -+/* mask&set gpiocontrol bits */ -+uint32 -+sb_gpiocontrol(void *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiocontrol); -+ break; -+ -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); -+ break; -+ -+ case SB_EXTIF: -+ return (0); -+ } -+ -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -+} -+ -+/* mask&set gpio output enable bits */ -+uint32 -+sb_gpioouten(void *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioouten); -+ break; -+ -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioouten); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpio[0].outen); -+ break; -+ } -+ -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -+} -+ -+/* mask&set gpio output bits */ -+uint32 -+sb_gpioout(void *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioout); -+ break; -+ -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioout); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpio[0].out); -+ break; -+ } -+ -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -+} -+ -+/* return the current gpioin register value */ -+uint32 -+sb_gpioin(void *sbh) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioin); -+ break; -+ -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioin); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpioin); -+ break; -+ } -+ -+ return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0)); -+} -+ -+/* mask&set gpio interrupt polarity bits */ -+uint32 -+sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); -+ break; -+ -+ case SB_PCI: -+ /* pci gpio implementation does not support interrupt polarity */ -+ ASSERT(0); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpiointpolarity); -+ break; -+ } -+ -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -+} -+ -+/* mask&set gpio interrupt mask bits */ -+uint32 -+sb_gpiointmask(void *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiointmask); -+ break; -+ -+ case SB_PCI: -+ /* pci gpio implementation does not support interrupt mask */ -+ ASSERT(0); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpiointmask); -+ break; -+ } -+ -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -+} -+ -+ -+/* -+ * Return the slowclock min or max frequency. -+ * Three sources of SLOW CLOCK: -+ * 1. On Chip LPO - 32khz or 160khz -+ * 2. On Chip Xtal OSC - 20mhz/4*(divider+1) -+ * 3. External PCI clock - 66mhz/4*(divider+1) -+ */ -+static uint -+slowfreq(void *sbh, bool max) -+{ -+ sb_info_t *si; -+ chipcregs_t *cc; -+ uint32 v; -+ uint div; -+ -+ si = SB_INFO(sbh); -+ -+ ASSERT(sb_coreid(sbh) == SB_CC); -+ -+ cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx); -+ -+ /* shouldn't be here unless we've established the chip has dynamic power control */ -+ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); -+ -+ if (si->ccrev < 6) { -+ v = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); -+ -+ if (v & PCI_CFG_GPIO_SCS) -+ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); -+ else -+ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); -+ } else { -+ v = R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; -+ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1); -+ if (v == SCC_SS_LPO) -+ return (max? LPOMAXFREQ : LPOMINFREQ); -+ else if (v == SCC_SS_XTAL) -+ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); -+ else if (v == SCC_SS_PCI) -+ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); -+ else -+ ASSERT(0); -+ } -+ return (0); -+} -+ -+/* initialize power control delay registers */ -+void -+sb_pwrctl_init(void *sbh) -+{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint slowmaxfreq; -+ uint pll_on_delay, fref_sel_delay; -+ -+ si = SB_INFO(sbh); -+ -+ if (si->bus == SB_BUS) -+ return; -+ -+ origidx = si->curidx; -+ -+ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) -+ return; -+ -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; -+ -+ slowmaxfreq = slowfreq(sbh, TRUE); -+ pll_on_delay = ((slowmaxfreq * PLL_DELAY) + 999999) / 1000000; -+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; -+ -+ W_REG(&cc->pll_on_delay, pll_on_delay); -+ W_REG(&cc->fref_sel_delay, fref_sel_delay); -+ -+ /* 4317pc does not work with SlowClock less than 5Mhz */ -+ if (si->bus == PCMCIA_BUS) -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (0 << SCC_CD_SHF)); -+ -+done: -+ sb_setcoreidx(sbh, origidx); -+} -+ -+/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ -+uint16 -+sb_pwrctl_fast_pwrup_delay(void *sbh) -+{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint slowminfreq; -+ uint16 fpdelay; -+ uint intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ fpdelay = 0; -+ origidx = si->curidx; -+ -+ if (si->bus == SB_BUS) -+ goto done; -+ -+ INTR_OFF(si, intr_val); -+ -+ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) -+ goto done; -+ -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; -+ -+ slowminfreq = slowfreq(sbh, FALSE); -+ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; -+ -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return (fpdelay); -+} -+ -+/* turn primary xtal and/or pll off/on */ -+int -+sb_pwrctl_xtal(void *sbh, uint what, bool on) -+{ -+ sb_info_t *si; -+ uint32 in, out, outen; -+ -+ si = SB_INFO(sbh); -+ -+ -+ if (si->bus == PCMCIA_BUS) { -+ return (0); -+ } -+ -+ if (si->bus != PCI_BUS) -+ 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)); -+ -+ /* -+ * 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(200); -+ } -+ -+ /* 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); -+ } -+ -+ return (0); -+} -+ -+/* set dynamic power control mode (forceslow, forcefast, dynamic) */ -+/* returns true if ignore pll off is set and false if it is not */ -+bool -+sb_pwrctl_clk(void *sbh, uint mode) -+{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint32 scc; -+ bool forcefastclk=FALSE; -+ uint intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ -+ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ -+ if (si->ccrev < 6) -+ return (FALSE); -+ -+ INTR_OFF(si, intr_val); -+ -+ origidx = si->curidx; -+ -+ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); -+ ASSERT(cc != NULL); -+ -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; -+ -+ switch (mode) { -+ case CLK_FAST: /* force fast (pll) clock */ -+ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ -+ sb_pwrctl_xtal(sbh, XTAL, ON); -+ -+ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); -+ break; -+ -+ case CLK_SLOW: /* force slow clock */ -+ if ((si->bus == SDIO_BUS) || (si->bus == PCMCIA_BUS)) -+ return (-1); -+ -+ if (si->ccrev >= 6) -+ OR_REG(&cc->slow_clk_ctl, SCC_FS); -+ break; -+ -+ case CLK_DYNAMIC: /* enable dynamic power control */ -+ scc = R_REG(&cc->slow_clk_ctl); -+ scc &= ~(SCC_FS | SCC_IP | SCC_XC); -+ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) -+ scc |= SCC_XC; -+ W_REG(&cc->slow_clk_ctl, scc); -+ -+ /* for dynamic control, we have to release our xtal_pu "force on" */ -+ if (scc & SCC_XC) -+ sb_pwrctl_xtal(sbh, XTAL, OFF); -+ break; -+ } -+ -+ /* Is the h/w forcing the use of the fast clk */ -+ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); -+ -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return (forcefastclk); -+} -+ -+/* register driver interrupt disabling and restoring callback functions */ -+void -+sb_register_intr_callback(void *sbh, void *intrsoff_fn, void *intrsrestore_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; -+ /* 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]; -+} -+ -+ -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/compressed/Makefile linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/Makefile ---- linux-2.6.12.5/arch/mips/bcm47xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/Makefile 2005-08-28 11:12:20.482851248 +0200 -@@ -0,0 +1,71 @@ -+# -+# 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$ -+# -+ -+# Link at 3 MB offset in RAM -+LOADADDR := 0x80001000 -+TEXT_START := 0x80500000 -+ifdef TEXTADDR -+LOADADDR := $(TEXTADDR) -+endif -+ -+STRIP := $(CROSS_COMPILE)strip -+ -+OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S -+ -+# SRCBASE := $(TOPDIR)/../.. -+VPATH := $(SRCBASE)/shared -+### Fix it by getting it from the Master rules -+ASFLAGS += -mno-abicalls -fno-pic -pipe -finline-limit=100000 -mips2 -Wa,--trap -I$(TOPDIR)/include/asm/mach-generic -+ASFLAGS += -I$(TOPDIR)/include/asm/gcc -nostdinc -+ASFLAGS += -D__ASSEMBLY__ -I$(TOPDIR)/arch/mips/bcm47xx/broadcom/include -I$(TOPDIR)/include -DLOADADDR=$(LOADADDR) -+CFLAGS += -I$(TOPDIR)/arch/mips/bcm47xx/broadcom/include -I$(TOPDIR)/include -DLOADADDR=$(LOADADDR) -+CFLAGS += -I$(TOPDIR)/include/asm/gcc -I$(TOPDIR)/include/asm/mach-generic -+ifdef CONFIG_MCOUNT -+CFLAGS := $(subst -pg,,$(CFLAGS)) -+endif -+SEDFLAGS := s/TEXT_START/$(TEXT_START)/ -+ -+SYSTEM := $(TOPDIR)/vmlinux -+#OBJECTS := head.o sbsdram.o misc.o sflash.o -+# Don't use nvram or dram initalization.Hope cfe to do it or kernel. -+OBJECTS := head.o misc.o -+ -+all: zImage -+ -+# Don't build dependencies, this may die if $(CC) isn't gcc -+dep: -+ -+bzImage: vmlinux -+ $(OBJCOPY) $< $@ -+ -+vmlinux: vmlinux.lds $(OBJECTS) piggy.o -+ $(LD) -no-warn-mismatch -T vmlinux.lds -o $@ $(OBJECTS) piggy.o -+ $(STRIP) $@ -+ -+vmlinux.lds: vmlinux.lds.in Makefile -+ @sed "$(SEDFLAGS)" < $< > $@ -+ -+piggy.o: $(SYSTEM) -+ cp $(SYSTEM) $(TOPDIR)/vmlinuxs -+ $(STRIP) $(TOPDIR)/vmlinuxs -+ $(OBJCOPY) $(TOPDIR)/vmlinuxs piggy -+ gzip -c9 piggy > vmlinuz -+ echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > piggy.lnk -+ $(LD) -no-warn-mismatch -T piggy.lnk -r -o $@ -b binary vmlinuz -b elf32-tradlittlemips -+ rm $(TOPDIR)/vmlinuxs -+ -+mrproper: clean -+ -+clean: -+ rm -f vmlinux vmlinuz zImage vmlinux.lds piggy piggy.lnk *.o -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/compressed/head.S linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/head.S ---- linux-2.6.12.5/arch/mips/bcm47xx/compressed/head.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/head.S 2005-08-28 11:12:20.502848208 +0200 -@@ -0,0 +1,84 @@ -+/* -+ * BCM947XX Self-Booting Linux -+ * -+ * Code should be position-independent until it copies itself to SDRAM. -+ * -+ * 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 <asm/asm.h> -+#include <asm/regdef.h> -+#include <asm/addrspace.h> -+#include <asm/mipsregs.h> -+#include <bcm4710.h> -+ -+ .text -+ LEAF(startup) -+ .set noreorder -+ -+/* Dont look at nvram now for dram initalization. Hope cfe/bootloader did it. Fix it latter */ -+ -+ blt t0, t1, inram -+ nop -+ -+#if 0 -+ /* Check if we booted from SDRAM */ -+ bal 1f -+ nop -+1: li t0, 0x1fffffff -+ and t0, t0, ra -+ li t1, BCM4710_FLASH -+ blt t0, t1, inram -+ nop -+ -+ /* Initialize SDRAM */ -+ li t0, KSEG1ADDR(BCM4710_FLASH) -+ la t1, text_start -+ la t2, board_draminit -+ sub t2, t2, t1 -+ add t2, t2, t0 -+ jalr t2 -+ nop -+ -+ /* Copy self to SDRAM */ -+ li a0, BCM4710_FLASH -+ la a1, text_start -+ la a2, input_data -+1: lw t0, 0(a0) -+ sw t0, 0(a1) -+ add a0, 4 -+ add a1, 4 -+ blt a1, a2, 1b -+ nop -+#endif -+inram: -+ /* Set up stack pointer */ -+ li sp, 0x80800000 - 4 -+ -+ /* Clear BSS */ -+ la a0, bss_start -+ la a1, bss_end -+1: sw zero, 0(a0) -+ addi a0, a0, 4 -+ blt a0, a1, 1b -+ nop -+ -+ /* Jump to C */ -+ la t0, c_main -+ jal t0 -+ move a0, ra -+ -+ /* Embedded NVRAM */ -+ .balign 0x400 -+ .space 0x2000 -+ -+ .set reorder -+ END(startup) -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/compressed/misc.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/misc.c ---- linux-2.6.12.5/arch/mips/bcm47xx/compressed/misc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/misc.c 2005-08-28 11:12:20.503848056 +0200 -@@ -0,0 +1,1183 @@ -+/* -+ * Misc initialization and support routines for self-booting -+ * compressed image. -+ * -+ * 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/init.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/mm.h> -+#include <linux/serial_reg.h> -+#include <linux/serial.h> -+#include <linux/delay.h> -+ -+#include <asm/bootinfo.h> -+#include <asm/cpu.h> -+#include <asm/bcache.h> -+#include <asm/io.h> -+#include <asm/page.h> -+#include <asm/pgtable.h> -+#include <asm/system.h> -+#include <asm/mmu_context.h> -+ -+#include <typedefs.h> -+#include <bcmdevs.h> -+#include <bcmnvram.h> -+#include <bcmutils.h> -+#include <sbconfig.h> -+#include <sbextif.h> -+#include <sbchipc.h> -+#include <sbmips.h> -+#include <sbmemc.h> -+#include <sflash.h> -+ -+/* At 125 MHz */ -+unsigned long loops_per_jiffy = 625000; -+ -+/* Static variables */ -+static unsigned int chipid, chiprev, mipscore; -+static unsigned int sbclock, mipsclock; -+static extifregs_t *eir; -+static chipcregs_t *cc; -+static mipsregs_t *mipsr; -+static sbmemcregs_t *memc; -+static void *usb; -+static struct serial_struct uart; -+static struct sflash *sflash; -+ -+#define LOG_BUF_LEN (1024) -+#define LOG_BUF_MASK (LOG_BUF_LEN-1) -+static char log_buf[LOG_BUF_LEN]; -+static unsigned long log_start; -+ -+/* Declarations needed for the cache related includes below */ -+ -+/* Primary cache parameters. These declarations are needed*/ -+static int icache_size, dcache_size; /* Size in bytes */ -+static int ic_lsize, dc_lsize; /* LineSize in bytes */ -+ -+/* Chip information */ -+unsigned int bcm_chipid = BCM4710_DEVICE_ID; -+unsigned int bcm_chiprev = 0; -+ -+#if 0 /* fix latter ... hope cfe has done it */ -+#include <asm/cacheops.h> -+#include <asm/bcm4710_cache.h> -+ -+__BUILD_SET_C0(taglo,CP0_TAGLO); -+__BUILD_SET_C0(taghi,CP0_TAGHI); -+ -+static void -+cache_init(void) -+{ -+ unsigned int config1; -+ unsigned int sets, ways; -+ unsigned int start, end; -+ -+ config1 = read_c0_config1(); -+ -+ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((ic_lsize = ((config1 >> 19) & 7))) -+ ic_lsize = 2 << ic_lsize; -+ sets = 64 << ((config1 >> 22) & 7); -+ ways = 1 + ((config1 >> 16) & 7); -+ icache_size = ic_lsize * sets * ways; -+ -+ start = KSEG0; -+ end = (start + icache_size); -+ clear_c0_taglo(~0); -+ clear_c0_taghi(~0); -+ while (start < end) { -+ cache_unroll(start, Index_Store_Tag_I); -+ start += ic_lsize; -+ } -+ -+ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((dc_lsize = ((config1 >> 10) & 7))) -+ dc_lsize = 2 << dc_lsize; -+ sets = 64 << ((config1 >> 13) & 7); -+ ways = 1 + ((config1 >> 7) & 7); -+ dcache_size = dc_lsize * sets * ways; -+ -+ start = KSEG0; -+ end = (start + dcache_size); -+ clear_c0_taglo(~0); -+ clear_c0_taghi(~0); -+ while (start < end) { -+ cache_unroll(start, Index_Store_Tag_D); -+ start += dc_lsize; -+ } -+} -+#endif -+ -+static inline unsigned int -+serial_in(struct serial_struct *info, int offset) -+{ -+#ifdef CONFIG_BCM4310 -+ readb((unsigned long) info->iomem_base + -+ (UART_SCR<<info->iomem_reg_shift)); -+#endif -+ return readb((unsigned long) info->iomem_base + -+ (offset<<info->iomem_reg_shift)); -+} -+ -+static inline void -+serial_out(struct serial_struct *info, int offset, int value) -+{ -+#ifdef SIM -+ return; -+#else -+ writeb(value, (unsigned long) info->iomem_base + -+ (offset<<info->iomem_reg_shift)); -+#endif -+} -+ -+static void -+sb_scan(void) -+{ -+ int i; -+ unsigned long cid, regs; -+ sbconfig_t *sb; -+ -+ /* Initialize static variables */ -+ eir = NULL; -+ cc = NULL; -+ usb = NULL; -+ memc = NULL; -+ mipsr = NULL; -+ mipscore = 0; -+ chipid = BCM4710_DEVICE_ID; -+ chiprev = 0; -+ -+ /* Too early to probe or malloc */ -+ for (i = 0; i < SB_MAXCORES; i++) { -+ regs = SB_ENUM_BASE + (i * SB_CORE_SIZE); -+ sb = (sbconfig_t *) KSEG1ADDR(regs + SBCONFIGOFF); -+ cid = (readl(&sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; -+ switch (cid) { -+ case SB_EXTIF: -+ eir = (extifregs_t *) KSEG1ADDR(regs); -+ break; -+ case SB_CC: -+ cc = (chipcregs_t *) KSEG1ADDR(regs); -+ chipid = readl(&cc->chipid) & CID_ID_MASK; -+ chiprev = (readl(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; -+ break; -+ case SB_USB: -+ usb = (void *)KSEG1ADDR(regs); -+ break; -+ case SB_MEMC: -+ memc = (void *)KSEG1ADDR(regs); -+ break; -+ case SB_MIPS: -+ case SB_MIPS33: -+ mipsr = (void *)KSEG1ADDR(regs); -+ mipscore = cid; -+ break; -+ } -+ if (eir) -+ break; -+ if (cc && mipsr) { -+ if (chipid == BCM4310_DEVICE_ID && chiprev == 0 && !usb) -+ continue; -+ else if (!memc) -+ continue; -+ break; -+ } -+ } -+} -+ -+static int -+keyhit(void) -+{ -+#ifdef SIM -+ return(1); -+#endif -+ -+ return ((serial_in(&uart, UART_LSR) & UART_LSR_DR) != 0); -+} -+ -+static int -+getc(void) -+{ -+#ifdef SIM -+ return(0); -+#endif -+ -+ while (!(serial_in(&uart, UART_LSR) & UART_LSR_DR)); -+ return (serial_in(&uart, UART_RX)); -+} -+ -+static void -+putc(int c) -+{ -+#ifdef SIM -+ return; -+#endif -+ /* CR before LF */ -+ if (c == '\n') -+ putc('\r'); -+ -+ /* Store in log buffer */ -+ *((char *) KSEG1ADDR(&log_buf[log_start])) = (char) c; -+ log_start = (log_start + 1) & LOG_BUF_MASK; -+ -+ while (!(serial_in(&uart, UART_LSR) & UART_LSR_THRE)); -+ serial_out(&uart, UART_TX, c); -+} -+ -+static void -+puts(const char *cs) -+{ -+#ifdef SIM -+ return; -+#else -+ char *s = (char *) cs; -+ short c; -+ -+ while (1) { -+ c = *(short *)(s); -+ if ((char)(c & 0xff)) -+ putc((char)(c & 0xff)); -+ else -+ break; -+ if ((char)((c >> 8) & 0xff)) -+ putc((char)((c >> 8) & 0xff)); -+ else -+ break; -+ s += sizeof(short); -+ } -+#endif -+} -+ -+static void -+puthex(unsigned int h) -+{ -+#ifdef SIM -+ return; -+#else -+ char c; -+ int i; -+ -+ for (i = 7; i >= 0; i--) { -+ c = (char)((h >> (i * 4)) & 0xf); -+ c += (c > 9) ? ('a' - 10) : '0'; -+ putc(c); -+ } -+#endif -+} -+ -+void -+putdec(unsigned int d) -+{ -+#ifdef SIM -+ return; -+#else -+ int leading_zero; -+ unsigned int divisor, result, remainder; -+ -+ leading_zero = 1; -+ remainder = d; -+ -+ for (divisor = 1000000000; -+ divisor > 0; -+ divisor /= 10) { -+ result = remainder / divisor; -+ remainder %= divisor; -+ -+ if (result != 0 || divisor == 1) -+ leading_zero = 0; -+ -+ if (leading_zero == 0) -+ putc((char)(result) + '0'); -+ } -+#endif -+} -+ -+static INLINE uint32 -+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; -+ } -+} -+ -+/* calculate the speed the SB would run at given a set of clockcontrol values */ -+static uint32 -+sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) -+{ -+#if 1 /* PLL clock ??? */ -+#warning "Fix Me....................... misc.c sb_clock_rate" -+ return 100; -+#else -+ uint32 n1, n2, clock, m1, m2, m3, mc; -+ -+ n1 = n & CN_N1_MASK; -+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { -+ n1 = factor6(n1); -+ n2 += CC_F5_BIAS; -+ } else if (pll_type == PLL_TYPE2) { -+ n1 += CC_T2_BIAS; -+ n2 += CC_T2_BIAS; -+ } else if (pll_type == PLL_TYPE3) { -+ return (100000000); -+ } -+ -+ clock = CC_CLOCK_BASE * n1 * n2; -+ -+ if (clock == 0) -+ return 0; -+ -+ m1 = m & CC_M1_MASK; -+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; -+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; -+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { -+ m1 = factor6(m1); -+ if (pll_type == PLL_TYPE1) -+ m2 += CC_F5_BIAS; -+ else -+ m2 = factor6(m2); -+ 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); -+ } -+ } else { -+ m1 += CC_T2_BIAS; -+ m2 += CC_T2M2_BIAS; -+ m3 += CC_T2_BIAS; -+ -+ if ((mc & CC_T2MC_M1BYP) == 0) -+ clock /= m1; -+ if ((mc & CC_T2MC_M2BYP) == 0) -+ clock /= m2; -+ if ((mc & CC_T2MC_M3BYP) == 0) -+ clock /= m3; -+ -+ return(clock); -+ } -+#endif -+} -+ -+static void -+uart_init(int baud) -+{ -+ sbconfig_t *sb; -+ unsigned long base, hz, ns, tmp; -+ int quot; -+ -+ if (eir) { -+#if 0 -+ /* Determine external UART register base */ -+ sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); -+ base = EXTIF_CFGIF_BASE(readl(&sb->sbadmatch1) & SBAM_BASE1_MASK); -+ -+ /* Enable programmable interface */ -+ writel(CF_EN, &eir->prog_config); -+ -+ /* Calculate clock cycle */ -+ sbclock = mipsclock = hz = sb_clock_rate(PLL_TYPE1, readl(&eir->clockcontrol_n), readl(&eir->clockcontrol_sb)); -+ hz = hz ? : 100000000; -+ ns = 1000000000 / hz; -+ -+ /* 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 */ -+ writel(tmp, &eir->prog_waitcount); /* 0x01020a0c for a 100Mhz clock */ -+ -+ uart.baud_base = 13500000 / 16; -+ uart.iomem_reg_shift = 0; -+ uart.iomem_base = (u8 *) KSEG1ADDR(base); -+#endif -+ } else if (cc) { -+ uint32 rev, cap, pll_type, tmp; -+ -+ /* Determine core revision */ -+ sb = (sbconfig_t *)((unsigned int) cc + SBCONFIGOFF); -+ rev = readl(&sb->sbidhigh) & SBIDH_RC_MASK; -+ cap = readl(&cc->capabilities); -+ pll_type = cap & CAP_PLL_MASK; -+ -+ /* Determine internal UART clock source */ -+ if (bcm_chipid ==BCM5365_DEVICE_ID) { -+#ifdef CONFIG_BCM5XXX_FPGA -+ uart.baud_base = 2000000; -+#else -+ uart.baud_base = 1850000; -+#endif -+ }else if (pll_type ==0x0010000) { -+ /* PLL clock */ -+ uart.baud_base = sb_clock_rate(pll_type, readl(&cc->clockcontrol_n), -+ readl(&cc->clockcontrol_m2)); -+ sbclock = mipsclock = hz = sb_clock_rate(pll_type, readl(&cc->clockcontrol_n), -+ readl(&cc->clockcontrol_sb)); -+ } else { -+ uint32 div; -+ -+ sbclock = hz = sb_clock_rate(pll_type, readl(&cc->clockcontrol_n), -+ readl(&cc->clockcontrol_sb)); -+ mipsclock = sb_clock_rate(pll_type, readl(&cc->clockcontrol_n), -+ readl(&cc->clockcontrol_mips)); -+ /* Internal backplane clock */ -+ if (rev >= 3) { -+ uart.baud_base = sbclock; -+ div = uart.baud_base / 1843200; -+ writel(div, &cc->uart_clkdiv); -+ } else { -+ uart.baud_base = 88000000; -+ div = 48; -+ } -+ if ((rev > 0) && ((readl(&cc->corecontrol) & CC_UARTCLKO) == 0)) { -+ /* If UartClkOvveride is not set then t depends on strapping -+ * as reflected by the UCLKSEL field; -+ */ -+ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) { -+ /* Internal divided backplane clock */ -+ uart.baud_base /= div; -+ } else { -+ /* Assume external clock of 1.8432 MHz */ -+ uart.baud_base = 1843200; -+ } -+ } -+ } -+ ns = 1000000000 / hz; -+ -+#if 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 */ -+ writel(tmp, &cc->parallelflashwaitcnt); -+#endif -+ -+ writel(tmp, &cc->cs01memwaitcnt); -+ -+ uart.baud_base /= 16; -+ uart.iomem_reg_shift = 0; -+#if 1 -+#warning "UART base Fix copied from linux " -+#define UART_BASE 0xb8000400 -+ uart.iomem_base = (u8 *) UART_BASE; -+#if 0 -+ if (rev) -+ uart.iomem_base = (u8 *) &cc->uart0data + (uart.line * 256); -+ else -+ uart.iomem_base = (u8 *) &cc->uart0data + (uart.line * 8); -+#endif -+#else -+ uart.iomem_base = (u8 *) &cc->uart0data; -+#endif -+ } -+ -+ loops_per_jiffy = 5 * (mipsclock / 1000); -+ -+ /* Set baud and 8N1 */ -+ quot = uart.baud_base / baud; -+ serial_out(&uart, UART_LCR, UART_LCR_DLAB); -+ serial_out(&uart, UART_DLL, quot & 0xff); -+ serial_out(&uart, UART_DLM, quot >> 8); -+ serial_out(&uart, UART_LCR, UART_LCR_WLEN8); -+} -+ -+static void -+reset_usb(chipcregs_t *cc, void *usb) -+{ -+#if defined(CONFIG_USB_OHCI) || defined(CONFIG_USBDEV) -+ sbconfig_t *sb; -+ -+ sb = (sbconfig_t *)((unsigned int) usb + SBCONFIGOFF); -+ if ((readl(&cc->intstatus) & 0x80000000) == 0 && -+ (readl(&sb->sbidhigh) & SBIDH_RC_MASK) == 1) { -+ /* Reset USB host core into sane state */ -+ writel((1 << 29) | SBTML_RESET | SBTML_CLK, &sb->sbtmstatelow); -+ udelay(10); -+ /* Reset USB device core into sane state */ -+ writel(SBTML_RESET | SBTML_CLK, &sb->sbtmstatelow); -+ udelay(10); -+ /* Reset backplane to 96 MHz */ -+ writel(0x0303, &cc->clockcontrol_n); -+ writel(0x04020011, &cc->clockcontrol_sb); -+ writel(0x11030011, &cc->clockcontrol_pci); -+ writel(0x01050811, &cc->clockcontrol_m2); -+ writel(1, &cc->watchdog); -+ while (1); -+ } -+#endif -+} -+ -+static void -+error(char *x) -+{ -+ puts("\n\n"); -+ puts(x); -+ puts("\n\n -- System halted"); -+ -+ while(1); /* Halt */ -+} -+ -+ -+/* -+ * gzip declarations -+ */ -+ -+#define OF(args) args -+#define STATIC static -+ -+#undef memset -+#undef memcpy -+#define memzero(s, n) memset ((s), 0, (n)) -+ -+typedef unsigned char uch; -+typedef unsigned short ush; -+typedef unsigned long ulg; -+ -+#define WSIZE 0x8000 /* Window size must be at least 32k, */ -+ /* and a power of two */ -+ -+static uch *inbuf; /* input buffer */ -+static ulg tmp; -+static uch window[WSIZE]; /* Sliding window buffer */ -+ -+static unsigned insize; /* valid bytes in inbuf */ -+static unsigned inptr; /* index of next byte to be processed in inbuf */ -+static unsigned outcnt; /* bytes in output buffer */ -+ -+/* gzip flag byte */ -+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -+#define COMMENT 0x10 /* bit 4 set: file comment present */ -+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -+#define RESERVED 0xC0 /* bit 6,7: reserved */ -+ -+extern uch input_data[]; -+extern int input_len; -+extern char text_start[], text_end[]; -+extern char data_start[], data_end[]; -+extern char bss_start[], bss_end[]; -+ -+static inline uch -+get_byte(void) -+{ -+ if (sflash) { -+#if 0 -+ uch c; -+ sflash_read(cc, inptr++, 1, &c); -+ return c; -+#endif -+ } else { -+ if ((inptr % 4) == 0) -+ tmp = *((ulg *) &inbuf[inptr]); -+ return ((uch *) &tmp)[inptr++ % 4]; -+ } -+} -+ -+/* Diagnostic functions */ -+#ifdef DEBUG -+# define Assert(cond,msg) {if(!(cond)) error(msg);} -+# define Trace(x) fprintf x -+# define Tracev(x) {if (verbose) fprintf x ;} -+# define Tracevv(x) {if (verbose>1) fprintf x ;} -+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -+#else -+# define Assert(cond,msg) -+# define Trace(x) -+# define Tracev(x) -+# define Tracevv(x) -+# define Tracec(c,x) -+# define Tracecv(c,x) -+#endif -+ -+static void flush_window(void); -+static void error(char *m); -+static void gzip_mark(void **); -+static void gzip_release(void **); -+ -+static uch *output_data; -+static ulg output_ptr; -+static ulg bytes_out; -+ -+static void *malloc(int size); -+static void free(void *where); -+static void error(char *m); -+static void gzip_mark(void **); -+static void gzip_release(void **); -+ -+static void puts(const char *); -+ -+extern int end; -+static ulg free_mem_ptr; -+static ulg free_mem_ptr_end; -+ -+#define HEAP_SIZE 0x2000 -+ -+#include "../../../../../lib/inflate.c" -+ -+static void * -+malloc(int size) -+{ -+ void *p; -+ -+ if (size <0) error("Malloc error\n"); -+ if (free_mem_ptr <= 0) error("Memory error\n"); -+ -+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ -+ -+ p = (void *)free_mem_ptr; -+ free_mem_ptr += size; -+ -+ if (free_mem_ptr >= free_mem_ptr_end) -+ error("Out of memory"); -+ return p; -+} -+ -+static void -+free(void *where) -+{ /* gzip_mark & gzip_release do the free */ -+} -+ -+static void -+gzip_mark(void **ptr) -+{ -+ *ptr = (void *) free_mem_ptr; -+} -+ -+static void -+gzip_release(void **ptr) -+{ -+ free_mem_ptr = (long) *ptr; -+} -+ -+void* -+memset(void* s, int c, size_t n) -+{ -+ int i; -+ char *ss = (char*)s; -+ -+ for (i=0;i<n;i++) ss[i] = c; -+ return s; -+} -+ -+void* -+memcpy(void* __dest, __const void* __src, size_t __n) -+{ -+ int i; -+ char *d = (char *)__dest, *s = (char *)__src; -+ -+ for (i=0;i<__n;i++) d[i] = s[i]; -+ return __dest; -+} -+ -+/* =========================================================================== -+ * Write the output window window[0..outcnt-1] and update crc and bytes_out. -+ * (Used for the decompressed data only.) -+ */ -+void -+flush_window(void) -+{ -+ ulg c = crc; -+ unsigned n; -+ uch *in, *out, ch; -+ -+ in = window; -+ out = &output_data[output_ptr]; -+ for (n = 0; n < outcnt; n++) { -+ ch = *out++ = *in++; -+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); -+ } -+ crc = c; -+ bytes_out += (ulg)outcnt; -+ output_ptr += (ulg)outcnt; -+ outcnt = 0; -+ puts("."); -+} -+ -+static void -+decompress_kernel(void) -+{ -+#if 1 /* Fix Me */ -+ inbuf = (uch *) 0x80500000; -+#else -+ /* Decompress from flash */ -+ inbuf = (uch *) KSEG1ADDR(0x1fc00000); -+#endif -+ insize = input_len; -+ inptr = (unsigned) input_data - (unsigned) text_start; -+ output_data = (uch *) LOADADDR; -+ free_mem_ptr = (ulg) bss_end; -+ free_mem_ptr_end = (ulg) bss_end + 0x100000; -+ -+ makecrc(); -+ puts("Uncompressing Linux..."); -+ -+ gunzip(); -+ -+ puts("done, booting the kernel.\n"); -+ -+#if 0 -+ /* Flush all caches */ -+ blast_dcache(); -+ blast_icache(); -+#endif -+ -+ /* Jump to kernel */ -+ ((void (*)(void)) LOADADDR)(); -+} -+ -+#if 0 -+static void -+sflash_self(chipcregs_t *cc) -+{ -+ unsigned char *start = text_start; -+ unsigned char *end = data_end; -+ unsigned char *cur = start; -+ unsigned int erasesize, len; -+ -+ while (cur < end) { -+ /* Erase sector */ -+ puts("Erasing sector 0x"); -+ puthex(cur - start); -+ puts("..."); -+ if ((erasesize = sflash_erase(cc, cur - start)) < 0) { -+ puts("error\n"); -+ break; -+ } -+ while (sflash_poll(cc, cur - start)); -+ puts("done\n"); -+ -+ /* Write sector */ -+ puts("Writing sector 0x"); -+ puthex(cur - start); -+ puts("..."); -+ while (erasesize) { -+ if ((len = sflash_write(cc, cur - start, erasesize, cur)) < 0) -+ break; -+ while (sflash_poll(cc, cur - start)); -+ cur += len; -+ erasesize -= len; -+ } -+ if (erasesize) { -+ puts("error\n"); -+ break; -+ } -+ puts("done\n"); -+ } -+} -+ -+static void -+_change_cachability(u32 cm) -+{ -+ u32 prid; -+ -+ change_c0_config(CONF_CM_CMASK, cm); -+ prid = read_c0_prid(); -+ if ((prid & (PRID_COMP_MASK | PRID_IMP_MASK)) == -+ (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) { -+ cm = read_c0_diag(); -+ /* Enable icache */ -+ cm |= (1 << 31); -+ /* Enable dcache */ -+ cm |= (1 << 30); -+ write_c0_diag(cm); -+ } -+} -+static void (*change_cachability)(u32); -+ -+#define HANDLER_ADDR 0xa0000180 -+ -+void -+handler(void) -+{ -+ /* enable interrupts */ -+ clear_c0_status(IE_IRQ5 | IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1 | IE_IRQ0 | ST0_IE); -+ -+ __asm__ __volatile__ (".set\tmips32\n\t" -+ "ssnop\n\t" -+ "ssnop\n\t" -+ "eret\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ ".set\tmips0"); /* step 11 */ -+} -+/* The followint MUST come right after handler() */ -+void -+afterhandler(void) -+{ -+} -+ -+#define BCM4704_DEFAULT_MIPS_CLOCK 200000000 -+static unsigned int target_mips_clock = 264000000; -+static unsigned int target_sb_clock = 132000000; -+ -+typedef struct { -+ uint32 mipsclock; -+ uint32 sbclock; -+ uint16 n; -+ uint32 sb; -+ uint32 pci; -+ uint32 m2; -+ uint32 m3; -+ uint ratio; -+ uint32 ratio_parm; -+} sb_clock_table_t; -+ -+static sb_clock_table_t sb_clock_table[] = { -+ { 180000000, 90000000, 0x0403, 0x02000002, 0x00000002, 0x02000002, 0x06000002, 0x21, 0x0aaa0555}, -+ { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 0x21, 0x0aaa0555}, -+ { 264000000, 132000000, 0x0903, 0x02000003, 0x04000702, 0x02000003, 0x06000003, 0x21, 0x0aaa0555}, -+ { 280000000, 140000000, 0x0503, 0x02010000, 0x00010001, 0x02010000, 0x06000001, 0x21, 0x0aaa0555}, -+ { 288000000, 144000000, 0x0404, 0x02010000, 0x00010001, 0x02010000, 0x06000001, 0x21, 0x0aaa0555}, -+ { 300000000, 150000000, 0x0803, 0x02000002, 0x00010002, 0x02000002, 0x06000002, 0x21, 0x0aaa0555}, -+ { 180000000, 80000000, 0x0403, 0x02010001, 0x00000002, 0x00010101, 0x06000002, 0x49, 0x012A00A9}, -+ { 234000000, 104000000, 0x0b01, 0x02010001, 0x04000204, 0x00010101, 0x06000002, 0x49, 0x01250125}, -+ { 300000000, 133333333, 0x0803, 0x02010001, 0x00010101, 0x00010101, 0x06000002, 0x49, 0x012a0115}, -+ { 0 } -+}; -+ -+void -+change_clock(void) -+{ -+ int c; -+ u32 s, e, d, i, tmp, ratio_parm; -+ sb_clock_table_t *cte, *ccte = NULL, *tcte = NULL; -+ -+ /* Change the clock and reboot if needed */ -+ /* Gross hack for now to go all the way */ -+ if (chipid == BCM4704_DEVICE_ID) { -+ if (mipsclock != BCM4704_DEFAULT_MIPS_CLOCK) { -+ target_mips_clock = mipsclock; -+ target_sb_clock = sbclock; -+ } -+ if ((mipsclock != target_mips_clock) || (sbclock != target_sb_clock)) { -+ for (cte = sb_clock_table; cte->mipsclock; cte++) { -+ if ((cte->mipsclock == mipsclock) && (cte->sbclock == sbclock)) -+ ccte = cte; -+ if ((cte->mipsclock == target_mips_clock) && (cte->sbclock == target_sb_clock)) -+ tcte = cte; -+ } -+ -+ if ((ccte == NULL) || (tcte == NULL)) { -+ puts("\nCould not figure out current or target settings"); -+ goto nochange; -+ } -+ -+ puts("Run at "); -+ putdec(tcte->mipsclock); -+ putc('/'); -+ putdec(tcte->sbclock); -+ putc('?'); -+ c = 'y'; -+ for (i = 50; i; i--) { -+ if (keyhit()) { -+ c = getc() | 0x20; -+ break; -+ } -+ if ((i % 10) == 0) -+ putc('.'); -+ mdelay(100); -+ } -+ if (c != 'y') { -+ for (i = 0, cte = sb_clock_table; cte->mipsclock; i++, cte++) { -+ puts("\n ["); -+ putdec(i); -+ puts("] = "); -+ putdec(cte->mipsclock); -+ putc('/'); -+ putdec(cte->sbclock); -+ if (cte == tcte) -+ putc('*'); -+ } -+ -+ while (1) { -+ puts("\nChange to ?"); -+ c = getc() - '0'; -+ if ((c >= 0) && (c < i)) -+ tcte = &sb_clock_table[c]; -+ else { -+ puts("\nPlase type a number from 0 to "); -+ putdec(i - 1); -+ continue; -+ } -+ target_mips_clock = tcte->mipsclock; -+ target_sb_clock = tcte->sbclock; -+ puts("\nChanging to "); -+ putdec(tcte->mipsclock); -+ putc('/'); -+ putdec(tcte->sbclock); -+ puts(", ok?"); -+ c = getc() | 0x20; -+ if (c == 'y') -+ break; -+ } -+ } -+ if (tcte == ccte) -+ goto nochange; -+ -+ /* Set the pll controls now */ -+ writel(tcte->n, &cc->clockcontrol_n); -+ writel(tcte->sb, &cc->clockcontrol_sb); -+ writel(tcte->pci, &cc->clockcontrol_pci); -+ writel(tcte->m2, &cc->clockcontrol_m2); -+ writel(tcte->m3, &cc->clockcontrol_mips); -+ -+ if (tcte->ratio_parm != ccte->ratio_parm) { -+ puts("\nChanging ratio_parm to 0x"); -+ puthex(tcte->ratio_parm); -+ puts(", type new one to override: "); -+ ratio_parm = 0; -+ while (1) { -+ c = getc() & 0x7f; -+ putc(c); -+ if ((c == 'x') || (c == 'X')) { -+ ratio_parm = 0; -+ continue; -+ } -+ if ((c >= '0') && (c <= '9')) { -+ ratio_parm = (ratio_parm << 4) + (c - '0'); -+ continue; -+ } -+ c &= ~0x20; -+ if ((c >= 'A') && (c <= 'F')) -+ ratio_parm = (ratio_parm << 4) + (c - 'A' + 10); -+ else -+ break; -+ } -+ putc('\n'); -+ -+ if (ratio_parm == 0) -+ ratio_parm = tcte->ratio_parm; -+ -+ /* Preload the code in the cache */ -+ s = ((u32)&&start_fill) & ~(ic_lsize - 1); -+ e = (((u32)&&end_fill) + (ic_lsize - 1)) & ~(ic_lsize - 1); -+ while (s < e) { -+ cache_unroll(s, Fill); -+ s += ic_lsize; -+ } -+ -+ /* Copy the handler & preload it into the cache */ -+ s = (u32)&handler; -+ e = (u32)&afterhandler; -+ d = HANDLER_ADDR; -+ while (s < e) { -+ for (i = 0; i < ic_lsize; i += 4) { -+ *(long*)(d + i) = *(long *)(s + i); -+ } -+ cache_unroll(d, Fill); -+ s += ic_lsize; -+ d += ic_lsize; -+ } -+ -+ /* Clear BEV bit */ -+ clear_c0_status(ST0_BEV); -+ -+ /* enable interrupts */ -+ set_c0_status(IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1 | IE_IRQ0 | ST0_IE); -+ /* enable timer interrupts */ -+ writel(1, &mipsr->intmask); -+ -+start_fill: -+ /* step 1, set clock ratios */ -+ write_c0_diag3(ratio_parm); -+ write_c0_diag1(8); -+ -+ /* step 2: program timer intr */ -+ writel(100, &mipsr->timer); -+ tmp = readl(&mipsr->timer); /* read it back to sync */ -+ -+ /* step 3, switch to async */ -+ write_c0_diag4(1 << 22); -+ -+ /* step 4, set cfg active */ -+ write_c0_diag2(0x9); -+ -+ /* steps 5 & 6 */ -+ __asm__ __volatile__(".set\tmips3\n\t" -+ "wait\n\t" -+ ".set\tmips0"); -+ -+ /* step 7, clear cfg_active */ -+ write_c0_diag2(0); -+ -+ /* step 8, fake soft reset */ -+ write_c0_diag5(read_c0_diag5() | 4); -+ } -+ -+ /* step 9 set watchdog timer */ -+ writel(20, &cc->watchdog); -+ tmp = readl(&cc->chipid); /* dummy read */ -+ -+ /* step 11 */ -+ __asm__ __volatile__(".set\tmips3\n\t" -+ "sync\n\t" -+ "wait\n\t" -+ ".set\tmips0"); -+ while (1); -+ } else { -+end_fill: -+nochange: -+ puts("\nNot changing clock. mips="); -+ putdec(target_mips_clock); -+ putc('/'); -+ putdec(target_sb_clock); -+ putc('\n'); -+ } -+ } else { -+ puts("Not a 4704, not changing clock\n"); -+ } -+} -+#endif -+ -+void -+c_main(unsigned long ra) -+{ -+ /* Disable interrupts */ -+ clear_c0_status(1); -+ -+ /* Scan backplane */ -+ sb_scan(); -+ -+// if (cc && usb && PHYSADDR(ra) >= 0x1fc00000) -+ reset_usb(cc, usb); -+ -+ -+ /* Determine chip ID and revision */ -+ if (cc) { -+ bcm_chipid = readl(&cc->chipid) & CID_ID_MASK; -+ bcm_chiprev = (readl(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; -+ } -+ -+ /* Initialize UART */ -+ uart_init(115200); -+#if 0 -+ puts("\nSelf-booting Linux running on a "); -+ puthex(chipid); -+ puts(" Rev. "); -+ putdec(chiprev); -+ puts(" @ "); -+ putdec(mipsclock); -+ putc('/'); -+ putdec(sbclock); -+ putc('\n'); -+ -+ puts("CP0 PRID: 0x"); -+ puthex(read_c0_prid()); -+ putc('\n'); -+ puts("CP0 Conf: 0x"); -+ puthex(read_c0_conf()); -+ putc('\n'); -+ puts("CP0 Info: 0x"); -+ puthex(read_c0_info()); -+ putc('\n'); -+ puts("CP0 Status: 0x"); -+ puthex(read_c0_status()); -+ putc('\n'); -+ puts("CP0 Cause: 0x"); -+ puthex(read_c0_cause()); -+ putc('\n'); -+ puts("CP0 Config: 0x"); -+ puthex(read_c0_config()); -+ putc('\n'); -+ puts("CP0 Config1: 0x"); -+ puthex(read_c0_config1()); -+ putc('\n'); -+ if (mipscore == SB_MIPS33) -+ puts("CP0 Reg22: sel0/1/2/3/4/5:\n "); -+ else -+ puts("CP0 Reg22: 0x"); -+ puthex(read_c0_diag()); -+ if (mipscore == SB_MIPS33) { -+ puts("\n "); -+ puthex(read_c0_diag1()); -+ puts("\n "); -+ puthex(read_c0_diag2()); -+ puts("\n "); -+ puthex(read_c0_diag3()); -+ puts("\n "); -+ puthex(read_c0_diag4()); -+ puts("\n "); -+ puthex(read_c0_diag5()); -+ } -+ putc('\n'); -+ -+ if (memc) { -+ puts("memc config: 0x"); -+ puthex(readl(&memc->config)); -+ putc('\n'); -+ puts("memc mode: 0x"); -+ puthex(readl(&memc->modebuf)); -+ putc('\n'); -+ puts("memc wrncdl: 0x"); -+ puthex(readl(&memc->wrncdlcor)); -+ putc('\n'); -+ puts("memc rdncdl: 0x"); -+ puthex(readl(&memc->rdncdlcor)); -+ putc('\n'); -+ puts("memc miscdly: 0x"); -+ puthex(readl(&memc->miscdlyctl)); -+ putc('\n'); -+ puts("memc dqsgate: 0x"); -+ puthex(readl(&memc->dqsgatencdl)); -+ putc('\n'); -+ } -+#endif -+#if 0 -+ /* Switch back to sync */ -+ write_c0_diag4(0); -+#endif -+#if 1 -+#warning "Fix cache init " -+#else -+ /* Must be in KSEG1 to change cachability */ -+ cache_init(); -+ change_cachability = (void (*)(u32)) KSEG1ADDR((unsigned long)(_change_cachability)); -+ change_cachability(CONF_CM_CACHABLE_NONCOHERENT); -+ -+ /* Change clock if needed */ -+ change_clock(); -+ -+ /* Initialize serial flash */ -+ sflash = cc ? sflash_init(cc) : NULL; -+ -+ if (sflash) -+ puts("sflash set???"); -+ -+ /* Copy self to flash if we booted from SDRAM */ -+ if (PHYSADDR(ra) < 0x1fc00000) { -+ if (sflash) -+ sflash_self(cc); -+ } -+#endif -+ -+ /* Decompress kernel */ -+ decompress_kernel(); -+} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/compressed/piggy.lnk linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/piggy.lnk ---- linux-2.6.12.5/arch/mips/bcm47xx/compressed/piggy.lnk 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/piggy.lnk 2005-08-28 11:12:20.504847904 +0200 -@@ -0,0 +1 @@ -+SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/compressed/vmlinux.lds linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/vmlinux.lds ---- linux-2.6.12.5/arch/mips/bcm47xx/compressed/vmlinux.lds 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/vmlinux.lds 2005-08-28 11:12:20.504847904 +0200 -@@ -0,0 +1,23 @@ -+OUTPUT_ARCH(mips) -+ENTRY(startup) -+SECTIONS { -+ . = 0x80500000 ; -+ .text : { -+ text_start = .; -+ *(.text) -+ *(.rodata) -+ text_end = .; -+ } -+ -+ .data : { -+ data_start = .; -+ *(.data) -+ data_end = .; -+ } -+ -+ .bss : { -+ bss_start = .; -+ *(.bss) -+ bss_end = .; -+ } -+} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/compressed/vmlinux.lds.in linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/vmlinux.lds.in ---- linux-2.6.12.5/arch/mips/bcm47xx/compressed/vmlinux.lds.in 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/compressed/vmlinux.lds.in 2005-08-28 11:12:20.504847904 +0200 -@@ -0,0 +1,23 @@ -+OUTPUT_ARCH(mips) -+ENTRY(startup) -+SECTIONS { -+ . = TEXT_START; -+ .text : { -+ text_start = .; -+ *(.text) -+ *(.rodata) -+ text_end = .; -+ } -+ -+ .data : { -+ data_start = .; -+ *(.data) -+ data_end = .; -+ } -+ -+ .bss : { -+ bss_start = .; -+ *(.bss) -+ bss_end = .; -+ } -+} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/int-handler.S linux-2.6.12.5-brcm/arch/mips/bcm47xx/int-handler.S ---- linux-2.6.12.5/arch/mips/bcm47xx/int-handler.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/int-handler.S 2005-08-28 11:12:20.505847752 +0200 -@@ -0,0 +1,24 @@ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> @@ -15581,10 +14180,34 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/int-handler.S linux-2.6.12.5-brcm/arc + nop + + END(bcm47xx_irq_handler) -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/irq.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/irq.c ---- linux-2.6.12.5/arch/mips/bcm47xx/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/irq.c 2005-08-28 11:12:20.505847752 +0200 -@@ -0,0 +1,52 @@ +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c +--- linux-2.6.12.5/arch/mips/bcm947xx/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c 2005-08-28 16:58:26.178029536 +0200 +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ +#include <linux/config.h> +#include <linux/errno.h> +#include <linux/init.h> @@ -15608,11 +14231,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/irq.c linux-2.6.12.5-brcm/arch/mips/b + + cause = read_c0_cause() & read_c0_status() & CAUSEF_IP; + -+#ifdef CONFIG_KERNPROF -+ change_c0_status(cause | 1, 1); -+#else + clear_c0_status(cause); -+#endif + + if (cause & CAUSEF_IP7) + do_IRQ(7, regs); @@ -15632,15 +14251,35 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/irq.c linux-2.6.12.5-brcm/arch/mips/b +{ + set_except_vector(0, bcm47xx_irq_handler); + mips_cpu_irq_init(0); -+ -+// printk("Breaking into debugger...\n"); -+// set_debug_traps(); -+// breakpoint(); -+} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/prom.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/prom.c ---- linux-2.6.12.5/arch/mips/bcm47xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/prom.c 2005-08-28 11:12:20.505847752 +0200 -@@ -0,0 +1,35 @@ ++} +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/prom.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c +--- linux-2.6.12.5/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c 2005-08-28 16:58:41.789656208 +0200 +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> @@ -15676,10 +14315,34 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/prom.c linux-2.6.12.5-brcm/arch/mips/ +{ + return 0; +} -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/setup.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/setup.c ---- linux-2.6.12.5/arch/mips/bcm47xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/setup.c 2005-08-28 11:12:20.506847600 +0200 -@@ -0,0 +1,111 @@ +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c +--- linux-2.6.12.5/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c 2005-08-28 16:57:28.317825624 +0200 +@@ -0,0 +1,127 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/tty.h> @@ -15696,11 +14359,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/setup.c linux-2.6.12.5-brcm/arch/mips +#include <sbconfig.h> +#include <bcmdevs.h> + -+// #include <ssbcore.h> -+ +#if 1 + -+//#define SER_PORT1(reg) (*((volatile unsigned char *)(0xbf800000+reg))) +#define SER_PORT1(reg) (*((volatile unsigned char *)(0xb8000400+reg))) + +int putDebugChar(char c) @@ -15731,8 +14391,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/setup.c linux-2.6.12.5-brcm/arch/mips + s.membase = regs; + s.irq = irq + 2; + s.uartclk = baud_base; -+ //s.baud_base = baud_base / 16; -+ //s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | UPF_RESOURCES | ASYNC_AUTO_IRQ; + s.flags = ASYNC_BOOT_AUTOCONF; + s.iotype = SERIAL_IO_MEM; + s.regshift = reg_shift; @@ -15769,11 +14427,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/setup.c linux-2.6.12.5-brcm/arch/mips + while (1); +} + -+//static struct sb_bus bus; -+ +static int __init bcm47xx_init(void) +{ -+// sb_bus_add(&bus, SB_BUS, (void *)SB_ENUM_BASE, SB_ENUM_LIM - SB_ENUM_BASE, "bcm47xx", NULL); + + sbh = sb_kattach(); + sb_mips_init(sbh); @@ -15791,10 +14446,34 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/setup.c linux-2.6.12.5-brcm/arch/mips +} + +early_initcall(bcm47xx_init); -diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/time.c linux-2.6.12.5-brcm/arch/mips/bcm47xx/time.c ---- linux-2.6.12.5/arch/mips/bcm47xx/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/arch/mips/bcm47xx/time.c 2005-08-28 11:12:20.506847600 +0200 -@@ -0,0 +1,74 @@ +diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/time.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c +--- linux-2.6.12.5/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c 2005-08-28 16:57:55.440702320 +0200 +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> @@ -15805,29 +14484,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/time.c linux-2.6.12.5-brcm/arch/mips/ +#include <asm/io.h> +#include <asm/time.h> + -+//#include <typedefs.h> -+//#include <bcmnvram.h> -+//#include <sbconfig.h> -+//#include <sbextif.h> -+//#include <sbutils.h> -+ -+/* Global SB handle */ -+//extern void *bcm947xx_sbh; -+//extern spinlock_t bcm947xx_sbh_lock; -+ -+/* Convenience */ -+//#define sbh bcm947xx_sbh -+//#define sbh_lock bcm947xx_sbh_lock -+ -+//extern int panic_timeout; -+//static int watchdog = 0; -+//static u8 *mcr = NULL; -+ +void __init +bcm47xx_time_init(void) +{ + unsigned int hz; -+// extifregs_t *eir; + + /* + * Use deterministic values for initial counter interrupt @@ -15836,31 +14496,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm47xx/time.c linux-2.6.12.5-brcm/arch/mips/ + write_c0_count(0); + write_c0_compare(0xffff); + -+// if (!(hz = sb_mips_clock(sbh))) -+// hz = 100000000; + hz = 200 * 1000 * 1000; + -+// printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh), -+// (hz + 500000) / 1000000); -+ + /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ + mips_hpt_frequency = hz / 2; + -+#if 0 -+ /* Set watchdog interval in ms */ -+ watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0); -+ -+ /* Set panic timeout in seconds */ -+ panic_timeout = watchdog / 1000; -+ panic_timeout *= 10; -+ -+ /* Setup blink */ -+ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { -+ sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); -+ unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1))); -+ mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1); -+ } -+#endif +} + +void __init @@ -15958,12 +14598,12 @@ diff -Nur linux-2.6.12.5/arch/mips/mm/tlbex.c linux-2.6.12.5-brcm/arch/mips/mm/t diff -Nur linux-2.6.12.5/arch/mips/pci/Makefile linux-2.6.12.5-brcm/arch/mips/pci/Makefile --- linux-2.6.12.5/arch/mips/pci/Makefile 2005-08-15 02:20:18.000000000 +0200 -+++ linux-2.6.12.5-brcm/arch/mips/pci/Makefile 2005-08-28 11:12:20.611831640 +0200 ++++ linux-2.6.12.5-brcm/arch/mips/pci/Makefile 2005-08-28 16:41:44.565297816 +0200 @@ -18,6 +18,7 @@ obj-$(CONFIG_MIPS_TX3927) += ops-jmr3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o -+obj-$(CONFIG_BCM47XX) += ops-sb.o fixup-bcm47xx.o pci-bcm47xx.o ++obj-$(CONFIG_BCM947XX) += ops-sb.o fixup-bcm47xx.o pci-bcm47xx.o # # These are still pretty much in the old state, watch, go blind. @@ -16122,16 +14762,16 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/pci.c linux-2.6.12.5-brcm/arch/mips/pci/p dev->resource[i].end += offset; diff -Nur linux-2.6.12.5/drivers/mtd/maps/Kconfig linux-2.6.12.5-brcm/drivers/mtd/maps/Kconfig --- linux-2.6.12.5/drivers/mtd/maps/Kconfig 2005-08-15 02:20:18.000000000 +0200 -+++ linux-2.6.12.5-brcm/drivers/mtd/maps/Kconfig 2005-08-28 11:12:20.663823736 +0200 ++++ linux-2.6.12.5-brcm/drivers/mtd/maps/Kconfig 2005-08-28 16:21:23.595930936 +0200 @@ -357,6 +357,12 @@ Mapping for the Flaga digital module. If you don't have one, ignore this setting. +config MTD_BCM47XX + tristate "BCM47xx flash device" -+ depends on MIPS && MTD_CFI && BCM47XX ++ depends on MIPS && MTD_CFI && BCM947XX + help -+ Support for the flash chips on the BCM47xx board. ++ Support for the flash chips on the BCM947xx board. + config MTD_BEECH tristate "CFI Flash device mapped on IBM 405LP Beech" @@ -16149,14 +14789,14 @@ diff -Nur linux-2.6.12.5/drivers/mtd/maps/Makefile linux-2.6.12.5-brcm/drivers/m obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o diff -Nur linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.12.5-brcm/drivers/mtd/maps/bcm47xx-flash.c --- linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.12.5-brcm/drivers/mtd/maps/bcm47xx-flash.c 2005-08-28 11:12:20.666823280 +0200 -@@ -0,0 +1,132 @@ ++++ linux-2.6.12.5-brcm/drivers/mtd/maps/bcm47xx-flash.c 2005-08-28 17:01:50.948899632 +0200 +@@ -0,0 +1,131 @@ +/* + * Flash mapping for BCM947XX boards + * + * Copyright (C) 2001 Broadcom Corporation + * -+ * $Id$ ++ * $Id: bcm47xx-flash.c,v 1.1 2004/10/21 07:18:31 jolt Exp $ + */ + +#include <linux/init.h> @@ -16169,7 +14809,6 @@ diff -Nur linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.12.5-brcm/dr +#include <linux/mtd/partitions.h> +#include <linux/config.h> + -+//#define WINDOW_ADDR 0x1fc00000 +#define WINDOW_ADDR 0x1c000000 +#define WINDOW_SIZE (0x400000*2) +#define BUSWIDTH 2 |