convert brcm-2.4 to the new target structure

SVN-Revision: 7092
This commit is contained in:
Felix Fietkau 2007-05-04 22:13:42 +00:00
parent 7d3baf4131
commit 833bb8f485
55 changed files with 16571 additions and 17096 deletions

View file

@ -0,0 +1,17 @@
#
# Makefile for the BCM947xx specific kernel interface routines
# under Linux.
#
EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
O_TARGET := bcm947xx.o
export-objs := export.o
obj-y := prom.o setup.o time.o sbmips.o gpio.o
obj-y += nvram.o nvram_linux.o sflash.o
obj-y += sbutils.o bcmutils.o bcmsrom.o hndchipc.o
obj-$(CONFIG_PCI) += sbpci.o pcibios.o
obj-y += export.o
include $(TOPDIR)/Rules.make

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,247 @@
/*
* Misc useful OS-independent routines.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
* $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <stdarg.h>
#include <bcmutils.h>
#include <osl.h>
#include <sbutils.h>
#include <bcmnvram.h>
#include <bcmendian.h>
#include <bcmdevs.h>
unsigned char bcm_ctype[] = {
_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */
_BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C,
_BCM_C, /* 8-15 */
_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */
_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */
_BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */
_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */
_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */
_BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */
_BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
_BCM_U|_BCM_X, _BCM_U, /* 64-71 */
_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */
_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */
_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
_BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
_BCM_L|_BCM_X, _BCM_L, /* 96-103 */
_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
_BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */
_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */
_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */
_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */
_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */
_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
};
ulong
bcm_strtoul(char *cp, char **endp, uint base)
{
ulong result, value;
bool minus;
minus = FALSE;
while (bcm_isspace(*cp))
cp++;
if (cp[0] == '+')
cp++;
else if (cp[0] == '-') {
minus = TRUE;
cp++;
}
if (base == 0) {
if (cp[0] == '0') {
if ((cp[1] == 'x') || (cp[1] == 'X')) {
base = 16;
cp = &cp[2];
} else {
base = 8;
cp = &cp[1];
}
} else
base = 10;
} else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
cp = &cp[2];
}
result = 0;
while (bcm_isxdigit(*cp) &&
(value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
result = result*base + value;
cp++;
}
if (minus)
result = (ulong)(result * -1);
if (endp)
*endp = (char *)cp;
return (result);
}
uchar
bcm_toupper(uchar c)
{
if (bcm_islower(c))
c -= 'a'-'A';
return (c);
}
char*
bcm_ether_ntoa(struct ether_addr *ea, char *buf)
{
sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff,
ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff);
return (buf);
}
/*
* Search the name=value vars for a specific one and return its value.
* Returns NULL if not found.
*/
char*
getvar(char *vars, char *name)
{
char *s;
int len;
len = strlen(name);
/* first look in vars[] */
for (s = vars; s && *s;) {
/* CSTYLED */
if ((memcmp(s, name, len) == 0) && (s[len] == '='))
return (&s[len+1]);
while (*s++)
;
}
/* then query nvram */
return (nvram_get(name));
}
/*
* Search the vars for a specific one and return its value as
* an integer. Returns 0 if not found.
*/
int
getintvar(char *vars, char *name)
{
char *val;
if ((val = getvar(vars, name)) == NULL)
return (0);
return (bcm_strtoul(val, NULL, 0));
}
/*******************************************************************************
* crc8
*
* Computes a crc8 over the input data using the polynomial:
*
* x^8 + x^7 +x^6 + x^4 + x^2 + 1
*
* The caller provides the initial value (either CRC8_INIT_VALUE
* or the previous returned value) to allow for processing of
* discontiguous blocks of data. When generating the CRC the
* caller is responsible for complementing the final return value
* and inserting it into the byte stream. When checking, a final
* return value of CRC8_GOOD_VALUE indicates a valid CRC.
*
* Reference: Dallas Semiconductor Application Note 27
* Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
* ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
* ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
*
* ****************************************************************************
*/
static uint8 crc8_table[256] = {
0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
};
#define CRC_INNER_LOOP(n, c, x) \
(c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
uint8
hndcrc8(
uint8 *pdata, /* pointer to array of data to process */
uint nbytes, /* number of input data bytes to process */
uint8 crc /* either CRC8_INIT_VALUE or previous return value */
)
{
/* hard code the crc loop instead of using CRC_INNER_LOOP macro
* to avoid the undefined and unnecessary (uint8 >> 8) operation.
*/
while (nbytes-- > 0)
crc = crc8_table[(crc ^ *pdata++) & 0xff];
return crc;
}

View file

@ -0,0 +1,33 @@
#
# Makefile for Broadcom BCM947XX boards
#
# Copyright 2001-2003, Broadcom Corporation
# All Rights Reserved.
#
# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
#
# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $
#
OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
SYSTEM ?= $(TOPDIR)/vmlinux
all: vmlinuz
# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
# Create a gzipped version named vmlinuz for compatibility
vmlinuz: piggy
gzip -c9 $< > $@
piggy: $(SYSTEM)
$(OBJCOPY) $(OBJCOPY_ARGS) $< $@
mrproper: clean
clean:
rm -f vmlinuz piggy

View file

@ -0,0 +1,71 @@
#include <linux/module.h>
#define _export(n) \
void n(void); \
EXPORT_SYMBOL(n);
_export(bcm947xx_sbh)
_export(sb_attach)
_export(sb_kattach)
_export(sb_boardtype)
_export(sb_boardvendor)
_export(sb_btcgpiowar)
_export(sb_bus)
_export(sb_chip)
_export(sb_chiprev)
_export(sb_chipcrev)
_export(sb_chippkg)
_export(sb_clkctl_clk)
_export(sb_clkctl_fast_pwrup_delay)
_export(sb_clkctl_init)
_export(sb_clkctl_xtal)
_export(sb_core_disable)
_export(sb_core_reset)
_export(sb_core_tofixup)
_export(sb_coreflags)
_export(sb_coreflagshi)
_export(sb_coreidx)
_export(sb_coreregs)
_export(sb_corerev)
_export(sb_coreunit)
_export(sb_detach)
_export(sb_deviceremoved)
_export(sb_gpiosetcore)
_export(sb_gpiocontrol)
_export(sb_gpiointmask)
_export(sb_gpiointpolarity)
_export(sb_gpioled)
_export(sb_gpioin)
_export(sb_gpioout)
_export(sb_gpioouten)
_export(sb_gpiotimerval)
_export(sb_irq)
_export(sb_iscoreup)
_export(sb_pci_setup)
_export(sb_pcirev)
_export(sb_pcmcia_init)
_export(sb_pcmciarev)
_export(sb_register_intr_callback)
_export(sb_setcore)
_export(sb_setcoreidx)
_export(sb_war16165)
_export(sb_war32414_forceHT)
_export(sb_osh)
_export(getvar)
_export(getintvar)
_export(bcm_strtoul)
_export(bcm_ctype)
_export(bcm_toupper)
_export(bcm_ether_ntoa)
_export(nvram_get)
_export(nvram_getall)
_export(nvram_set)
_export(nvram_unset)
_export(nvram_commit)
_export(srom_read)
_export(srom_write)

View file

@ -0,0 +1,12 @@
#
# Makefile for the BCM947xx specific kernel interface routines
# under Linux.
#
EXTRA_CFLAGS += -fno-delayed-branch
USE_STANDARD_AS_RULE := true
O_TARGET := brcm.o
obj-y := int-handler.o irq.o
include $(TOPDIR)/Rules.make

View file

@ -0,0 +1,51 @@
/*
* Generic interrupt handler for Broadcom MIPS boards
*
* Copyright 2004, 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: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $
*/
#include <linux/config.h>
#include <asm/asm.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
/*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 Combined hardware interrupt (hw0)
* 3 Hardware
* 4 Hardware
* 5 Hardware
* 6 Hardware
* 7 R4k timer
*/
.text
.set noreorder
.set noat
.align 5
NESTED(brcmIRQ, PT_SIZE, sp)
SAVE_ALL
CLI
.set at
.set noreorder
jal brcm_irq_dispatch
move a0, sp
j ret_from_irq
nop
END(brcmIRQ)

View file

@ -0,0 +1,130 @@
/*
* Generic interrupt control functions for Broadcom MIPS boards
*
* Copyright 2004, 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: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/gdb-stub.h>
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
extern asmlinkage void brcmIRQ(void);
extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
void
brcm_irq_dispatch(struct pt_regs *regs)
{
u32 cause;
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);
if (cause & CAUSEF_IP2)
do_IRQ(2, regs);
if (cause & CAUSEF_IP3)
do_IRQ(3, regs);
if (cause & CAUSEF_IP4)
do_IRQ(4, regs);
if (cause & CAUSEF_IP5)
do_IRQ(5, regs);
if (cause & CAUSEF_IP6)
do_IRQ(6, regs);
}
static void
enable_brcm_irq(unsigned int irq)
{
if (irq < 8)
set_c0_status(1 << (irq + 8));
else
set_c0_status(IE_IRQ0);
}
static void
disable_brcm_irq(unsigned int irq)
{
if (irq < 8)
clear_c0_status(1 << (irq + 8));
else
clear_c0_status(IE_IRQ0);
}
static void
ack_brcm_irq(unsigned int irq)
{
/* Already done in brcm_irq_dispatch */
}
static unsigned int
startup_brcm_irq(unsigned int irq)
{
enable_brcm_irq(irq);
return 0; /* never anything pending */
}
static void
end_brcm_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_brcm_irq(irq);
}
static struct hw_interrupt_type brcm_irq_type = {
typename: "MIPS",
startup: startup_brcm_irq,
shutdown: disable_brcm_irq,
enable: enable_brcm_irq,
disable: disable_brcm_irq,
ack: ack_brcm_irq,
end: end_brcm_irq,
NULL
};
void __init
init_IRQ(void)
{
int i;
for (i = 0; i < NR_IRQS; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = 0;
irq_desc[i].depth = 1;
irq_desc[i].handler = &brcm_irq_type;
}
set_except_vector(0, brcmIRQ);
change_c0_status(ST0_IM, ALLINTS);
#ifdef CONFIG_REMOTE_DEBUG
printk("Breaking into debugger...\n");
set_debug_traps();
breakpoint();
#endif
}

View file

@ -0,0 +1,159 @@
/*
* GPIO char driver
*
* Copyright 2005, 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/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <typedefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
static sb_t *gpio_sbh;
static int gpio_major;
static devfs_handle_t gpio_dir;
static struct {
char *name;
devfs_handle_t handle;
} gpio_file[] = {
{ "in", NULL },
{ "out", NULL },
{ "outen", NULL },
{ "control", NULL }
};
static int
gpio_open(struct inode *inode, struct file * file)
{
if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
return -ENODEV;
MOD_INC_USE_COUNT;
return 0;
}
static int
gpio_release(struct inode *inode, struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t
gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
u32 val;
switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
case 0:
val = sb_gpioin(gpio_sbh);
break;
case 1:
val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
break;
case 2:
val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
break;
case 3:
val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
break;
default:
return -ENODEV;
}
if (put_user(val, (u32 *) buf))
return -EFAULT;
return sizeof(val);
}
static ssize_t
gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
u32 val;
if (get_user(val, (u32 *) buf))
return -EFAULT;
switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
case 0:
return -EACCES;
case 1:
sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
break;
case 2:
sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
break;
case 3:
sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
break;
default:
return -ENODEV;
}
return sizeof(val);
}
static struct file_operations gpio_fops = {
owner: THIS_MODULE,
open: gpio_open,
release: gpio_release,
read: gpio_read,
write: gpio_write,
};
static int __init
gpio_init(void)
{
int i;
if (!(gpio_sbh = sb_kattach()))
return -ENODEV;
sb_gpiosetcore(gpio_sbh);
if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0)
return gpio_major;
gpio_dir = devfs_mk_dir(NULL, "gpio", NULL);
for (i = 0; i < ARRAYSIZE(gpio_file); i++) {
gpio_file[i].handle = devfs_register(gpio_dir,
gpio_file[i].name,
DEVFS_FL_DEFAULT, gpio_major, i,
S_IFCHR | S_IRUGO | S_IWUGO,
&gpio_fops, NULL);
}
return 0;
}
static void __exit
gpio_exit(void)
{
int i;
for (i = 0; i < ARRAYSIZE(gpio_file); i++)
devfs_unregister(gpio_file[i].handle);
devfs_unregister(gpio_dir);
devfs_unregister_chrdev(gpio_major, "gpio");
sb_detach(gpio_sbh);
}
module_init(gpio_init);
module_exit(gpio_exit);

View file

@ -0,0 +1,158 @@
/*
* BCM47XX support code for some chipcommon (old extif) facilities (uart)
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: hndchipc.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
*/
#include <typedefs.h>
#include <bcmdefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
#include <bcmnvram.h>
#include <sbconfig.h>
#include <sbextif.h>
#include <sbchipc.h>
#include <hndcpu.h>
/*
* Returns TRUE if an external UART exists at the given base
* register.
*/
static bool
BCMINITFN(serial_exists)(osl_t *osh, uint8 *regs)
{
uint8 save_mcr, status1;
save_mcr = R_REG(osh, &regs[UART_MCR]);
W_REG(osh, &regs[UART_MCR], UART_MCR_LOOP | 0x0a);
status1 = R_REG(osh, &regs[UART_MSR]) & 0xf0;
W_REG(osh, &regs[UART_MCR], save_mcr);
return (status1 == 0x90);
}
/*
* Initializes UART access. The callback function will be called once
* per found UART.
*/
void
BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base,
uint reg_shift))
{
osl_t *osh;
void *regs;
ulong base;
uint irq;
int i, n;
osh = sb_osh(sbh);
if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) {
extifregs_t *eir = (extifregs_t *) regs;
sbconfig_t *sb;
/* Determine external UART register base */
sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
base = EXTIF_CFGIF_BASE(sb_base(R_REG(osh, &sb->sbadmatch1)));
/* Determine IRQ */
irq = sb_irq(sbh);
/* Disable GPIO interrupt initially */
W_REG(osh, &eir->gpiointpolarity, 0);
W_REG(osh, &eir->gpiointmask, 0);
/* Search for external UARTs */
n = 2;
for (i = 0; i < 2; i++) {
regs = (void *) REG_MAP(base + (i * 8), 8);
if (serial_exists(osh, regs)) {
/* Set GPIO 1 to be the external UART IRQ */
W_REG(osh, &eir->gpiointmask, 2);
/* XXXDetermine external UART clock */
if (add)
add(regs, irq, 13500000, 0);
}
}
/* Add internal UART if enabled */
if (R_REG(osh, &eir->corecontrol) & CC_UE)
if (add)
add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
} else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
chipcregs_t *cc = (chipcregs_t *) regs;
uint32 rev, cap, pll, baud_base, div;
/* Determine core revision and capabilities */
rev = sb_corerev(sbh);
cap = R_REG(osh, &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(osh, &cc->clockcontrol_n),
R_REG(osh, &cc->clockcontrol_m2));
div = 1;
} else {
/* Fixed ALP clock */
if (rev >= 11 && rev != 15) {
baud_base = 20000000;
div = 1;
/* Set the override bit so we don't divide it */
W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
}
/* Internal backplane clock */
else if (rev >= 3) {
baud_base = sb_clock(sbh);
div = 2; /* Minimum divisor */
W_REG(osh, &cc->clkdiv,
((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
}
/* Fixed internal backplane clock */
else {
baud_base = 88000000;
div = 48;
}
/* Clock source depends on strapping if UartClkOverride is unset */
if ((rev > 0) &&
((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
/* Internal divided backplane clock */
baud_base /= div;
} else {
/* Assume external clock of 1.8432 MHz */
baud_base = 1843200;
}
}
}
/* 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);
}
}
}

View file

@ -0,0 +1,91 @@
/*
* BCM4710 address space map and definitions
* Think twice before adding to this file, this is not the kitchen sink
* These definitions are not guaranteed for all 47xx chips, only the 4710
*
* Copyright 2004, 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: bcm4710.h,v 1.3 2004/09/27 07:23:30 tallest Exp $
*/
#ifndef _bcm4710_h_
#define _bcm4710_h_
/* Address map */
#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
/* Core register space */
#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
#define BCM4710_REG_USB 0x18004000 /* USB core registers */
#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */
#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */
#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */
#define BCM4710_PROG 0x1f800000 /* Programable interface */
#define BCM4710_FLASH 0x1fc00000 /* Flash */
#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
#define SBFLAG_PCI 0
#define SBFLAG_ENET0 1
#define SBFLAG_ILINE20 2
#define SBFLAG_CODEC 3
#define SBFLAG_USB 4
#define SBFLAG_EXTIF 5
#define SBFLAG_ENET1 6
#ifdef CONFIG_HWSIM
#define BCM4710_TRACE(trval) do { *((int *)0xa0000f18) = (trval); } while (0)
#else
#define BCM4710_TRACE(trval)
#endif
/* BCM94702 CPCI -ExtIF used for LocalBus devs */
#define BCM94702_CPCI_RESET_ADDR BCM4710_EXTIF
#define BCM94702_CPCI_BOARDID_ADDR (BCM4710_EXTIF | 0x4000)
#define BCM94702_CPCI_DOC_ADDR (BCM4710_EXTIF | 0x6000)
#define BCM94702_DOC_ADDR BCM94702_CPCI_DOC_ADDR
#define BCM94702_CPCI_LED_ADDR (BCM4710_EXTIF | 0xc000)
#define BCM94702_CPCI_NVRAM_ADDR (BCM4710_EXTIF | 0xe000)
#define BCM94702_CPCI_NVRAM_SIZE 0x1ff0 /* 8K NVRAM : DS1743/STM48txx*/
#define BCM94702_CPCI_TOD_REG_BASE (BCM94702_CPCI_NVRAM_ADDR | 0x1ff0)
#define LED_REG(x) \
(*(volatile unsigned char *) (KSEG1ADDR(BCM94702_CPCI_LED_ADDR) + (x)))
/*
* Reset function implemented in PLD. Read or write should trigger hard reset
*/
#define SYS_HARD_RESET() \
{ for (;;) \
*( (volatile unsigned char *)\
KSEG1ADDR(BCM94702_CPCI_RESET_ADDR) ) = 0x80; \
}
#endif /* _bcm4710_h_ */

View file

@ -0,0 +1,106 @@
/*
* Misc system wide definitions
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
* $Id: bcmdefs.h,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $
*/
#ifndef _bcmdefs_h_
#define _bcmdefs_h_
/*
* One doesn't need to include this file explicitly, gets included automatically if
* typedefs.h is included.
*/
/* Reclaiming text and data :
* The following macros specify special linker sections that can be reclaimed
* after a system is considered 'up'.
*/
#if defined(__GNUC__) && defined(BCMRECLAIM)
extern bool bcmreclaimed;
#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data
#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn
#else /* #if defined(__GNUC__) && defined(BCMRECLAIM) */
#define BCMINITDATA(_data) _data
#define BCMINITFN(_fn) _fn
#define bcmreclaimed 0
#endif /* #if defined(__GNUC__) && defined(BCMRECLAIM) */
/* Reclaim uninit functions if BCMNODOWN is defined */
/* and if they are not already removed by -gc-sections */
#ifdef BCMNODOWN
#define BCMUNINITFN(_fn) BCMINITFN(_fn)
#else
#define BCMUNINITFN(_fn) _fn
#endif
#ifdef BCMRECLAIM
#define CONST
#else
#define CONST const
#endif /* BCMRECLAIM */
/* Compatibility with old-style BCMRECLAIM */
#define BCMINIT(_id) _id
/* Put some library data/code into ROM to reduce RAM requirements */
#if defined(__GNUC__) && defined(BCMROMOFFLOAD)
#define BCMROMDATA(_data) __attribute__ ((__section__ (".datarom." #_data))) _data
#define BCMROMFN(_fn) __attribute__ ((__section__ (".textrom." #_fn))) _fn
#else
#define BCMROMDATA(_data) _data
#define BCMROMFN(_fn) _fn
#endif
/* Bus types */
#define SB_BUS 0 /* Silicon Backplane */
#define PCI_BUS 1 /* PCI target */
#define PCMCIA_BUS 2 /* PCMCIA target */
#define SDIO_BUS 3 /* SDIO target */
#define JTAG_BUS 4 /* JTAG */
#define NO_BUS 0xFF /* Bus that does not support R/W REG */
/* Allows optimization for single-bus support */
#ifdef BCMBUSTYPE
#define BUSTYPE(bus) (BCMBUSTYPE)
#else
#define BUSTYPE(bus) (bus)
#endif
/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */
#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */
#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */
#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
/* packet headroom necessary to accomodate the largest header in the system, (i.e TXOFF).
* By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
* There is a compile time check in wlc.c which ensure that this value is at least as big
* as TXOFF. This value is used in dma_rxfill (hnddma.c).
*/
#define BCMEXTRAHDROOM 160
/* Headroom required for dongle-to-host communication. Packets allocated
* locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
* leave this much room in front for low-level message headers which may
* be needed to get across the dongle bus to the host. (These messages
* don't go over the network, so room for the full WL header above would
* be a waste.)
*/
#define BCMDONGLEHDRSZ 8
#endif /* _bcmdefs_h_ */

View file

@ -0,0 +1,369 @@
/*
* Broadcom device-specific manifest constants.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
* $Id: bcmdevs.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $
*/
#ifndef _BCMDEVS_H
#define _BCMDEVS_H
#include "bcm4710.h"
/* Known PCI vendor Id's */
#define VENDOR_EPIGRAM 0xfeda
#define VENDOR_BROADCOM 0x14e4
#define VENDOR_3COM 0x10b7
#define VENDOR_NETGEAR 0x1385
#define VENDOR_DIAMOND 0x1092
#define VENDOR_DELL 0x1028
#define VENDOR_HP 0x0e11
#define VENDOR_APPLE 0x106b
/* PCI Device Id's */
#define BCM4210_DEVICE_ID 0x1072 /* never used */
#define BCM4211_DEVICE_ID 0x4211
#define BCM4230_DEVICE_ID 0x1086 /* never used */
#define BCM4231_DEVICE_ID 0x4231
#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
#define BCM47XX_USB_ID 0x4715 /* 47xx usb */
#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */
#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */
#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */
#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */
#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */
#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid returned by sb_chip() */
#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */
#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */
#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
#define BCM4306_D11G_ID2 0x4325
#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
#define BCM4306_UART_ID 0x4322 /* 4306 uart */
#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
#define BCM4309_PKG_ID 1 /* 4309 package id */
#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */
#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */
#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */
#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */
#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
#define BCM4303_PKG_ID 2 /* 4303 package id */
#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */
#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
#define BCM4318_CHIP_ID 0x4318 /* 4318 chip common chipid */
#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */
#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */
#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */
#define BCM4321_CHIP_ID 0x4321 /* 4321 chip common chipid */
#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */
#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Hgz band id */
#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */
#define BCM4331_CHIP_ID 0x4331 /* 4331 chip common chipid */
#define BCM4331_D11N2G_ID 0x4330 /* 4331 802.11n 2.4Ghz band id */
#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */
#define BCM4331_D11N5G_ID 0x4332 /* 4331 802.11n 5Ghz band id */
#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */
#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */
#define BCM5350_CHIP_ID 0x5350 /* bcm5350 chipcommon chipid */
#define BCM5352_CHIP_ID 0x5352 /* bcm5352 chipcommon chipid */
#define BCM4320_CHIP_ID 0x4320 /* bcm4320 chipcommon chipid */
#define BCM4328_CHIP_ID 0x4328 /* bcm4328 chipcommon chipid */
#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */
#define BCM43XX_JTAGM_ID 0x43f1 /* 43xx jtagm device id */
#define BCM43XXOLD_JTAGM_ID 0x4331 /* 43xx old jtagm device id */
#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */
#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */
#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */
#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */
/* PCMCIA vendor Id's */
#define VENDOR_BROADCOM_PCMCIA 0x02d0
/* SDIO vendor Id's */
#define VENDOR_BROADCOM_SDIO 0x00BF
/* boardflags */
#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */
#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */
#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
#define BFL_FEM 0x0800 /* This board supports the Front End Module */
#define BFL_EXTLNA 0x1000 /* This board has an external LNA */
#define BFL_HGPA 0x2000 /* This board has a high gain PA */
#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */
#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */
/* boardflags2 */
#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* This board has an external rxbb regulator */
#define BFL2_SSWITCH_AVAIL 0x00000002 /* This board has a superswitch for > 2 antennas */
#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits TX Power Control to be enabled */
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */
#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */
#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
/* power control defines */
#define PLL_DELAY 150 /* us pll on delay */
#define FREF_DELAY 200 /* us fref change delay */
#define MIN_SLOW_CLK 32 /* us Slow clock period */
#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
/* Reference Board Types */
#define BU4710_BOARD 0x0400
#define VSIM4710_BOARD 0x0401
#define QT4710_BOARD 0x0402
#define BU4309_BOARD 0x040a
#define BCM94309CB_BOARD 0x040b
#define BCM94309MP_BOARD 0x040c
#define BCM4309AP_BOARD 0x040d
#define BCM94302MP_BOARD 0x040e
#define BU4306_BOARD 0x0416
#define BCM94306CB_BOARD 0x0417
#define BCM94306MP_BOARD 0x0418
#define BCM94710D_BOARD 0x041a
#define BCM94710R1_BOARD 0x041b
#define BCM94710R4_BOARD 0x041c
#define BCM94710AP_BOARD 0x041d
#define BU2050_BOARD 0x041f
#define BCM94309G_BOARD 0x0421
#define BU4704_BOARD 0x0423
#define BU4702_BOARD 0x0424
#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */
#define BCM94702MN_BOARD 0x0428
/* BCM4702 1U CompactPCI Board */
#define BCM94702CPCI_BOARD 0x0429
/* BCM4702 with BCM95380 VLAN Router */
#define BCM95380RR_BOARD 0x042a
/* cb4306 with SiGe PA */
#define BCM94306CBSG_BOARD 0x042b
/* cb4306 with SiGe PA */
#define PCSG94306_BOARD 0x042d
/* bu4704 with sdram */
#define BU4704SD_BOARD 0x042e
/* Dual 11a/11g Router */
#define BCM94704AGR_BOARD 0x042f
/* 11a-only minipci */
#define BCM94308MP_BOARD 0x0430
#define BU4712_BOARD 0x0444
#define BU4712SD_BOARD 0x045d
#define BU4712L_BOARD 0x045f
/* BCM4712 boards */
#define BCM94712AP_BOARD 0x0445
#define BCM94712P_BOARD 0x0446
/* BCM4318 boards */
#define BU4318_BOARD 0x0447
#define CB4318_BOARD 0x0448
#define MPG4318_BOARD 0x0449
#define MP4318_BOARD 0x044a
#define SD4318_BOARD 0x044b
/* BCM63XX boards */
#define BCM96338_BOARD 0x6338
#define BCM96348_BOARD 0x6348
/* Another mp4306 with SiGe */
#define BCM94306P_BOARD 0x044c
/* mp4303 */
#define BCM94303MP_BOARD 0x044e
/* mpsgh4306 */
#define BCM94306MPSGH_BOARD 0x044f
/* BRCM 4306 w/ Front End Modules */
#define BCM94306MPM 0x0450
#define BCM94306MPL 0x0453
/* 4712agr */
#define BCM94712AGR_BOARD 0x0451
/* pcmcia 4303 */
#define PC4303_BOARD 0x0454
/* 5350K */
#define BCM95350K_BOARD 0x0455
/* 5350R */
#define BCM95350R_BOARD 0x0456
/* 4306mplna */
#define BCM94306MPLNA_BOARD 0x0457
/* 4320 boards */
#define BU4320_BOARD 0x0458
#define BU4320S_BOARD 0x0459
#define BCM94320PH_BOARD 0x045a
/* 4306mph */
#define BCM94306MPH_BOARD 0x045b
/* 4306pciv */
#define BCM94306PCIV_BOARD 0x045c
#define BU4712SD_BOARD 0x045d
#define BCM94320PFLSH_BOARD 0x045e
#define BU4712L_BOARD 0x045f
#define BCM94712LGR_BOARD 0x0460
#define BCM94320R_BOARD 0x0461
#define BU5352_BOARD 0x0462
#define BCM94318MPGH_BOARD 0x0463
#define BU4311_BOARD 0x0464
#define BCM94311MC_BOARD 0x0465
#define BCM94311MCAG_BOARD 0x0466
#define BCM95352GR_BOARD 0x0467
/* bcm95351agr */
#define BCM95351AGR_BOARD 0x0470
/* bcm94704mpcb */
#define BCM94704MPCB_BOARD 0x0472
/* 4785 boards */
#define BU4785_BOARD 0x0478
/* 4321 boards */
#define BU4321_BOARD 0x046b
#define BU4321E_BOARD 0x047c
#define MP4321_BOARD 0x046c
#define CB2_4321_BOARD 0x046d
#define MC4321_BOARD 0x046e
/* # of GPIO pins */
#define GPIO_NUMPINS 16
/* radio ID codes */
#define NORADIO_ID 0xe4f5
#define NORADIO_IDCODE 0x4e4f5246
#define BCM2050_ID 0x2050
#define BCM2050_IDCODE 0x02050000
#define BCM2050A0_IDCODE 0x1205017f
#define BCM2050A1_IDCODE 0x2205017f
#define BCM2050R8_IDCODE 0x8205017f
#define BCM2055_ID 0x2055
#define BCM2055_IDCODE 0x02055000
#define BCM2055A0_IDCODE 0x1205517f
#define BCM2060_ID 0x2060
#define BCM2060_IDCODE 0x02060000
#define BCM2060WW_IDCODE 0x1206017f
#define BCM2062_ID 0x2062
#define BCM2062_IDCODE 0x02062000
#define BCM2062A0_IDCODE 0x0206217f
/* parts of an idcode: */
#define IDCODE_MFG_MASK 0x00000fff
#define IDCODE_MFG_SHIFT 0
#define IDCODE_ID_MASK 0x0ffff000
#define IDCODE_ID_SHIFT 12
#define IDCODE_REV_MASK 0xf0000000
#define IDCODE_REV_SHIFT 28
#endif /* _BCMDEVS_H */

View file

@ -0,0 +1,391 @@
/*
* Broadcom device-specific manifest constants.
*
* Copyright 2005, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
* $Id$
*/
#ifndef _BCMDEVS_H
#define _BCMDEVS_H
/* Known PCI vendor Id's */
#define VENDOR_EPIGRAM 0xfeda
#define VENDOR_BROADCOM 0x14e4
#define VENDOR_3COM 0x10b7
#define VENDOR_NETGEAR 0x1385
#define VENDOR_DIAMOND 0x1092
#define VENDOR_DELL 0x1028
#define VENDOR_HP 0x0e11
#define VENDOR_APPLE 0x106b
/* PCI Device Id's */
#define BCM4210_DEVICE_ID 0x1072 /* never used */
#define BCM4211_DEVICE_ID 0x4211
#define BCM4230_DEVICE_ID 0x1086 /* never used */
#define BCM4231_DEVICE_ID 0x4231
#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
#define BCM47XX_USB_ID 0x4715 /* 47xx usb */
#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */
#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */
#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */
#define BCM4610_ENET_ID 0x4613 /* 4610 enet */
#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */
#define BCM4610_USB_ID 0x4615 /* 4610 usb */
#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */
#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */
#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */
#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */
#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */
#define BCM4307_ENET_ID 0x4306 /* 4307 enet */
#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */
#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */
#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
#define BCM4306_D11G_ID2 0x4325
#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
#define BCM4306_UART_ID 0x4322 /* 4306 uart */
#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
#define BCM4309_PKG_ID 1 /* 4309 package id */
#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
#define BCM4303_PKG_ID 2 /* 4303 package id */
#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */
#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */
#define BCM4310_UART_ID 0x4312 /* 4310 uart */
#define BCM4310_ENET_ID 0x4313 /* 4310 enet */
#define BCM4310_USB_ID 0x4315 /* 4310 usb */
#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */
#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */
#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */
#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */
#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */
#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */
#define FPGA_JTAGM_ID 0x4330 /* ??? */
/* Address map */
#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
/* Core register space */
#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
#define BCM4710_REG_USB 0x18004000 /* USB core registers */
#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */
#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */
#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */
#define BCM4710_PROG 0x1f800000 /* Programable interface */
#define BCM4710_FLASH 0x1fc00000 /* Flash */
#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */
#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */
#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */
#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */
#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */
#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */
/* PCMCIA vendor Id's */
#define VENDOR_BROADCOM_PCMCIA 0x02d0
/* SDIO vendor Id's */
#define VENDOR_BROADCOM_SDIO 0x00BF
/* boardflags */
#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */
#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */
#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
#define BFL_FEM 0x0800 /* This board supports the Front End Module */
#define BFL_EXTLNA 0x1000 /* This board has an external LNA */
#define BFL_HGPA 0x2000 /* This board has a high gain PA */
#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */
#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */
#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */
#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */
#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
/* Bus types */
#define SB_BUS 0 /* Silicon Backplane */
#define PCI_BUS 1 /* PCI target */
#define PCMCIA_BUS 2 /* PCMCIA target */
#define SDIO_BUS 3 /* SDIO target */
#define JTAG_BUS 4 /* JTAG */
/* Allows optimization for single-bus support */
#ifdef BCMBUSTYPE
#define BUSTYPE(bus) (BCMBUSTYPE)
#else
#define BUSTYPE(bus) (bus)
#endif
/* power control defines */
#define PLL_DELAY 150 /* us pll on delay */
#define FREF_DELAY 200 /* us fref change delay */
#define MIN_SLOW_CLK 32 /* us Slow clock period */
#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
/* Reference Board Types */
#define BU4710_BOARD 0x0400
#define VSIM4710_BOARD 0x0401
#define QT4710_BOARD 0x0402
#define BU4610_BOARD 0x0403
#define VSIM4610_BOARD 0x0404
#define BU4307_BOARD 0x0405
#define BCM94301CB_BOARD 0x0406
#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */
#define BCM94301MP_BOARD 0x0407
#define BCM94307MP_BOARD 0x0408
#define BCMAP4307_BOARD 0x0409
#define BU4309_BOARD 0x040a
#define BCM94309CB_BOARD 0x040b
#define BCM94309MP_BOARD 0x040c
#define BCM4309AP_BOARD 0x040d
#define BCM94302MP_BOARD 0x040e
#define VSIM4310_BOARD 0x040f
#define BU4711_BOARD 0x0410
#define BCM94310U_BOARD 0x0411
#define BCM94310AP_BOARD 0x0412
#define BCM94310MP_BOARD 0x0414
#define BU4306_BOARD 0x0416
#define BCM94306CB_BOARD 0x0417
#define BCM94306MP_BOARD 0x0418
#define BCM94710D_BOARD 0x041a
#define BCM94710R1_BOARD 0x041b
#define BCM94710R4_BOARD 0x041c
#define BCM94710AP_BOARD 0x041d
#define BU2050_BOARD 0x041f
#define BCM94309G_BOARD 0x0421
#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */
#define BU4704_BOARD 0x0423
#define BU4702_BOARD 0x0424
#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */
#define BU4317_BOARD 0x0426
#define BCM94702MN_BOARD 0x0428
/* BCM4702 1U CompactPCI Board */
#define BCM94702CPCI_BOARD 0x0429
/* BCM4702 with BCM95380 VLAN Router */
#define BCM95380RR_BOARD 0x042a
/* cb4306 with SiGe PA */
#define BCM94306CBSG_BOARD 0x042b
/* mp4301 with 2050 radio */
#define BCM94301MPL_BOARD 0x042c
/* cb4306 with SiGe PA */
#define PCSG94306_BOARD 0x042d
/* bu4704 with sdram */
#define BU4704SD_BOARD 0x042e
/* Dual 11a/11g Router */
#define BCM94704AGR_BOARD 0x042f
/* 11a-only minipci */
#define BCM94308MP_BOARD 0x0430
/* BCM94317 boards */
#define BCM94317CB_BOARD 0x0440
#define BCM94317MP_BOARD 0x0441
#define BCM94317PCMCIA_BOARD 0x0442
#define BCM94317SDIO_BOARD 0x0443
#define BU4712_BOARD 0x0444
#define BU4712SD_BOARD 0x045d
#define BU4712L_BOARD 0x045f
/* BCM4712 boards */
#define BCM94712AP_BOARD 0x0445
#define BCM94712P_BOARD 0x0446
/* BCM4318 boards */
#define BU4318_BOARD 0x0447
#define CB4318_BOARD 0x0448
#define MPG4318_BOARD 0x0449
#define MP4318_BOARD 0x044a
#define SD4318_BOARD 0x044b
/* BCM63XX boards */
#define BCM96338_BOARD 0x6338
#define BCM96345_BOARD 0x6345
#define BCM96348_BOARD 0x6348
/* Another mp4306 with SiGe */
#define BCM94306P_BOARD 0x044c
/* CF-like 4317 modules */
#define BCM94317CF_BOARD 0x044d
/* mp4303 */
#define BCM94303MP_BOARD 0x044e
/* mpsgh4306 */
#define BCM94306MPSGH_BOARD 0x044f
/* BRCM 4306 w/ Front End Modules */
#define BCM94306MPM 0x0450
#define BCM94306MPL 0x0453
/* 4712agr */
#define BCM94712AGR_BOARD 0x0451
/* The real CF 4317 board */
#define CFI4317_BOARD 0x0452
/* pcmcia 4303 */
#define PC4303_BOARD 0x0454
/* 5350K */
#define BCM95350K_BOARD 0x0455
/* 5350R */
#define BCM95350R_BOARD 0x0456
/* 4306mplna */
#define BCM94306MPLNA_BOARD 0x0457
/* 4320 boards */
#define BU4320_BOARD 0x0458
#define BU4320S_BOARD 0x0459
#define BCM94320PH_BOARD 0x045a
/* 4306mph */
#define BCM94306MPH_BOARD 0x045b
/* 4306pciv */
#define BCM94306PCIV_BOARD 0x045c
#define BU4712SD_BOARD 0x045d
#define BCM94320PFLSH_BOARD 0x045e
#define BU4712L_BOARD 0x045f
#define BCM94712LGR_BOARD 0x0460
#define BCM94320R_BOARD 0x0461
#define BU5352_BOARD 0x0462
#define BCM94318MPGH_BOARD 0x0463
#define BCM95352GR_BOARD 0x0467
/* bcm95351agr */
#define BCM95351AGR_BOARD 0x0470
/* # of GPIO pins */
#define GPIO_NUMPINS 16
#endif /* _BCMDEVS_H */

View file

@ -0,0 +1,198 @@
/*
* local version of endian.h - byte order defines
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: bcmendian.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _BCMENDIAN_H_
#define _BCMENDIAN_H_
#include <typedefs.h>
/* Byte swap a 16 bit value */
#define BCMSWAP16(val) \
((uint16)(\
(((uint16)(val) & (uint16)0x00ffU) << 8) | \
(((uint16)(val) & (uint16)0xff00U) >> 8)))
/* Byte swap a 32 bit value */
#define BCMSWAP32(val) \
((uint32)(\
(((uint32)(val) & (uint32)0x000000ffUL) << 24) | \
(((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \
(((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \
(((uint32)(val) & (uint32)0xff000000UL) >> 24)))
/* 2 Byte swap a 32 bit value */
#define BCMSWAP32BY16(val) \
((uint32)(\
(((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \
(((uint32)(val) & (uint32)0xffff0000UL) >> 16)))
static INLINE uint16
bcmswap16(uint16 val)
{
return BCMSWAP16(val);
}
static INLINE uint32
bcmswap32(uint32 val)
{
return BCMSWAP32(val);
}
static INLINE uint32
bcmswap32by16(uint32 val)
{
return BCMSWAP32BY16(val);
}
/* buf - start of buffer of shorts to swap */
/* len - byte length of buffer */
static INLINE void
bcmswap16_buf(uint16 *buf, uint len)
{
len = len/2;
while (len--) {
*buf = bcmswap16(*buf);
buf++;
}
}
#ifndef hton16
#ifndef IL_BIGENDIAN
#define HTON16(i) BCMSWAP16(i)
#define hton16(i) bcmswap16(i)
#define hton32(i) bcmswap32(i)
#define ntoh16(i) bcmswap16(i)
#define ntoh32(i) bcmswap32(i)
#define ltoh16(i) (i)
#define ltoh32(i) (i)
#define htol16(i) (i)
#define htol32(i) (i)
#else
#define HTON16(i) (i)
#define hton16(i) (i)
#define hton32(i) (i)
#define ntoh16(i) (i)
#define ntoh32(i) (i)
#define ltoh16(i) bcmswap16(i)
#define ltoh32(i) bcmswap32(i)
#define htol16(i) bcmswap16(i)
#define htol32(i) bcmswap32(i)
#endif /* IL_BIGENDIAN */
#endif /* hton16 */
#ifndef IL_BIGENDIAN
#define ltoh16_buf(buf, i)
#define htol16_buf(buf, i)
#else
#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
#endif /* IL_BIGENDIAN */
/*
* store 16-bit value to unaligned little endian byte array.
*/
static INLINE void
htol16_ua_store(uint16 val, uint8 *bytes)
{
bytes[0] = val&0xff;
bytes[1] = val>>8;
}
/*
* store 32-bit value to unaligned little endian byte array.
*/
static INLINE void
htol32_ua_store(uint32 val, uint8 *bytes)
{
bytes[0] = val&0xff;
bytes[1] = (val>>8)&0xff;
bytes[2] = (val>>16)&0xff;
bytes[3] = val>>24;
}
/*
* store 16-bit value to unaligned network(big) endian byte array.
*/
static INLINE void
hton16_ua_store(uint16 val, uint8 *bytes)
{
bytes[1] = val&0xff;
bytes[0] = val>>8;
}
/*
* store 32-bit value to unaligned network(big) endian byte array.
*/
static INLINE void
hton32_ua_store(uint32 val, uint8 *bytes)
{
bytes[3] = val&0xff;
bytes[2] = (val>>8)&0xff;
bytes[1] = (val>>16)&0xff;
bytes[0] = val>>24;
}
/*
* load 16-bit value from unaligned little endian byte array.
*/
static INLINE uint16
ltoh16_ua(void *bytes)
{
return (((uint8*)bytes)[1]<<8)+((uint8 *)bytes)[0];
}
/*
* load 32-bit value from unaligned little endian byte array.
*/
static INLINE uint32
ltoh32_ua(void *bytes)
{
return (((uint8*)bytes)[3]<<24)+(((uint8*)bytes)[2]<<16)+
(((uint8*)bytes)[1]<<8)+((uint8*)bytes)[0];
}
/*
* load 16-bit value from unaligned big(network) endian byte array.
*/
static INLINE uint16
ntoh16_ua(void *bytes)
{
return (((uint8*)bytes)[0]<<8)+((uint8*)bytes)[1];
}
/*
* load 32-bit value from unaligned big(network) endian byte array.
*/
static INLINE uint32
ntoh32_ua(void *bytes)
{
return (((uint8*)bytes)[0]<<24)+(((uint8*)bytes)[1]<<16)+
(((uint8*)bytes)[2]<<8)+((uint8*)bytes)[3];
}
#define ltoh_ua(ptr) (\
sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \
sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \
(((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \
)
#define ntoh_ua(ptr) (\
sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \
sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \
(((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \
)
#endif /* _BCMENDIAN_H_ */

View file

@ -0,0 +1,159 @@
/*
* NVRAM variable manipulation
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: bcmnvram.h,v 1.17 2006/03/02 12:33:44 honor Exp $
*/
#ifndef _bcmnvram_h_
#define _bcmnvram_h_
#ifndef _LANGUAGE_ASSEMBLY
#include <typedefs.h>
#include <bcmdefs.h>
struct nvram_header {
uint32 magic;
uint32 len;
uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
uint32 config_ncdl; /* ncdl values for memc */
};
struct nvram_tuple {
char *name;
char *value;
struct nvram_tuple *next;
};
/*
* Initialize NVRAM access. May be unnecessary or undefined on certain
* platforms.
*/
extern int nvram_init(void *sbh);
/*
* Disable NVRAM access. May be unnecessary or undefined on certain
* platforms.
*/
extern void nvram_exit(void *sbh);
/*
* Get the value of an NVRAM variable. The pointer returned may be
* invalid after a set.
* @param name name of variable to get
* @return value of variable or NULL if undefined
*/
extern char * nvram_get(const char *name);
/*
* Read the reset GPIO value from the nvram and set the GPIO
* as input
*/
extern int BCMINITFN(nvram_resetgpio_init)(void *sbh);
extern int BCMINITFN(nvram_gpio_init)(const char *name, void *sbh);
extern int BCMINITFN(nvram_gpio_set)(const char *name, void *sbh, int type);
/*
* Get the value of an NVRAM variable.
* @param name name of variable to get
* @return value of variable or NUL if undefined
*/
#define nvram_safe_get(name) (nvram_get(name) ? : "")
#define nvram_safe_unset(name) ({ \
if(nvram_get(name)) \
nvram_unset(name); \
})
#define nvram_safe_set(name, value) ({ \
if(!nvram_get(name) || strcmp(nvram_get(name), value)) \
nvram_set(name, value); \
})
/*
* Match an NVRAM variable.
* @param name name of variable to match
* @param match value to compare against value of variable
* @return TRUE if variable is defined and its value is string equal
* to match or FALSE otherwise
*/
static INLINE int
nvram_match(char *name, char *match) {
const char *value = nvram_get(name);
return (value && !strcmp(value, match));
}
/*
* Inversely match an NVRAM variable.
* @param name name of variable to match
* @param match value to compare against value of variable
* @return TRUE if variable is defined and its value is not string
* equal to invmatch or FALSE otherwise
*/
static INLINE int
nvram_invmatch(char *name, char *invmatch) {
const char *value = nvram_get(name);
return (value && strcmp(value, invmatch));
}
/*
* Set the value of an NVRAM variable. The name and value strings are
* copied into private storage. Pointers to previously set values
* may become invalid. The new value may be immediately
* retrieved but will not be permanently stored until a commit.
* @param name name of variable to set
* @param value value of variable
* @return 0 on success and errno on failure
*/
extern int nvram_set(const char *name, const char *value);
/*
* Unset an NVRAM variable. Pointers to previously set values
* remain valid until a set.
* @param name name of variable to unset
* @return 0 on success and errno on failure
* NOTE: use nvram_commit to commit this change to flash.
*/
extern int nvram_unset(const char *name);
/*
* Commit NVRAM variables to permanent storage. All pointers to values
* may be invalid after a commit.
* NVRAM values are undefined after a commit.
* @return 0 on success and errno on failure
*/
extern int nvram_commit(void);
/*
* Get all NVRAM variables (format name=value\0 ... \0\0).
* @param buf buffer to store variables
* @param count size of buffer in bytes
* @return 0 on success and errno on failure
*/
extern int nvram_getall(char *buf, int count);
extern int file2nvram(char *filename, char *varname);
extern int nvram2file(char *varname, char *filename);
#endif /* _LANGUAGE_ASSEMBLY */
#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
#define NVRAM_CLEAR_MAGIC 0x0
#define NVRAM_INVALID_MAGIC 0xFFFFFFFF
#define NVRAM_VERSION 1
#define NVRAM_HEADER_SIZE 20
#define NVRAM_SPACE 0x8000
#define NVRAM_MAX_VALUE_LEN 255
#define NVRAM_MAX_PARAM_LEN 64
#endif /* _bcmnvram_h_ */

View file

@ -0,0 +1,108 @@
/*
* Misc useful routines to access NIC local SROM/OTP .
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: bcmsrom.h,v 1.1.1.13 2006/04/15 01:29:08 michael Exp $
*/
#ifndef _bcmsrom_h_
#define _bcmsrom_h_
/* Maximum srom: 4 Kilobits == 512 bytes */
#define SROM_MAX 512
/* SROM Rev 4: Reallocate the software part of the srom to accomodate
* MIMO features. It assumes up to two PCIE functions and 440 bytes
* of useable srom i.e. the useable storage in chips with OTP that
* implements hardware redundancy.
*/
#define SROM4_WORDS 220
#define SROM4_SIGN 32
#define SROM4_SIGNATURE 0x5372
#define SROM4_BREV 33
#define SROM4_BFL0 34
#define SROM4_BFL1 35
#define SROM4_BFL2 36
#define SROM4_BFL3 37
#define SROM4_MACHI 38
#define SROM4_MACMID 39
#define SROM4_MACLO 40
#define SROM4_CCODE 41
#define SROM4_REGREV 42
#define SROM4_LEDBH10 43
#define SROM4_LEDBH32 44
#define SROM4_LEDDC 45
#define SROM4_AA 46
#define SROM4_AA2G_MASK 0x00ff
#define SROM4_AA2G_SHIFT 0
#define SROM4_AA5G_MASK 0xff00
#define SROM4_AA5G_SHIFT 8
#define SROM4_AG10 47
#define SROM4_AG32 48
#define SROM4_TXPID2G 49
#define SROM4_TXPID5G 51
#define SROM4_TXPID5GL 53
#define SROM4_TXPID5GH 55
/* Per-path fields */
#define MAX_PATH 4
#define SROM4_PATH0 64
#define SROM4_PATH1 87
#define SROM4_PATH2 110
#define SROM4_PATH3 133
#define SROM4_2G_ITT_MAXP 0
#define SROM4_2G_PA 1
#define SROM4_5G_ITT_MAXP 5
#define SROM4_5GLH_MAXP 6
#define SROM4_5G_PA 7
#define SROM4_5GL_PA 11
#define SROM4_5GH_PA 15
/* Fields in the ITT_MAXP and 5GLH_MAXP words */
#define B2G_MAXP_MASK 0xff
#define B2G_ITT_SHIFT 8
#define B5G_MAXP_MASK 0xff
#define B5G_ITT_SHIFT 8
#define B5GH_MAXP_MASK 0xff
#define B5GL_MAXP_SHIFT 8
/* All the miriad power offsets */
#define SROM4_2G_CCKPO 156
#define SROM4_2G_OFDMPO 157
#define SROM4_5G_OFDMPO 159
#define SROM4_5GL_OFDMPO 161
#define SROM4_5GH_OFDMPO 163
#define SROM4_2G_MCSPO 165
#define SROM4_5G_MCSPO 173
#define SROM4_5GL_MCSPO 181
#define SROM4_5GH_MCSPO 189
#define SROM4_CCDPO 197
#define SROM4_STBCPO 198
#define SROM4_BW40PO 199
#define SROM4_BWDUPPO 200
extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, uint *count);
extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
#endif /* _bcmsrom_h_ */

View file

@ -0,0 +1,433 @@
/*
* Misc useful os-independent macros and functions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
* $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $
*/
#ifndef _bcmutils_h_
#define _bcmutils_h_
/* ** driver-only section ** */
#ifdef BCMDRIVER
#define _BCM_U 0x01 /* upper */
#define _BCM_L 0x02 /* lower */
#define _BCM_D 0x04 /* digit */
#define _BCM_C 0x08 /* cntrl */
#define _BCM_P 0x10 /* punct */
#define _BCM_S 0x20 /* white space (space/lf/tab) */
#define _BCM_X 0x40 /* hex digit */
#define _BCM_SP 0x80 /* hard space (0x20) */
#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */
extern unsigned char bcm_ctype[];
#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
/*
* Spin at most 'us' microseconds while 'exp' is true.
* Caller should explicitly test 'exp' when this completes
* and take appropriate error action if 'exp' is still true.
*/
#define SPINWAIT(exp, us) { \
uint countdown = (us) + 9; \
while ((exp) && (countdown >= 10)) {\
OSL_DELAY(10); \
countdown -= 10; \
} \
}
struct ether_addr {
uint8 octet[6];
} __attribute__((packed));
/* string */
extern uchar bcm_toupper(uchar c);
extern ulong bcm_strtoul(char *cp, char **endp, uint base);
extern char *bcmstrstr(char *haystack, char *needle);
extern char *bcmstrcat(char *dest, const char *src);
extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
/* ethernet address */
extern char *bcm_ether_ntoa(struct ether_addr *ea, char *buf);
/* variable access */
extern char *getvar(char *vars, char *name);
extern int getintvar(char *vars, char *name);
extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
#ifdef BCMPERFSTATS
extern void bcm_perf_enable(void);
extern void bcmstats(char *fmt);
extern void bcmlog(char *fmt, uint a1, uint a2);
extern void bcmdumplog(char *buf, int size);
extern int bcmdumplogent(char *buf, uint idx);
#else
#define bcm_perf_enable()
#define bcmstats(fmt)
#define bcmlog(fmt, a1, a2)
#define bcmdumplog(buf, size) *buf = '\0'
#define bcmdumplogent(buf, idx) -1
#endif /* BCMPERFSTATS */
extern char *bcm_nvram_vars(uint *length);
extern int bcm_nvram_cache(void *sbh);
/* Support for sharing code across in-driver iovar implementations.
* The intent is that a driver use this structure to map iovar names
* to its (private) iovar identifiers, and the lookup function to
* find the entry. Macros are provided to map ids and get/set actions
* into a single number space for a switch statement.
*/
/* iovar structure */
typedef struct bcm_iovar {
const char *name; /* name for lookup and display */
uint16 varid; /* id for switch */
uint16 flags; /* driver-specific flag bits */
uint16 type; /* base type of argument */
uint16 minlen; /* min length for buffer vars */
} bcm_iovar_t;
/* varid definitions are per-driver, may use these get/set bits */
/* IOVar action bits for id mapping */
#define IOV_GET 0 /* Get an iovar */
#define IOV_SET 1 /* Set an iovar */
/* Varid to actionid mapping */
#define IOV_GVAL(id) ((id)*2)
#define IOV_SVAL(id) (((id)*2)+IOV_SET)
#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET)
/* flags are per-driver based on driver attributes */
/* Base type definitions */
#define IOVT_VOID 0 /* no value (implictly set only) */
#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */
#define IOVT_INT8 2 /* integer values are range-checked */
#define IOVT_UINT8 3 /* unsigned int 8 bits */
#define IOVT_INT16 4 /* int 16 bits */
#define IOVT_UINT16 5 /* unsigned int 16 bits */
#define IOVT_INT32 6 /* int 32 bits */
#define IOVT_UINT32 7 /* unsigned int 32 bits */
#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */
extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name);
extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set);
#endif /* #ifdef BCMDRIVER */
/* ** driver/apps-shared section ** */
#define BCME_STRLEN 64 /* Max string length for BCM errors */
#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST))
/*
* error codes could be added but the defined ones shouldn't be changed/deleted
* these error codes are exposed to the user code
* when ever a new error code is added to this list
* please update errorstring table with the related error string and
* update osl files with os specific errorcode map
*/
#define BCME_OK 0 /* Success */
#define BCME_ERROR -1 /* Error generic */
#define BCME_BADARG -2 /* Bad Argument */
#define BCME_BADOPTION -3 /* Bad option */
#define BCME_NOTUP -4 /* Not up */
#define BCME_NOTDOWN -5 /* Not down */
#define BCME_NOTAP -6 /* Not AP */
#define BCME_NOTSTA -7 /* Not STA */
#define BCME_BADKEYIDX -8 /* BAD Key Index */
#define BCME_RADIOOFF -9 /* Radio Off */
#define BCME_NOTBANDLOCKED -10 /* Not band locked */
#define BCME_NOCLK -11 /* No Clock */
#define BCME_BADRATESET -12 /* BAD Rate valueset */
#define BCME_BADBAND -13 /* BAD Band */
#define BCME_BUFTOOSHORT -14 /* Buffer too short */
#define BCME_BUFTOOLONG -15 /* Buffer too long */
#define BCME_BUSY -16 /* Busy */
#define BCME_NOTASSOCIATED -17 /* Not Associated */
#define BCME_BADSSIDLEN -18 /* Bad SSID len */
#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */
#define BCME_BADCHAN -20 /* Bad Channel */
#define BCME_BADADDR -21 /* Bad Address */
#define BCME_NORESOURCE -22 /* Not Enough Resources */
#define BCME_UNSUPPORTED -23 /* Unsupported */
#define BCME_BADLEN -24 /* Bad length */
#define BCME_NOTREADY -25 /* Not Ready */
#define BCME_EPERM -26 /* Not Permitted */
#define BCME_NOMEM -27 /* No Memory */
#define BCME_ASSOCIATED -28 /* Associated */
#define BCME_RANGE -29 /* Not In Range */
#define BCME_NOTFOUND -30 /* Not Found */
#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */
#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */
#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */
#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */
#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */
#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */
#define BCME_LAST BCME_DONGLE_DOWN
/* These are collection of BCME Error strings */
#define BCMERRSTRINGTABLE { \
"OK", \
"Undefined error", \
"Bad Argument", \
"Bad Option", \
"Not up", \
"Not down", \
"Not AP", \
"Not STA", \
"Bad Key Index", \
"Radio Off", \
"Not band locked", \
"No clock", \
"Bad Rate valueset", \
"Bad Band", \
"Buffer too short", \
"Buffer too long", \
"Busy", \
"Not Associated", \
"Bad SSID len", \
"Out of Range Channel", \
"Bad Channel", \
"Bad Address", \
"Not Enough Resources", \
"Unsupported", \
"Bad length", \
"Not Ready", \
"Not Permitted", \
"No Memory", \
"Associated", \
"Not In Range", \
"Not Found", \
"WME Not Enabled", \
"TSPEC Not Found", \
"ACM Not Supported", \
"Not WME Association", \
"SDIO Bus Error", \
"Dongle Not Accessible" \
}
#ifndef ABS
#define ABS(a) (((a) < 0)?-(a):(a))
#endif /* ABS */
#ifndef MIN
#define MIN(a, b) (((a) < (b))?(a):(b))
#endif /* MIN */
#ifndef MAX
#define MAX(a, b) (((a) > (b))?(a):(b))
#endif /* MAX */
#define CEIL(x, y) (((x) + ((y)-1)) / (y))
#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0)
#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0)
#define VALID_MASK(mask) !((mask) & ((mask) + 1))
#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member)
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
/* bit map related macros */
#ifndef setbit
#ifndef NBBY /* the BSD family defines NBBY */
#define NBBY 8 /* 8 bits per byte */
#endif /* #ifndef NBBY */
#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
#define isset(a, i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
#define isclr(a, i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
#endif /* setbit */
#define NBITS(type) (sizeof(type) * 8)
#define NBITVAL(nbits) (1 << (nbits))
#define MAXBITVAL(nbits) ((1 << (nbits)) - 1)
#define NBITMASK(nbits) MAXBITVAL(nbits)
#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8)
/* basic mux operation - can be optimized on several architectures */
#define MUX(pred, true, false) ((pred) ? (true) : (false))
/* modulo inc/dec - assumes x E [0, bound - 1] */
#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
/* modulo inc/dec, bound = 2^k */
#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
/* modulo add/sub - assumes x, y E [0, bound - 1] */
#define MODADD(x, y, bound) \
MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
#define MODSUB(x, y, bound) \
MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
/* module add/sub, bound = 2^k */
#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
/* crc defines */
#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
/* bcm_format_flags() bit description structure */
typedef struct bcm_bit_desc {
uint32 bit;
char* name;
} bcm_bit_desc_t;
/* tag_ID/length/value_buffer tuple */
typedef struct bcm_tlv {
uint8 id;
uint8 len;
uint8 data[1];
} bcm_tlv_t;
/* Check that bcm_tlv_t fits into the given buflen */
#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
/* buffer length for ethernet address from bcm_ether_ntoa() */
#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */
/* unaligned load and store macros */
#ifdef IL_BIGENDIAN
static INLINE uint32
load32_ua(uint8 *a)
{
return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]);
}
static INLINE void
store32_ua(uint8 *a, uint32 v)
{
a[0] = (v >> 24) & 0xff;
a[1] = (v >> 16) & 0xff;
a[2] = (v >> 8) & 0xff;
a[3] = v & 0xff;
}
static INLINE uint16
load16_ua(uint8 *a)
{
return ((a[0] << 8) | a[1]);
}
static INLINE void
store16_ua(uint8 *a, uint16 v)
{
a[0] = (v >> 8) & 0xff;
a[1] = v & 0xff;
}
#else
static INLINE uint32
load32_ua(uint8 *a)
{
return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
}
static INLINE void
store32_ua(uint8 *a, uint32 v)
{
a[3] = (v >> 24) & 0xff;
a[2] = (v >> 16) & 0xff;
a[1] = (v >> 8) & 0xff;
a[0] = v & 0xff;
}
static INLINE uint16
load16_ua(uint8 *a)
{
return ((a[1] << 8) | a[0]);
}
static INLINE void
store16_ua(uint8 *a, uint16 v)
{
a[1] = (v >> 8) & 0xff;
a[0] = v & 0xff;
}
#endif /* IL_BIGENDIAN */
/* externs */
/* crc */
extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc);
extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc);
/* format/print */
extern void printfbig(char *buf);
/* IE parsing */
extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
/* bcmerror */
extern const char *bcmerrorstr(int bcmerror);
/* multi-bool data type: set of bools, mbool is true if any is set */
typedef uint32 mbool;
#define mboolset(mb, bit) (mb |= bit) /* set one bool */
#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */
#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */
#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val)))
/* power conversion */
extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
extern uint8 bcm_mw_to_qdbm(uint16 mw);
/* generic datastruct to help dump routines */
struct fielddesc {
char *nameandfmt;
uint32 offset;
uint32 len;
};
/* Buffer structure for collecting string-formatted data
* using bcm_bprintf() API.
* Use bcm_binit() to initialize before use
*/
struct bcmstrbuf
{
char *buf; /* pointer to current position in origbuf */
uint size; /* current (residual) size in bytes */
char *origbuf; /* unmodified pointer to orignal buffer */
uint origsize; /* unmodified orignal buffer size in bytes */
};
extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset);
extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str,
char *buf, uint32 bufsize);
extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
extern uint bcm_bitcount(uint8 *bitmap, uint bytelength);
#endif /* _bcmutils_h_ */

View file

@ -0,0 +1,28 @@
/*
* HND SiliconBackplane MIPS/ARM cores software interface.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: hndcpu.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _hndcpu_h_
#define _hndcpu_h_
#if defined(mips)
#include <hndmips.h>
#elif defined(__ARM_ARCH_4T__)
#include <hndarm.h>
#endif
extern uint sb_irq(sb_t *sbh);
extern uint32 sb_cpu_clock(sb_t *sbh);
extern void sb_cpu_wait(void);
#endif /* _hndcpu_h_ */

View file

@ -0,0 +1,45 @@
/*
* HND SiliconBackplane MIPS core software interface.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: hndmips.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _hndmips_h_
#define _hndmips_h_
extern void sb_mips_init(sb_t *sbh, uint shirq_map_base);
extern bool sb_mips_setclock(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock);
extern void enable_pfc(uint32 mode);
extern uint32 sb_memc_get_ncdl(sb_t *sbh);
#if defined(BCMPERFSTATS)
/* enable counting - exclusive version. Only one set of counters allowed at a time */
extern void hndmips_perf_instrcount_enable(void);
extern void hndmips_perf_icachecount_enable(void);
extern void hndmips_perf_dcachecount_enable(void);
/* start and stop counting */
#define hndmips_perf_start01() \
MTC0(C0_PERFORMANCE, 4, MFC0(C0_PERFORMANCE, 4) | 0x80008000)
#define hndmips_perf_stop01() \
MTC0(C0_PERFORMANCE, 4, MFC0(C0_PERFORMANCE, 4) & ~0x80008000)
/* retrieve coutners - counters *decrement* */
#define hndmips_perf_read0() -(long)(MFC0(C0_PERFORMANCE, 0))
#define hndmips_perf_read1() -(long)(MFC0(C0_PERFORMANCE, 1))
#define hndmips_perf_read2() -(long)(MFC0(C0_PERFORMANCE, 2))
/* enable counting - modular version. Each counters can be enabled separately. */
extern void hndmips_perf_icache_hit_enable(void);
extern void hndmips_perf_icache_miss_enable(void);
extern uint32 hndmips_perf_read_instrcount(void);
extern uint32 hndmips_perf_read_cache_miss(void);
extern uint32 hndmips_perf_read_cache_hit(void);
#endif /* defined(BCMINTERNAL) || defined (BCMPERFSTATS) */
#endif /* _hndmips_h_ */

View file

@ -0,0 +1,30 @@
/*
* HND SiliconBackplane PCI core software interface.
*
* $Id: hndpci.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
* Copyright 2006, Broadcom Corporation
* 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.
*/
#ifndef _hndpci_h_
#define _hndpci_h_
extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf,
int len);
extern int extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf,
int len);
extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf,
int len);
extern int extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf,
int len);
extern void sbpci_ban(uint16 core);
extern int sbpci_init(sb_t *sbh);
extern int sbpci_init_pci(sb_t *sbh);
extern void sbpci_check(sb_t *sbh);
#endif /* _hndpci_h_ */

View file

@ -0,0 +1,417 @@
/*
* Linux-specific abstractions to gain some independence from linux kernel versions.
* Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
*
* Copyright 2006, Broadcom Corporation
* 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: linuxver.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _linuxver_h_
#define _linuxver_h_
#include <linux/config.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0))
/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */
#ifdef __UNDEF_NO_VERSION__
#undef __NO_VERSION__
#else
#define __NO_VERSION__
#endif
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */
#if defined(MODULE) && defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
#include <linux/moduleparam.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i")
#define module_param_string(_name_, _string_, _size_, _perm_) \
MODULE_PARM(_string_, "c" __MODULE_STRING(_size_))
#endif
/* linux/malloc.h is deprecated, use linux/slab.h instead. */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9))
#include <linux/malloc.h>
#else
#include <linux/slab.h>
#endif
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <asm/io.h>
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41))
#include <linux/workqueue.h>
#else
#include <linux/tqueue.h>
#ifndef work_struct
#define work_struct tq_struct
#endif
#ifndef INIT_WORK
#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data))
#endif
#ifndef schedule_work
#define schedule_work(_work) schedule_task((_work))
#endif
#ifndef flush_scheduled_work
#define flush_scheduled_work() flush_scheduled_tasks()
#endif
#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
/* Some distributions have their own 2.6.x compatibility layers */
#ifndef IRQ_NONE
typedef void irqreturn_t;
#define IRQ_NONE
#define IRQ_HANDLED
#define IRQ_RETVAL(x)
#endif
#else
typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs);
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69))
/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which
* does this, but it's not in 2.4 so we do our own for now.
*/
static inline void
cs_error(client_handle_t handle, int func, int ret)
{
error_info_t err = { func, ret };
CardServices(ReportError, handle, &err);
}
#endif
#endif /* CONFIG_PCMCIA */
#ifndef __exit
#define __exit
#endif
#ifndef __devexit
#define __devexit
#endif
#ifndef __devinit
#define __devinit __init
#endif
#ifndef __devinitdata
#define __devinitdata
#endif
#ifndef __devexit_p
#define __devexit_p(x) x
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
#define pci_get_drvdata(dev) (dev)->sysdata
#define pci_set_drvdata(dev, value) (dev)->sysdata = (value)
/*
* New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration
*/
struct pci_device_id {
unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
unsigned long driver_data; /* Data private to the driver */
};
struct pci_driver {
struct list_head node;
char *name;
const struct pci_device_id *id_table; /* NULL if wants all devices */
int (*probe)(struct pci_dev *dev,
const struct pci_device_id *id); /* New device inserted */
void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug
* capable driver)
*/
void (*suspend)(struct pci_dev *dev); /* Device suspended */
void (*resume)(struct pci_dev *dev); /* Device woken up */
};
#define MODULE_DEVICE_TABLE(type, name)
#define PCI_ANY_ID (~0)
/* compatpci.c */
#define pci_module_init pci_register_driver
extern int pci_register_driver(struct pci_driver *drv);
extern void pci_unregister_driver(struct pci_driver *drv);
#endif /* PCI registration */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18))
#ifdef MODULE
#define module_init(x) int init_module(void) { return x(); }
#define module_exit(x) void cleanup_module(void) { x(); }
#else
#define module_init(x) __initcall(x);
#define module_exit(x) __exitcall(x);
#endif
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48))
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13))
#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)])
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44))
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23))
#define pci_enable_device(dev) do { } while (0)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14))
#define net_device device
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42))
/*
* DMA mapping
*
* See linux/Documentation/DMA-mapping.txt
*/
#ifndef PCI_DMA_TODEVICE
#define PCI_DMA_TODEVICE 1
#define PCI_DMA_FROMDEVICE 2
#endif
typedef u32 dma_addr_t;
/* Pure 2^n version of get_order */
static inline int get_order(unsigned long size)
{
int order;
size = (size-1) >> (PAGE_SHIFT-1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC | GFP_DMA;
ret = (void *)__get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
return ret;
}
static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long)vaddr, get_order(size));
}
#ifdef ILSIM
extern uint pci_map_single(void *dev, void *va, uint size, int direction);
extern void pci_unmap_single(void *dev, uint pa, uint size, int direction);
#else
#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
#define pci_unmap_single(cookie, address, size, dir)
#endif
#endif /* DMA mapping */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43))
#define dev_kfree_skb_any(a) dev_kfree_skb(a)
#define netif_down(dev) do { (dev)->start = 0; } while (0)
/* pcmcia-cs provides its own netdevice compatibility layer */
#ifndef _COMPAT_NETDEVICE_H
/*
* SoftNet
*
* For pre-softnet kernels we need to tell the upper layer not to
* re-enter start_xmit() while we are in there. However softnet
* guarantees not to enter while we are in there so there is no need
* to do the netif_stop_queue() dance unless the transmit queue really
* gets stuck. This should also improve performance according to tests
* done by Aman Singla.
*/
#define dev_kfree_skb_irq(a) dev_kfree_skb(a)
#define netif_wake_queue(dev) \
do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0)
#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy)
static inline void netif_start_queue(struct net_device *dev)
{
dev->tbusy = 0;
dev->interrupt = 0;
dev->start = 1;
}
#define netif_queue_stopped(dev) (dev)->tbusy
#define netif_running(dev) (dev)->start
#endif /* _COMPAT_NETDEVICE_H */
#define netif_device_attach(dev) netif_start_queue(dev)
#define netif_device_detach(dev) netif_stop_queue(dev)
/* 2.4.x renamed bottom halves to tasklets */
#define tasklet_struct tq_struct
static inline void tasklet_schedule(struct tasklet_struct *tasklet)
{
queue_task(tasklet, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
static inline void tasklet_init(struct tasklet_struct *tasklet,
void (*func)(unsigned long),
unsigned long data)
{
tasklet->next = NULL;
tasklet->sync = 0;
tasklet->routine = (void (*)(void *))func;
tasklet->data = (void *)data;
}
#define tasklet_kill(tasklet) { do{} while (0); }
/* 2.4.x introduced del_timer_sync() */
#define del_timer_sync(timer) del_timer(timer)
#else
#define netif_down(dev)
#endif /* SoftNet */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3))
/*
* Emit code to initialise a tq_struct's routine and data pointers
*/
#define PREPARE_TQUEUE(_tq, _routine, _data) \
do { \
(_tq)->routine = _routine; \
(_tq)->data = _data; \
} while (0)
/*
* Emit code to initialise all of a tq_struct
*/
#define INIT_TQUEUE(_tq, _routine, _data) \
do { \
INIT_LIST_HEAD(&(_tq)->list); \
(_tq)->sync = 0; \
PREPARE_TQUEUE((_tq), (_routine), (_data)); \
} while (0)
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6))
/* Power management related routines */
static inline int
pci_save_state(struct pci_dev *dev, u32 *buffer)
{
int i;
if (buffer) {
for (i = 0; i < 16; i++)
pci_read_config_dword(dev, i * 4, &buffer[i]);
}
return 0;
}
static inline int
pci_restore_state(struct pci_dev *dev, u32 *buffer)
{
int i;
if (buffer) {
for (i = 0; i < 16; i++)
pci_write_config_dword(dev, i * 4, buffer[i]);
}
/*
* otherwise, write the context information we know from bootup.
* This works around a problem where warm-booting from Windows
* combined with a D3(hot)->D0 transition causes PCI config
* header data to be forgotten.
*/
else {
for (i = 0; i < 6; i ++)
pci_write_config_dword(dev,
PCI_BASE_ADDRESS_0 + (i * 4),
pci_resource_start(dev, i));
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
return 0;
}
#endif /* PCI power management */
/* Old cp0 access macros deprecated in 2.4.19 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19))
#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
#endif
/* Module refcount handled internally in 2.6.x */
#ifndef SET_MODULE_OWNER
#define SET_MODULE_OWNER(dev) do {} while (0)
#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
#else
#define OLD_MOD_INC_USE_COUNT do {} while (0)
#define OLD_MOD_DEC_USE_COUNT do {} while (0)
#endif
#ifndef SET_NETDEV_DEV
#define SET_NETDEV_DEV(net, pdev) do {} while (0)
#endif
#ifndef HAVE_FREE_NETDEV
#define free_netdev(dev) kfree(dev)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
/* struct packet_type redefined in 2.6.x */
#define af_packet_priv data
#endif
#endif /* _linuxver_h_ */

View file

@ -0,0 +1,541 @@
/*
* HND Run Time Environment for standalone MIPS programs.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: mipsinc.h,v 1.1.1.5 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _MISPINC_H
#define _MISPINC_H
/* MIPS defines */
#ifdef _LANGUAGE_ASSEMBLY
/*
* Symbolic register names for 32 bit ABI
*/
#define zero $0 /* wired zero */
#define AT $1 /* assembler temp - uppercase because of ".set at" */
#define v0 $2 /* return value */
#define v1 $3
#define a0 $4 /* argument registers */
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8 /* caller saved */
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16 /* callee saved */
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 /* caller saved */
#define t9 $25
#define jp $25 /* PIC jump register */
#define k0 $26 /* kernel scratch */
#define k1 $27
#define gp $28 /* global pointer */
#define sp $29 /* stack pointer */
#define fp $30 /* frame pointer */
#define s8 $30 /* same like fp! */
#define ra $31 /* return address */
/* CP0 Registers */
#define C0_INX $0
#define C0_RAND $1
#define C0_TLBLO0 $2
#define C0_TLBLO C0_TLBLO0
#define C0_TLBLO1 $3
#define C0_CTEXT $4
#define C0_PGMASK $5
#define C0_WIRED $6
#define C0_BADVADDR $8
#define C0_COUNT $9
#define C0_TLBHI $10
#define C0_COMPARE $11
#define C0_SR $12
#define C0_STATUS C0_SR
#define C0_CAUSE $13
#define C0_EPC $14
#define C0_PRID $15
#define C0_CONFIG $16
#define C0_LLADDR $17
#define C0_WATCHLO $18
#define C0_WATCHHI $19
#define C0_XCTEXT $20
#define C0_DIAGNOSTIC $22
#define C0_BROADCOM C0_DIAGNOSTIC
#define C0_PERFORMANCE $25
#define C0_ECC $26
#define C0_CACHEERR $27
#define C0_TAGLO $28
#define C0_TAGHI $29
#define C0_ERREPC $30
#define C0_DESAVE $31
/*
* LEAF - declare leaf routine
*/
#define LEAF(symbol) \
.globl symbol; \
.align 2; \
.type symbol, @function; \
.ent symbol, 0; \
symbol: .frame sp, 0, ra
/*
* END - mark end of function
*/
#define END(function) \
.end function; \
.size function, . - function
#define _ULCAST_
#define MFC0_SEL(dst, src, sel) \
.word\t(0x40000000 | ((dst) << 16) | ((src) << 11) | (sel))
#define MTC0_SEL(dst, src, sel) \
.word\t(0x40800000 | ((dst) << 16) | ((src) << 11) | (sel))
#else
/*
* 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
#define _ULCAST_ (unsigned long)
/* 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_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */
#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 */
#define C0_DESAVE 31 /* CP0: DebugSave */
#endif /* _LANGUAGE_ASSEMBLY */
/*
* 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
#define PHYSADDR_MASK 0x1fffffff
/*
* Map an address to a certain kernel segment
*/
#undef PHYSADDR
#undef KSEG0ADDR
#undef KSEG1ADDR
#undef KSEG2ADDR
#undef KSEG3ADDR
#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK)
#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0)
#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1)
#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2)
#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3)
#ifndef Index_Invalidate_I
/*
* Cache Operations
*/
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01
#define Index_Invalidate_SI 0x02
#define Index_Writeback_Inv_SD 0x03
#define Index_Load_Tag_I 0x04
#define Index_Load_Tag_D 0x05
#define Index_Load_Tag_SI 0x06
#define Index_Load_Tag_SD 0x07
#define Index_Store_Tag_I 0x08
#define Index_Store_Tag_D 0x09
#define Index_Store_Tag_SI 0x0A
#define Index_Store_Tag_SD 0x0B
#define Create_Dirty_Excl_D 0x0d
#define Create_Dirty_Excl_SD 0x0f
#define Hit_Invalidate_I 0x10
#define Hit_Invalidate_D 0x11
#define Hit_Invalidate_SI 0x12
#define Hit_Invalidate_SD 0x13
#define Fill_I 0x14
#define Hit_Writeback_Inv_D 0x15
/* 0x16 is unused */
#define Hit_Writeback_Inv_SD 0x17
#define R5K_Page_Invalidate_S 0x17
#define Hit_Writeback_I 0x18
#define Hit_Writeback_D 0x19
/* 0x1a is unused */
#define Hit_Writeback_SD 0x1b
/* 0x1c is unused */
/* 0x1e is unused */
#define Hit_Set_Virtual_SI 0x1e
#define Hit_Set_Virtual_SD 0x1f
#endif /* !Index_Invalidate_I */
/*
* R4x00 interrupt enable / cause bits
*/
#define IE_SW0 (_ULCAST_(1) << 8)
#define IE_SW1 (_ULCAST_(1) << 9)
#define IE_IRQ0 (_ULCAST_(1) << 10)
#define IE_IRQ1 (_ULCAST_(1) << 11)
#define IE_IRQ2 (_ULCAST_(1) << 12)
#define IE_IRQ3 (_ULCAST_(1) << 13)
#define IE_IRQ4 (_ULCAST_(1) << 14)
#define IE_IRQ5 (_ULCAST_(1) << 15)
#ifndef ST0_UM
/*
* Bitfields in the mips32 cp0 status register
*/
#define ST0_IE 0x00000001
#define ST0_EXL 0x00000002
#define ST0_ERL 0x00000004
#define ST0_UM 0x00000010
#define ST0_SWINT0 0x00000100
#define ST0_SWINT1 0x00000200
#define ST0_HWINT0 0x00000400
#define ST0_HWINT1 0x00000800
#define ST0_HWINT2 0x00001000
#define ST0_HWINT3 0x00002000
#define ST0_HWINT4 0x00004000
#define ST0_HWINT5 0x00008000
#define ST0_IM 0x0000ff00
#define ST0_NMI 0x00080000
#define ST0_SR 0x00100000
#define ST0_TS 0x00200000
#define ST0_BEV 0x00400000
#define ST0_RE 0x02000000
#define ST0_RP 0x08000000
#define ST0_CU 0xf0000000
#define ST0_CU0 0x10000000
#define ST0_CU1 0x20000000
#define ST0_CU2 0x40000000
#define ST0_CU3 0x80000000
#endif /* !ST0_UM */
/*
* Bitfields in the mips32 cp0 cause register
*/
#define C_EXC 0x0000007c
#define C_EXC_SHIFT 2
#define C_INT 0x0000ff00
#define C_INT_SHIFT 8
#define C_SW0 (_ULCAST_(1) << 8)
#define C_SW1 (_ULCAST_(1) << 9)
#define C_IRQ0 (_ULCAST_(1) << 10)
#define C_IRQ1 (_ULCAST_(1) << 11)
#define C_IRQ2 (_ULCAST_(1) << 12)
#define C_IRQ3 (_ULCAST_(1) << 13)
#define C_IRQ4 (_ULCAST_(1) << 14)
#define C_IRQ5 (_ULCAST_(1) << 15)
#define C_WP 0x00400000
#define C_IV 0x00800000
#define C_CE 0x30000000
#define C_CE_SHIFT 28
#define C_BD 0x80000000
/* Values in C_EXC */
#define EXC_INT 0
#define EXC_TLBM 1
#define EXC_TLBL 2
#define EXC_TLBS 3
#define EXC_AEL 4
#define EXC_AES 5
#define EXC_IBE 6
#define EXC_DBE 7
#define EXC_SYS 8
#define EXC_BPT 9
#define EXC_RI 10
#define EXC_CU 11
#define EXC_OV 12
#define EXC_TR 13
#define EXC_WATCH 23
#define EXC_MCHK 24
/*
* Bits in the cp0 config register.
*/
#define CONF_CM_CACHABLE_NO_WA 0
#define CONF_CM_CACHABLE_WA 1
#define CONF_CM_UNCACHED 2
#define CONF_CM_CACHABLE_NONCOHERENT 3
#define CONF_CM_CACHABLE_CE 4
#define CONF_CM_CACHABLE_COW 5
#define CONF_CM_CACHABLE_CUW 6
#define CONF_CM_CACHABLE_ACCELERATED 7
#define CONF_CM_CMASK 7
#define CONF_CU (_ULCAST_(1) << 3)
#define CONF_DB (_ULCAST_(1) << 4)
#define CONF_IB (_ULCAST_(1) << 5)
#define CONF_SE (_ULCAST_(1) << 12)
#ifndef CONF_BE /* duplicate in mipsregs.h */
#define CONF_BE (_ULCAST_(1) << 15)
#endif
#define CONF_SC (_ULCAST_(1) << 17)
#define CONF_AC (_ULCAST_(1) << 23)
#define CONF_HALT (_ULCAST_(1) << 25)
#ifndef CONF_M /* duplicate in mipsregs.h */
#define CONF_M (_ULCAST_(1) << 31)
#endif
/*
* Bits in the cp0 config register select 1.
*/
#define CONF1_FP 0x00000001 /* FPU present */
#define CONF1_EP 0x00000002 /* EJTAG present */
#define CONF1_CA 0x00000004 /* mips16 implemented */
#define CONF1_WR 0x00000008 /* Watch registers present */
#define CONF1_PC 0x00000010 /* Performance counters present */
#define CONF1_DA_SHIFT 7 /* D$ associativity */
#define CONF1_DA_MASK 0x00000380
#define CONF1_DA_BASE 1
#define CONF1_DL_SHIFT 10 /* D$ line size */
#define CONF1_DL_MASK 0x00001c00
#define CONF1_DL_BASE 2
#define CONF1_DS_SHIFT 13 /* D$ sets/way */
#define CONF1_DS_MASK 0x0000e000
#define CONF1_DS_BASE 64
#define CONF1_IA_SHIFT 16 /* I$ associativity */
#define CONF1_IA_MASK 0x00070000
#define CONF1_IA_BASE 1
#define CONF1_IL_SHIFT 19 /* I$ line size */
#define CONF1_IL_MASK 0x00380000
#define CONF1_IL_BASE 2
#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */
#define CONF1_IS_MASK 0x01c00000
#define CONF1_IS_BASE 64
#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */
#define CONF1_MS_SHIFT 25
/* PRID register */
#define PRID_COPT_MASK 0xff000000
#define PRID_COMP_MASK 0x00ff0000
#define PRID_IMP_MASK 0x0000ff00
#define PRID_REV_MASK 0x000000ff
#define PRID_COMP_LEGACY 0x000000
#define PRID_COMP_MIPS 0x010000
#define PRID_COMP_BROADCOM 0x020000
#define PRID_COMP_ALCHEMY 0x030000
#define PRID_COMP_SIBYTE 0x040000
#define PRID_IMP_BCM4710 0x4000
#define PRID_IMP_BCM3302 0x9000
#define PRID_IMP_BCM3303 0x9100
#define PRID_IMP_UNKNOWN 0xff00
#define BCM330X(id) \
(((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \
(PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) || \
((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \
(PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
/* Bits in C0_BROADCOM */
#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */
#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */
#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */
#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */
#define BRCM_CLF_ENABLE 0x00100000 /* Enable cache line first feature */
/* PreFetch Cache aka Read Ahead Cache */
#define PFC_CR0 0xff400000 /* control reg 0 */
#define PFC_CR1 0xff400004 /* control reg 1 */
/* PFC operations */
#define PFC_I 0x00000001 /* Enable PFC use for instructions */
#define PFC_D 0x00000002 /* Enable PFC use for data */
#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */
#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */
#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */
#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */
#define PFC_DPF 0x00000040 /* Enable directional prefetching */
#define PFC_FLUSH 0x00000100 /* Flush the PFC */
#define PFC_BRR 0x40000000 /* Bus error indication */
#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */
/* Handy defaults */
#define PFC_DISABLED 0
#define PFC_AUTO 0xffffffff /* auto select the default mode */
#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV)
#define PFC_INST_NOPF (PFC_I | PFC_CINV)
#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV)
#define PFC_DATA_NOPF (PFC_D | PFC_CINV)
#define PFC_I_AND_D (PFC_INST | PFC_DATA)
#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF)
#ifndef _LANGUAGE_ASSEMBLY
/*
* Macros to access the system control coprocessor
*/
#define MFC0(source, sel) \
({ \
int __res; \
__asm__ __volatile__(" \
.set\tnoreorder; \
.set\tnoat; \
.word\t"STR(0x40010000 | ((source) << 11) | (sel))"; \
move\t%0, $1; \
.set\tat; \
.set\treorder" \
:"=r" (__res) \
: \
:"$1"); \
__res; \
})
#define MTC0(source, sel, value) \
do { \
__asm__ __volatile__(" \
.set\tnoreorder; \
.set\tnoat; \
move\t$1, %z0; \
.word\t"STR(0x40810000 | ((source) << 11) | (sel))"; \
.set\tat; \
.set\treorder" \
: \
:"jr" (value) \
:"$1"); \
} while (0)
#define get_c0_count() \
({ \
int __res; \
__asm__ __volatile__(" \
.set\tnoreorder; \
.set\tnoat; \
mfc0\t%0, $9; \
.set\tat; \
.set\treorder" \
:"=r" (__res)); \
__res; \
})
static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize)
{
uint lsz, sets, ways;
/* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT)))
lsz = CONF1_IL_BASE << lsz;
sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT);
ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT);
*size = lsz * sets * ways;
*lsize = lsz;
}
static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize)
{
uint lsz, sets, ways;
/* Data Cache Size = Associativity * Line Size * Sets Per Way */
if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT)))
lsz = CONF1_DL_BASE << lsz;
sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT);
ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT);
*size = lsz * sets * ways;
*lsize = lsz;
}
#define cache_op(base, op) \
__asm__ __volatile__(" \
.set noreorder; \
.set mips3; \
cache %1, (%0); \
.set mips0; \
.set reorder" \
: \
: "r" (base), \
"i" (op));
#define cache_unroll4(base, delta, op) \
__asm__ __volatile__(" \
.set noreorder; \
.set mips3; \
cache %1, 0(%0); \
cache %1, delta(%0); \
cache %1, (2 * delta)(%0); \
cache %1, (3 * delta)(%0); \
.set mips0; \
.set reorder" \
: \
: "r" (base), \
"i" (op));
#endif /* !_LANGUAGE_ASSEMBLY */
#endif /* _MISPINC_H */

View file

@ -0,0 +1,181 @@
#ifndef __osl_h
#define __osl_h
#include <linux/delay.h>
#include <typedefs.h>
#include <linuxver.h>
#include <bcmutils.h>
#include <pcicfg.h>
#define ASSERT(n)
/* Pkttag flag should be part of public information */
typedef struct {
bool pkttag;
uint pktalloced; /* Number of allocated packet buffers */
void *tx_fn;
void *tx_ctx;
} osl_pubinfo_t;
struct osl_info {
osl_pubinfo_t pub;
uint magic;
void *pdev;
uint malloced;
uint failed;
void *dbgmem_list;
};
typedef struct osl_info osl_t;
#define PCI_CFG_RETRY 10
/* map/unmap direction */
#define DMA_TX 1 /* TX direction for DMA */
#define DMA_RX 2 /* RX direction for DMA */
#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v))
#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v))
#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val)))
/* bcopy, bcmp, and bzero */
#define bcopy(src, dst, len) memcpy((dst), (src), (len))
#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
#define bzero(b, len) memset((b), '\0', (len))
/* uncached virtual address */
#ifdef mips
#define OSL_UNCACHED(va) KSEG1ADDR((va))
#include <asm/addrspace.h>
#else
#define OSL_UNCACHED(va) (va)
#endif /* mips */
#ifndef IL_BIGENDIAN
#define R_REG(osh, r) (\
sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
readl((volatile uint32*)(r)) \
)
#define W_REG(osh, r, v) do { \
switch (sizeof(*(r))) { \
case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \
case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \
case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
} \
} while (0)
#else /* IL_BIGENDIAN */
#define R_REG(osh, r) ({ \
__typeof(*(r)) __osl_v; \
switch (sizeof(*(r))) { \
case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \
case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \
case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \
} \
__osl_v; \
})
#define W_REG(osh, r, v) do { \
switch (sizeof(*(r))) { \
case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \
case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \
case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
} \
} while (0)
#endif /* IL_BIGENDIAN */
/* dereference an address that may cause a bus exception */
#define BUSPROBE(val, addr) get_dbe((val), (addr))
#include <asm/paccess.h>
/* map/unmap physical to virtual I/O */
#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
#define REG_UNMAP(va) iounmap((void *)(va))
/* shared (dma-able) memory access macros */
#define R_SM(r) *(r)
#define W_SM(r, v) (*(r) = (v))
#define BZERO_SM(r, len) memset((r), '\0', (len))
#define MALLOC(osh, size) kmalloc((size), GFP_ATOMIC)
#define MFREE(osh, addr, size) kfree((addr))
#define MALLOCED(osh) (0)
#define osl_delay OSL_DELAY
static inline void OSL_DELAY(uint usec)
{
uint d;
while (usec > 0) {
d = MIN(usec, 1000);
udelay(d);
usec -= d;
}
}
static inline void
bcm_mdelay(uint ms)
{
uint i;
for (i = 0; i < ms; i++) {
OSL_DELAY(1000);
}
}
#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size)
#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size)
#define OSL_PCI_READ_CONFIG(osh, offset, size) \
osl_pci_read_config((osh), (offset), (size))
static inline uint32
osl_pci_read_config(osl_t *osh, uint offset, uint size)
{
uint val;
uint retry = PCI_CFG_RETRY;
do {
pci_read_config_dword(osh->pdev, offset, &val);
if (val != 0xffffffff)
break;
} while (retry--);
return (val);
}
#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
osl_pci_write_config((osh), (offset), (size), (val))
static inline void
osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
{
uint retry = PCI_CFG_RETRY;
do {
pci_write_config_dword(osh->pdev, offset, val);
if (offset != PCI_BAR0_WIN)
break;
if (osl_pci_read_config(osh, offset, size) == val)
break;
} while (retry--);
}
/* return bus # for the pci device pointed by osh->pdev */
#define OSL_PCI_BUS(osh) osl_pci_bus(osh)
static inline uint
osl_pci_bus(osl_t *osh)
{
return ((struct pci_dev *)osh->pdev)->bus->number;
}
/* return slot # for the pci device pointed by osh->pdev */
#define OSL_PCI_SLOT(osh) osl_pci_slot(osh)
static inline uint
osl_pci_slot(osl_t *osh)
{
return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn);
}
#endif

View file

@ -0,0 +1,495 @@
/*
* pcicfg.h: PCI configuration constants and structures.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: pcicfg.h,v 1.1.1.11 2006/04/08 06:13:40 honor Exp $
*/
#ifndef _h_pcicfg_
#define _h_pcicfg_
/* The following inside ifndef's so we don't collide with NTDDK.H */
#ifndef PCI_MAX_BUS
#define PCI_MAX_BUS 0x100
#endif
#ifndef PCI_MAX_DEVICES
#define PCI_MAX_DEVICES 0x20
#endif
#ifndef PCI_MAX_FUNCTION
#define PCI_MAX_FUNCTION 0x8
#endif
#ifndef PCI_INVALID_VENDORID
#define PCI_INVALID_VENDORID 0xffff
#endif
#ifndef PCI_INVALID_DEVICEID
#define PCI_INVALID_DEVICEID 0xffff
#endif
/* Convert between bus-slot-function-register and config addresses */
#define PCICFG_BUS_SHIFT 16 /* Bus shift */
#define PCICFG_SLOT_SHIFT 11 /* Slot shift */
#define PCICFG_FUN_SHIFT 8 /* Function shift */
#define PCICFG_OFF_SHIFT 0 /* Register shift */
#define PCICFG_BUS_MASK 0xff /* Bus mask */
#define PCICFG_SLOT_MASK 0x1f /* Slot mask */
#define PCICFG_FUN_MASK 7 /* Function mask */
#define PCICFG_OFF_MASK 0xff /* Bus mask */
#define PCI_CONFIG_ADDR(b, s, f, o) \
((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \
| (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \
| (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \
| (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT))
#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK)
#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK)
#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK)
#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK)
/* PCIE Config space accessing MACROS */
#define PCIECFG_BUS_SHIFT 24 /* Bus shift */
#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */
#define PCIECFG_FUN_SHIFT 16 /* Function shift */
#define PCIECFG_OFF_SHIFT 0 /* Register shift */
#define PCIECFG_BUS_MASK 0xff /* Bus mask */
#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */
#define PCIECFG_FUN_MASK 7 /* Function mask */
#define PCIECFG_OFF_MASK 0x3ff /* Register mask */
#define PCIE_CONFIG_ADDR(b, s, f, o) \
((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \
| (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \
| (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \
| (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT))
#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK)
#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK)
#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK)
#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK)
/* The actual config space */
#define PCI_BAR_MAX 6
#define PCI_ROM_BAR 8
#define PCR_RSVDA_MAX 2
/* Bits in PCI bars' flags */
#define PCIBAR_FLAGS 0xf
#define PCIBAR_IO 0x1
#define PCIBAR_MEM1M 0x2
#define PCIBAR_MEM64 0x4
#define PCIBAR_PREFETCH 0x8
#define PCIBAR_MEM32_MASK 0xFFFFFF80
/* pci config status reg has a bit to indicate that capability ptr is present */
#define PCI_CAPPTR_PRESENT 0x0010
typedef struct _pci_config_regs {
unsigned short vendor;
unsigned short device;
unsigned short command;
unsigned short status;
unsigned char rev_id;
unsigned char prog_if;
unsigned char sub_class;
unsigned char base_class;
unsigned char cache_line_size;
unsigned char latency_timer;
unsigned char header_type;
unsigned char bist;
unsigned long base[PCI_BAR_MAX];
unsigned long cardbus_cis;
unsigned short subsys_vendor;
unsigned short subsys_id;
unsigned long baserom;
unsigned long rsvd_a[PCR_RSVDA_MAX];
unsigned char int_line;
unsigned char int_pin;
unsigned char min_gnt;
unsigned char max_lat;
unsigned char dev_dep[192];
} pci_config_regs;
#define SZPCR (sizeof (pci_config_regs))
#define MINSZPCR 64 /* offsetof (dev_dep[0] */
/* A structure for the config registers is nice, but in most
* systems the config space is not memory mapped, so we need
* filed offsetts. :-(
*/
#define PCI_CFG_VID 0
#define PCI_CFG_DID 2
#define PCI_CFG_CMD 4
#define PCI_CFG_STAT 6
#define PCI_CFG_REV 8
#define PCI_CFG_PROGIF 9
#define PCI_CFG_SUBCL 0xa
#define PCI_CFG_BASECL 0xb
#define PCI_CFG_CLSZ 0xc
#define PCI_CFG_LATTIM 0xd
#define PCI_CFG_HDR 0xe
#define PCI_CFG_BIST 0xf
#define PCI_CFG_BAR0 0x10
#define PCI_CFG_BAR1 0x14
#define PCI_CFG_BAR2 0x18
#define PCI_CFG_BAR3 0x1c
#define PCI_CFG_BAR4 0x20
#define PCI_CFG_BAR5 0x24
#define PCI_CFG_CIS 0x28
#define PCI_CFG_SVID 0x2c
#define PCI_CFG_SSID 0x2e
#define PCI_CFG_ROMBAR 0x30
#define PCI_CFG_CAPPTR 0x34
#define PCI_CFG_INT 0x3c
#define PCI_CFG_PIN 0x3d
#define PCI_CFG_MINGNT 0x3e
#define PCI_CFG_MAXLAT 0x3f
#ifdef __NetBSD__
#undef PCI_CLASS_DISPLAY
#undef PCI_CLASS_MEMORY
#undef PCI_CLASS_BRIDGE
#undef PCI_CLASS_INPUT
#undef PCI_CLASS_DOCK
#endif /* __NetBSD__ */
/* Classes and subclasses */
typedef enum {
PCI_CLASS_OLD = 0,
PCI_CLASS_DASDI,
PCI_CLASS_NET,
PCI_CLASS_DISPLAY,
PCI_CLASS_MMEDIA,
PCI_CLASS_MEMORY,
PCI_CLASS_BRIDGE,
PCI_CLASS_COMM,
PCI_CLASS_BASE,
PCI_CLASS_INPUT,
PCI_CLASS_DOCK,
PCI_CLASS_CPU,
PCI_CLASS_SERIAL,
PCI_CLASS_INTELLIGENT = 0xe,
PCI_CLASS_SATELLITE,
PCI_CLASS_CRYPT,
PCI_CLASS_DSP,
PCI_CLASS_XOR = 0xfe
} pci_classes;
typedef enum {
PCI_DASDI_SCSI,
PCI_DASDI_IDE,
PCI_DASDI_FLOPPY,
PCI_DASDI_IPI,
PCI_DASDI_RAID,
PCI_DASDI_OTHER = 0x80
} pci_dasdi_subclasses;
typedef enum {
PCI_NET_ETHER,
PCI_NET_TOKEN,
PCI_NET_FDDI,
PCI_NET_ATM,
PCI_NET_OTHER = 0x80
} pci_net_subclasses;
typedef enum {
PCI_DISPLAY_VGA,
PCI_DISPLAY_XGA,
PCI_DISPLAY_3D,
PCI_DISPLAY_OTHER = 0x80
} pci_display_subclasses;
typedef enum {
PCI_MMEDIA_VIDEO,
PCI_MMEDIA_AUDIO,
PCI_MMEDIA_PHONE,
PCI_MEDIA_OTHER = 0x80
} pci_mmedia_subclasses;
typedef enum {
PCI_MEMORY_RAM,
PCI_MEMORY_FLASH,
PCI_MEMORY_OTHER = 0x80
} pci_memory_subclasses;
typedef enum {
PCI_BRIDGE_HOST,
PCI_BRIDGE_ISA,
PCI_BRIDGE_EISA,
PCI_BRIDGE_MC,
PCI_BRIDGE_PCI,
PCI_BRIDGE_PCMCIA,
PCI_BRIDGE_NUBUS,
PCI_BRIDGE_CARDBUS,
PCI_BRIDGE_RACEWAY,
PCI_BRIDGE_OTHER = 0x80
} pci_bridge_subclasses;
typedef enum {
PCI_COMM_UART,
PCI_COMM_PARALLEL,
PCI_COMM_MULTIUART,
PCI_COMM_MODEM,
PCI_COMM_OTHER = 0x80
} pci_comm_subclasses;
typedef enum {
PCI_BASE_PIC,
PCI_BASE_DMA,
PCI_BASE_TIMER,
PCI_BASE_RTC,
PCI_BASE_PCI_HOTPLUG,
PCI_BASE_OTHER = 0x80
} pci_base_subclasses;
typedef enum {
PCI_INPUT_KBD,
PCI_INPUT_PEN,
PCI_INPUT_MOUSE,
PCI_INPUT_SCANNER,
PCI_INPUT_GAMEPORT,
PCI_INPUT_OTHER = 0x80
} pci_input_subclasses;
typedef enum {
PCI_DOCK_GENERIC,
PCI_DOCK_OTHER = 0x80
} pci_dock_subclasses;
typedef enum {
PCI_CPU_386,
PCI_CPU_486,
PCI_CPU_PENTIUM,
PCI_CPU_ALPHA = 0x10,
PCI_CPU_POWERPC = 0x20,
PCI_CPU_MIPS = 0x30,
PCI_CPU_COPROC = 0x40,
PCI_CPU_OTHER = 0x80
} pci_cpu_subclasses;
typedef enum {
PCI_SERIAL_IEEE1394,
PCI_SERIAL_ACCESS,
PCI_SERIAL_SSA,
PCI_SERIAL_USB,
PCI_SERIAL_FIBER,
PCI_SERIAL_SMBUS,
PCI_SERIAL_OTHER = 0x80
} pci_serial_subclasses;
typedef enum {
PCI_INTELLIGENT_I2O
} pci_intelligent_subclasses;
typedef enum {
PCI_SATELLITE_TV,
PCI_SATELLITE_AUDIO,
PCI_SATELLITE_VOICE,
PCI_SATELLITE_DATA,
PCI_SATELLITE_OTHER = 0x80
} pci_satellite_subclasses;
typedef enum {
PCI_CRYPT_NETWORK,
PCI_CRYPT_ENTERTAINMENT,
PCI_CRYPT_OTHER = 0x80
} pci_crypt_subclasses;
typedef enum {
PCI_DSP_DPIO,
PCI_DSP_OTHER = 0x80
} pci_dsp_subclasses;
typedef enum {
PCI_XOR_QDMA,
PCI_XOR_OTHER = 0x80
} pci_xor_subclasses;
/* Header types */
typedef enum {
PCI_HEADER_NORMAL,
PCI_HEADER_BRIDGE,
PCI_HEADER_CARDBUS
} pci_header_types;
/* Overlay for a PCI-to-PCI bridge */
#define PPB_RSVDA_MAX 2
#define PPB_RSVDD_MAX 8
typedef struct _ppb_config_regs {
unsigned short vendor;
unsigned short device;
unsigned short command;
unsigned short status;
unsigned char rev_id;
unsigned char prog_if;
unsigned char sub_class;
unsigned char base_class;
unsigned char cache_line_size;
unsigned char latency_timer;
unsigned char header_type;
unsigned char bist;
unsigned long rsvd_a[PPB_RSVDA_MAX];
unsigned char prim_bus;
unsigned char sec_bus;
unsigned char sub_bus;
unsigned char sec_lat;
unsigned char io_base;
unsigned char io_lim;
unsigned short sec_status;
unsigned short mem_base;
unsigned short mem_lim;
unsigned short pf_mem_base;
unsigned short pf_mem_lim;
unsigned long pf_mem_base_hi;
unsigned long pf_mem_lim_hi;
unsigned short io_base_hi;
unsigned short io_lim_hi;
unsigned short subsys_vendor;
unsigned short subsys_id;
unsigned long rsvd_b;
unsigned char rsvd_c;
unsigned char int_pin;
unsigned short bridge_ctrl;
unsigned char chip_ctrl;
unsigned char diag_ctrl;
unsigned short arb_ctrl;
unsigned long rsvd_d[PPB_RSVDD_MAX];
unsigned char dev_dep[192];
} ppb_config_regs;
/* PCI CAPABILITY DEFINES */
#define PCI_CAP_POWERMGMTCAP_ID 0x01
#define PCI_CAP_MSICAP_ID 0x05
#define PCI_CAP_PCIECAP_ID 0x10
/* Data structure to define the Message Signalled Interrupt facility
* Valid for PCI and PCIE configurations
*/
typedef struct _pciconfig_cap_msi {
unsigned char capID;
unsigned char nextptr;
unsigned short msgctrl;
unsigned int msgaddr;
} pciconfig_cap_msi;
/* Data structure to define the Power managment facility
* Valid for PCI and PCIE configurations
*/
typedef struct _pciconfig_cap_pwrmgmt {
unsigned char capID;
unsigned char nextptr;
unsigned short pme_cap;
unsigned short pme_sts_ctrl;
unsigned char pme_bridge_ext;
unsigned char data;
} pciconfig_cap_pwrmgmt;
/* Data structure to define the PCIE capability */
typedef struct _pciconfig_cap_pcie {
unsigned char capID;
unsigned char nextptr;
unsigned short pcie_cap;
unsigned int dev_cap;
unsigned short dev_ctrl;
unsigned short dev_status;
unsigned int link_cap;
unsigned short link_ctrl;
unsigned short link_status;
} pciconfig_cap_pcie;
/* PCIE Enhanced CAPABILITY DEFINES */
#define PCIE_EXTCFG_OFFSET 0x100
#define PCIE_ADVERRREP_CAPID 0x0001
#define PCIE_VC_CAPID 0x0002
#define PCIE_DEVSNUM_CAPID 0x0003
#define PCIE_PWRBUDGET_CAPID 0x0004
/* Header to define the PCIE specific capabilities in the extended config space */
typedef struct _pcie_enhanced_caphdr {
unsigned short capID;
unsigned short cap_ver : 4;
unsigned short next_ptr : 12;
} pcie_enhanced_caphdr;
/* Everything below is BRCM HND proprietary */
/* Brcm PCI configuration registers */
#define cap_list rsvd_a[0]
#define bar0_window dev_dep[0x80 - 0x40]
#define bar1_window dev_dep[0x84 - 0x40]
#define sprom_control dev_dep[0x88 - 0x40]
#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */
#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */
#define PCI_SPROM_CONTROL 0x88 /* sprom property control */
#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */
#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */
#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */
#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */
#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */
#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address */
#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */
#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */
#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */
#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */
#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */
#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */
#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the
* 8KB window, so their address is the "regular"
* address plus 4K
*/
#define PCI_BAR0_WINSZ 8192 /* bar0 window size */
/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */
#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */
#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */
/* PCI_INT_STATUS */
#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */
/* PCI_INT_MASK */
#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */
#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */
#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */
/* PCI_SPROM_CONTROL */
#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */
#define SPROM_LOCKED 0x08 /* SPROM Locked */
#define SPROM_BLANK 0x04 /* indicating a blank SPROM */
#define SPROM_WRITEEN 0x10 /* SPROM write enable */
#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */
#define SPROM_OTPIN_USE 0x80 /* device OTP In use */
#define SPROM_SIZE 256 /* sprom size in 16-bit */
#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */
/* PCI_CFG_CMD_STAT */
#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */
#endif /* _h_pcicfg_ */

View file

@ -0,0 +1,516 @@
/*
* SiliconBackplane Chipcommon core hardware definitions.
*
* The chipcommon core provides chip identification, SB control,
* jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
* gpio interface, extbus, and support for serial and parallel flashes.
*
* $Id: sbchipc.h,v 1.1.1.14 2006/04/15 01:29:08 michael Exp $
* Copyright 2006, Broadcom Corporation
* 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.
*
*/
#ifndef _SBCHIPC_H
#define _SBCHIPC_H
#ifndef _LANGUAGE_ASSEMBLY
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif /* PAD */
typedef volatile struct {
uint32 chipid; /* 0x0 */
uint32 capabilities;
uint32 corecontrol; /* corerev >= 1 */
uint32 bist;
/* OTP */
uint32 otpstatus; /* 0x10, corerev >= 10 */
uint32 otpcontrol;
uint32 otpprog;
uint32 PAD;
/* Interrupt control */
uint32 intstatus; /* 0x20 */
uint32 intmask;
uint32 chipcontrol; /* 0x28, rev >= 11 */
uint32 chipstatus; /* 0x2c, rev >= 11 */
/* Jtag Master */
uint32 jtagcmd; /* 0x30, rev >= 10 */
uint32 jtagir;
uint32 jtagdr;
uint32 jtagctrl;
/* serial flash interface registers */
uint32 flashcontrol; /* 0x40 */
uint32 flashaddress;
uint32 flashdata;
uint32 PAD[1];
/* Silicon backplane configuration broadcast control */
uint32 broadcastaddress; /* 0x50 */
uint32 broadcastdata;
uint32 PAD[2];
/* gpio - cleared only by power-on-reset */
uint32 gpioin; /* 0x60 */
uint32 gpioout;
uint32 gpioouten;
uint32 gpiocontrol;
uint32 gpiointpolarity;
uint32 gpiointmask;
uint32 PAD[2];
/* Watchdog timer */
uint32 watchdog; /* 0x80 */
uint32 PAD[1];
/* GPIO based LED powersave registers corerev >= 16 */
uint32 gpiotimerval; /* 0x88 */
uint32 gpiotimeroutmask;
/* clock control */
uint32 clockcontrol_n; /* 0x90 */
uint32 clockcontrol_sb; /* aka m0 */
uint32 clockcontrol_pci; /* aka m1 */
uint32 clockcontrol_m2; /* mii/uart/mipsref */
uint32 clockcontrol_m3; /* cpu */
uint32 clkdiv; /* corerev >= 3 */
uint32 PAD[2];
/* pll delay registers (corerev >= 4) */
uint32 pll_on_delay; /* 0xb0 */
uint32 fref_sel_delay;
uint32 slow_clk_ctl; /* 5 < corerev < 10 */
uint32 PAD[1];
/* Instaclock registers (corerev >= 10) */
uint32 system_clk_ctl; /* 0xc0 */
uint32 clkstatestretch;
uint32 PAD[14];
/* ExtBus control registers (corerev >= 3) */
uint32 pcmcia_config; /* 0x100 */
uint32 pcmcia_memwait;
uint32 pcmcia_attrwait;
uint32 pcmcia_iowait;
uint32 ide_config;
uint32 ide_memwait;
uint32 ide_attrwait;
uint32 ide_iowait;
uint32 prog_config;
uint32 prog_waitcount;
uint32 flash_config;
uint32 flash_waitcount;
uint32 PAD[44];
/* Clock control and hardware workarounds */
uint32 clk_ctl_st;
uint32 hw_war;
uint32 PAD[70];
/* uarts */
uint8 uart0data; /* 0x300 */
uint8 uart0imr;
uint8 uart0fcr;
uint8 uart0lcr;
uint8 uart0mcr;
uint8 uart0lsr;
uint8 uart0msr;
uint8 uart0scratch;
uint8 PAD[248]; /* corerev >= 1 */
uint8 uart1data; /* 0x400 */
uint8 uart1imr;
uint8 uart1fcr;
uint8 uart1lcr;
uint8 uart1mcr;
uint8 uart1lsr;
uint8 uart1msr;
uint8 uart1scratch;
} chipcregs_t;
#endif /* _LANGUAGE_ASSEMBLY */
#define CC_CHIPID 0
#define CC_CAPABILITIES 4
#define CC_JTAGCMD 0x30
#define CC_JTAGIR 0x34
#define CC_JTAGDR 0x38
#define CC_JTAGCTRL 0x3c
#define CC_WATCHDOG 0x80
#define CC_CLKC_N 0x90
#define CC_CLKC_M0 0x94
#define CC_CLKC_M1 0x98
#define CC_CLKC_M2 0x9c
#define CC_CLKC_M3 0xa0
#define CC_CLKDIV 0xa4
#define CC_SYS_CLK_CTL 0xc0
#define CC_OTP 0x800
/* chipid */
#define CID_ID_MASK 0x0000ffff /* Chip Id mask */
#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */
#define CID_REV_SHIFT 16 /* Chip Revision shift */
#define CID_PKG_MASK 0x00f00000 /* Package Option mask */
#define CID_PKG_SHIFT 20 /* Package Option shift */
#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */
#define CID_CC_SHIFT 24
/* capabilities */
#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */
#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */
#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */
#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */
#define CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */
#define CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */
#define CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */
#define CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */
#define CAP_FLASH_MASK 0x00000700 /* Type of flash */
#define CAP_PLL_MASK 0x00038000 /* Type of PLL */
#define CAP_PWR_CTL 0x00040000 /* Power control */
#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */
#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */
#define CAP_OTPSIZE_BASE 5 /* OTP Size base */
#define CAP_JTAGP 0x00400000 /* JTAG Master Present */
#define CAP_ROM 0x00800000 /* Internal boot rom active */
#define CAP_BKPLN64 0x08000000 /* 64-bit backplane */
/* PLL type */
#define PLL_NONE 0x00000000
#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */
#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */
#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */
#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */
#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */
#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */
#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */
/* corecontrol */
#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */
#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
/* chipcontrol */
#define CHIPCTRL_4321A0_DEFAULT 0x3a4
#define CHIPCTRL_4321A1_DEFAULT 0x0a4
/* Fields in the otpstatus register */
#define OTPS_PROGFAIL 0x80000000
#define OTPS_PROTECT 0x00000007
#define OTPS_HW_PROTECT 0x00000001
#define OTPS_SW_PROTECT 0x00000002
#define OTPS_CID_PROTECT 0x00000004
/* Fields in the otpcontrol register */
#define OTPC_RECWAIT 0xff000000
#define OTPC_PROGWAIT 0x00ffff00
#define OTPC_PRW_SHIFT 8
#define OTPC_MAXFAIL 0x00000038
#define OTPC_VSEL 0x00000006
#define OTPC_SELVL 0x00000001
/* Fields in otpprog */
#define OTPP_COL_MASK 0x000000ff
#define OTPP_ROW_MASK 0x0000ff00
#define OTPP_ROW_SHIFT 8
#define OTPP_READERR 0x10000000
#define OTPP_VALUE 0x20000000
#define OTPP_VALUE_SHIFT 29
#define OTPP_READ 0x40000000
#define OTPP_START 0x80000000
#define OTPP_BUSY 0x80000000
/* jtagcmd */
#define JCMD_START 0x80000000
#define JCMD_BUSY 0x80000000
#define JCMD_PAUSE 0x40000000
#define JCMD0_ACC_MASK 0x0000f000
#define JCMD0_ACC_IRDR 0x00000000
#define JCMD0_ACC_DR 0x00001000
#define JCMD0_ACC_IR 0x00002000
#define JCMD0_ACC_RESET 0x00003000
#define JCMD0_ACC_IRPDR 0x00004000
#define JCMD0_ACC_PDR 0x00005000
#define JCMD0_IRW_MASK 0x00000f00
#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */
#define JCMD_ACC_IRDR 0x00000000
#define JCMD_ACC_DR 0x00010000
#define JCMD_ACC_IR 0x00020000
#define JCMD_ACC_RESET 0x00030000
#define JCMD_ACC_IRPDR 0x00040000
#define JCMD_ACC_PDR 0x00050000
#define JCMD_IRW_MASK 0x00001f00
#define JCMD_IRW_SHIFT 8
#define JCMD_DRW_MASK 0x0000003f
/* jtagctrl */
#define JCTRL_FORCE_CLK 4 /* Force clock */
#define JCTRL_EXT_EN 2 /* Enable external targets */
#define JCTRL_EN 1 /* Enable Jtag master */
/* Fields in clkdiv */
#define CLKD_SFLASH 0x0f000000
#define CLKD_SFLASH_SHIFT 24
#define CLKD_OTP 0x000f0000
#define CLKD_OTP_SHIFT 16
#define CLKD_JTAG 0x00000f00
#define CLKD_JTAG_SHIFT 8
#define CLKD_UART 0x000000ff
/* intstatus/intmask */
#define CI_GPIO 0x00000001 /* gpio intr */
#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */
#define CI_WDRESET 0x80000000 /* watchdog reset occurred */
/* slow_clk_ctl */
#define SCC_SS_MASK 0x00000007 /* slow clock source mask */
#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */
#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */
#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */
#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled,
* 0: LPO is enabled
*/
#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock,
* 0: power logic control
*/
#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors
* PLL clock disable requests from core
*/
#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't
* disable crystal when appropriate
*/
#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
#define SCC_CD_SHIFT 16
/* system_clk_ctl */
#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */
#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */
#define SYCC_FP 0x00000004 /* ForcePLLOn */
#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */
#define SYCC_HR 0x00000010 /* Force HT */
#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */
#define SYCC_CD_SHIFT 16
/* gpiotimerval */
#define GPIO_ONTIME_SHIFT 16
/* clockcontrol_n */
#define CN_N1_MASK 0x3f /* n1 control */
#define CN_N2_MASK 0x3f00 /* n2 control */
#define CN_N2_SHIFT 8
#define CN_PLLC_MASK 0xf0000 /* pll control */
#define CN_PLLC_SHIFT 16
/* clockcontrol_sb/pci/uart */
#define CC_M1_MASK 0x3f /* m1 control */
#define CC_M2_MASK 0x3f00 /* m2 control */
#define CC_M2_SHIFT 8
#define CC_M3_MASK 0x3f0000 /* m3 control */
#define CC_M3_SHIFT 16
#define CC_MC_MASK 0x1f000000 /* mux control */
#define CC_MC_SHIFT 24
/* N3M Clock control magic field values */
#define CC_F6_2 0x02 /* A factor of 2 in */
#define CC_F6_3 0x03 /* 6-bit fields like */
#define CC_F6_4 0x05 /* N1, M1 or M3 */
#define CC_F6_5 0x09
#define CC_F6_6 0x11
#define CC_F6_7 0x21
#define CC_F5_BIAS 5 /* 5-bit fields get this added */
#define CC_MC_BYPASS 0x08
#define CC_MC_M1 0x04
#define CC_MC_M1M2 0x02
#define CC_MC_M1M2M3 0x01
#define CC_MC_M1M3 0x11
/* Type 2 Clock control magic field values */
#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */
#define CC_T2M2_BIAS 3 /* m2 bias */
#define CC_T2MC_M1BYP 1
#define CC_T2MC_M2BYP 2
#define CC_T2MC_M3BYP 4
/* Type 6 Clock control magic field values */
#define CC_T6_MMASK 1 /* bits of interest in m */
#define CC_T6_M0 120000000 /* sb clock for m = 0 */
#define CC_T6_M1 100000000 /* sb clock for m = 1 */
#define SB2MIPS_T6(sb) (2 * (sb))
/* Common clock base */
#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */
#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */
/* Clock control values for 200Mhz in 5350 */
#define CLKC_5350_N 0x0311
#define CLKC_5350_M 0x04020009
/* Flash types in the chipcommon capabilities register */
#define FLASH_NONE 0x000 /* No flash */
#define SFLASH_ST 0x100 /* ST serial flash */
#define SFLASH_AT 0x200 /* Atmel serial flash */
#define PFLASH 0x700 /* Parallel flash */
/* Bits in the ExtBus config registers */
#define CC_CFG_EN 0x0001 /* Enable */
#define CC_CFG_EM_MASK 0x000e /* Extif Mode */
#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */
#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */
#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */
#define CC_CFG_EM_IDE 0x0006 /* IDE */
#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */
#define CC_CFG_CE 0x0080 /* Sync: Clock enable */
#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */
/* ExtBus address space */
#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */
#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */
#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */
#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */
#define CC_EB_IDE 0x1a800000 /* IDE memory base */
#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */
#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */
#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */
#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */
/* Start/busy bit in flashcontrol */
#define SFLASH_OPCODE 0x000000ff
#define SFLASH_ACTION 0x00000700
#define SFLASH_START 0x80000000
#define SFLASH_BUSY SFLASH_START
/* flashcontrol action codes */
#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */
#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */
#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 address bytes */
#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addres & 1 data bytes */
#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addres & 4 data bytes */
#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addres, 4 don't care & 4 data bytes */
#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addres, 1 don't care & 4 data bytes */
/* flashcontrol action+opcodes for ST flashes */
#define SFLASH_ST_WREN 0x0006 /* Write Enable */
#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */
#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */
#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */
#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */
#define SFLASH_ST_PP 0x0302 /* Page Program */
#define SFLASH_ST_SE 0x02d8 /* Sector Erase */
#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */
#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */
#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */
/* Status register bits for ST flashes */
#define SFLASH_ST_WIP 0x01 /* Write In Progress */
#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */
#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */
#define SFLASH_ST_BP_SHIFT 2
#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */
/* flashcontrol action+opcodes for Atmel flashes */
#define SFLASH_AT_READ 0x07e8
#define SFLASH_AT_PAGE_READ 0x07d2
#define SFLASH_AT_BUF1_READ
#define SFLASH_AT_BUF2_READ
#define SFLASH_AT_STATUS 0x01d7
#define SFLASH_AT_BUF1_WRITE 0x0384
#define SFLASH_AT_BUF2_WRITE 0x0387
#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283
#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286
#define SFLASH_AT_BUF1_PROGRAM 0x0288
#define SFLASH_AT_BUF2_PROGRAM 0x0289
#define SFLASH_AT_PAGE_ERASE 0x0281
#define SFLASH_AT_BLOCK_ERASE 0x0250
#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382
#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385
#define SFLASH_AT_BUF1_LOAD 0x0253
#define SFLASH_AT_BUF2_LOAD 0x0255
#define SFLASH_AT_BUF1_COMPARE 0x0260
#define SFLASH_AT_BUF2_COMPARE 0x0261
#define SFLASH_AT_BUF1_REPROGRAM 0x0258
#define SFLASH_AT_BUF2_REPROGRAM 0x0259
/* Status register bits for Atmel flashes */
#define SFLASH_AT_READY 0x80
#define SFLASH_AT_MISMATCH 0x40
#define SFLASH_AT_ID_MASK 0x38
#define SFLASH_AT_ID_SHIFT 3
/* OTP regions */
#define OTP_HW_REGION OTPS_HW_PROTECT
#define OTP_SW_REGION OTPS_SW_PROTECT
#define OTP_CID_REGION OTPS_CID_PROTECT
/* OTP regions (Byte offsets from otp size) */
#define OTP_SWLIM_OFF (-8)
#define OTP_CIDBASE_OFF 0
#define OTP_CIDLIM_OFF 8
/* Predefined OTP words (Word offset from otp size) */
#define OTP_BOUNDARY_OFF (-4)
#define OTP_HWSIGN_OFF (-3)
#define OTP_SWSIGN_OFF (-2)
#define OTP_CIDSIGN_OFF (-1)
#define OTP_CID_OFF 0
#define OTP_PKG_OFF 1
#define OTP_FID_OFF 2
#define OTP_RSV_OFF 3
#define OTP_LIM_OFF 4
#define OTP_SIGNATURE 0x578a
#define OTP_MAGIC 0x4e56
/*
* These are the UART port assignments, expressed as offsets from the base
* register. These assignments should hold for any serial port based on
* a 8250, 16450, or 16550(A).
*/
#define UART_RX 0 /* In: Receive buffer (DLAB=0) */
#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */
#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */
#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */
#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */
#define UART_IIR 2 /* In: Interrupt Identity Register */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_LSR 5 /* In: Line Status Register */
#define UART_MSR 6 /* In: Modem Status Register */
#define UART_SCR 7 /* I/O: Scratch Register */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_RXRDY 0x01 /* Receiver ready */
#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */
/* Interrupt Enable Register (IER) bits */
#define UART_IER_EDSSI 8 /* enable modem status interrupt */
#define UART_IER_ELSI 4 /* enable receiver line status interrupt */
#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */
#define UART_IER_ERBFI 1 /* enable data available interrupt */
#endif /* _SBCHIPC_H */

View file

@ -0,0 +1,369 @@
/*
* Broadcom SiliconBackplane hardware register definitions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbconfig.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _SBCONFIG_H
#define _SBCONFIG_H
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif
/*
* SiliconBackplane Address Map.
* All regions may not exist on all chips.
*/
#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */
#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */
#define SB_PCI_MEM_SZ (64 * 1024 * 1024)
#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */
#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */
#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */
#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */
#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */
#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */
#define SB_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */
#define SB_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */
#define SB_ROM 0x20000000 /* ARM ROM */
#define SB_SRAM2 0x80000000 /* ARM SRAM Region 2 */
#define SB_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */
#define SB_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */
#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */
#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */
#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2
* (2 ZettaBytes), low 32 bits
*/
#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2
* (2 ZettaBytes), high 32 bits
*/
#define SB_EUART (SB_EXTIF_BASE + 0x00800000)
#define SB_LED (SB_EXTIF_BASE + 0x00900000)
/* enumeration space related defs */
#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */
#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE)
#define SB_MAXFUNCS 4 /* max. # functions per core */
#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */
#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */
/* mips address */
#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
/*
* Sonics Configuration Space Registers.
*/
#define SBIPSFLAG 0x08
#define SBTPSFLAG 0x18
#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */
#define SBTMERRLOG 0x50 /* sonics >= 2.3 */
#define SBADMATCH3 0x60
#define SBADMATCH2 0x68
#define SBADMATCH1 0x70
#define SBIMSTATE 0x90
#define SBINTVEC 0x94
#define SBTMSTATELOW 0x98
#define SBTMSTATEHIGH 0x9c
#define SBBWA0 0xa0
#define SBIMCONFIGLOW 0xa8
#define SBIMCONFIGHIGH 0xac
#define SBADMATCH0 0xb0
#define SBTMCONFIGLOW 0xb8
#define SBTMCONFIGHIGH 0xbc
#define SBBCONFIG 0xc0
#define SBBSTATE 0xc8
#define SBACTCNFG 0xd8
#define SBFLAGST 0xe8
#define SBIDLOW 0xf8
#define SBIDHIGH 0xfc
/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have
* a few registers *below* that line. I think it would be very confusing to try
* and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here,
*/
#define SBIMERRLOGA 0xea8
#define SBIMERRLOG 0xeb0
#define SBTMPORTCONNID0 0xed8
#define SBTMPORTLOCK0 0xef8
#ifndef _LANGUAGE_ASSEMBLY
typedef volatile struct _sbconfig {
uint32 PAD[2];
uint32 sbipsflag; /* initiator port ocp slave flag */
uint32 PAD[3];
uint32 sbtpsflag; /* target port ocp slave flag */
uint32 PAD[11];
uint32 sbtmerrloga; /* (sonics >= 2.3) */
uint32 PAD;
uint32 sbtmerrlog; /* (sonics >= 2.3) */
uint32 PAD[3];
uint32 sbadmatch3; /* address match3 */
uint32 PAD;
uint32 sbadmatch2; /* address match2 */
uint32 PAD;
uint32 sbadmatch1; /* address match1 */
uint32 PAD[7];
uint32 sbimstate; /* initiator agent state */
uint32 sbintvec; /* interrupt mask */
uint32 sbtmstatelow; /* target state */
uint32 sbtmstatehigh; /* target state */
uint32 sbbwa0; /* bandwidth allocation table0 */
uint32 PAD;
uint32 sbimconfiglow; /* initiator configuration */
uint32 sbimconfighigh; /* initiator configuration */
uint32 sbadmatch0; /* address match0 */
uint32 PAD;
uint32 sbtmconfiglow; /* target configuration */
uint32 sbtmconfighigh; /* target configuration */
uint32 sbbconfig; /* broadcast configuration */
uint32 PAD;
uint32 sbbstate; /* broadcast state */
uint32 PAD[3];
uint32 sbactcnfg; /* activate configuration */
uint32 PAD[3];
uint32 sbflagst; /* current sbflags */
uint32 PAD[3];
uint32 sbidlow; /* identification */
uint32 sbidhigh; /* identification */
} sbconfig_t;
#endif /* _LANGUAGE_ASSEMBLY */
/* sbipsflag */
#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */
#define SBIPS_INT1_SHIFT 0
#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */
#define SBIPS_INT2_SHIFT 8
#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */
#define SBIPS_INT3_SHIFT 16
#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */
#define SBIPS_INT4_SHIFT 24
/* sbtpsflag */
#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */
#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */
/* sbtmerrlog */
#define SBTMEL_CM 0x00000007 /* command */
#define SBTMEL_CI 0x0000ff00 /* connection id */
#define SBTMEL_EC 0x0f000000 /* error code */
#define SBTMEL_ME 0x80000000 /* multiple error */
/* sbimstate */
#define SBIM_PC 0xf /* pipecount */
#define SBIM_AP_MASK 0x30 /* arbitration policy */
#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */
#define SBIM_AP_TS 0x10 /* use timesliaces only */
#define SBIM_AP_TK 0x20 /* use token only */
#define SBIM_AP_RSV 0x30 /* reserved */
#define SBIM_IBE 0x20000 /* inbanderror */
#define SBIM_TO 0x40000 /* timeout */
#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */
#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */
/* sbtmstatelow */
#define SBTML_RESET 0x1 /* reset */
#define SBTML_REJ_MASK 0x6 /* reject */
#define SBTML_REJ_SHIFT 1
#define SBTML_CLK 0x10000 /* clock enable */
#define SBTML_FGC 0x20000 /* force gated clocks on */
#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */
#define SBTML_PE 0x40000000 /* pme enable */
#define SBTML_BE 0x80000000 /* bist enable */
/* sbtmstatehigh */
#define SBTMH_SERR 0x1 /* serror */
#define SBTMH_INT 0x2 /* interrupt */
#define SBTMH_BUSY 0x4 /* busy */
#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */
#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */
#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */
#define SBTMH_GCR 0x20000000 /* gated clock request */
#define SBTMH_BISTF 0x40000000 /* bist failed */
#define SBTMH_BISTD 0x80000000 /* bist done */
/* sbbwa0 */
#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */
#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */
#define SBBWA_TAB1_SHIFT 16
/* sbimconfiglow */
#define SBIMCL_STO_MASK 0x7 /* service timeout */
#define SBIMCL_RTO_MASK 0x70 /* request timeout */
#define SBIMCL_RTO_SHIFT 4
#define SBIMCL_CID_MASK 0xff0000 /* connection id */
#define SBIMCL_CID_SHIFT 16
/* sbimconfighigh */
#define SBIMCH_IEM_MASK 0xc /* inband error mode */
#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */
#define SBIMCH_TEM_SHIFT 4
#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */
#define SBIMCH_BEM_SHIFT 6
/* sbadmatch0 */
#define SBAM_TYPE_MASK 0x3 /* address type */
#define SBAM_AD64 0x4 /* reserved */
#define SBAM_ADINT0_MASK 0xf8 /* type0 size */
#define SBAM_ADINT0_SHIFT 3
#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */
#define SBAM_ADINT1_SHIFT 3
#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */
#define SBAM_ADINT2_SHIFT 3
#define SBAM_ADEN 0x400 /* enable */
#define SBAM_ADNEG 0x800 /* negative decode */
#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */
#define SBAM_BASE0_SHIFT 8
#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */
#define SBAM_BASE1_SHIFT 12
#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */
#define SBAM_BASE2_SHIFT 16
/* sbtmconfiglow */
#define SBTMCL_CD_MASK 0xff /* clock divide */
#define SBTMCL_CO_MASK 0xf800 /* clock offset */
#define SBTMCL_CO_SHIFT 11
#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */
#define SBTMCL_IF_SHIFT 18
#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */
#define SBTMCL_IM_SHIFT 24
/* sbtmconfighigh */
#define SBTMCH_BM_MASK 0x3 /* busy mode */
#define SBTMCH_RM_MASK 0x3 /* retry mode */
#define SBTMCH_RM_SHIFT 2
#define SBTMCH_SM_MASK 0x30 /* stop mode */
#define SBTMCH_SM_SHIFT 4
#define SBTMCH_EM_MASK 0x300 /* sb error mode */
#define SBTMCH_EM_SHIFT 8
#define SBTMCH_IM_MASK 0xc00 /* int mode */
#define SBTMCH_IM_SHIFT 10
/* sbbconfig */
#define SBBC_LAT_MASK 0x3 /* sb latency */
#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */
#define SBBC_MAX0_SHIFT 16
#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */
#define SBBC_MAX1_SHIFT 20
/* sbbstate */
#define SBBS_SRD 0x1 /* st reg disable */
#define SBBS_HRD 0x2 /* hold reg disable */
/* sbidlow */
#define SBIDL_CS_MASK 0x3 /* config space */
#define SBIDL_AR_MASK 0x38 /* # address ranges supported */
#define SBIDL_AR_SHIFT 3
#define SBIDL_SYNCH 0x40 /* sync */
#define SBIDL_INIT 0x80 /* initiator */
#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */
#define SBIDL_MINLAT_SHIFT 8
#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */
#define SBIDL_MAXLAT_SHIFT 12
#define SBIDL_FIRST 0x10000 /* this initiator is first */
#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */
#define SBIDL_CW_SHIFT 18
#define SBIDL_TP_MASK 0xf00000 /* target ports */
#define SBIDL_TP_SHIFT 20
#define SBIDL_IP_MASK 0xf000000 /* initiator ports */
#define SBIDL_IP_SHIFT 24
#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */
#define SBIDL_RV_SHIFT 28
#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */
#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */
/* sbidhigh */
#define SBIDH_RC_MASK 0x000f /* revision code */
#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */
#define SBIDH_RCE_SHIFT 8
#define SBCOREREV(sbidh) \
((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
#define SBIDH_CC_MASK 0x8ff0 /* core code */
#define SBIDH_CC_SHIFT 4
#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
#define SBIDH_VC_SHIFT 16
#define SB_COMMIT 0xfd8 /* update buffered registers value */
/* vendor codes */
#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */
/* core codes */
#define SB_NODEV 0x700 /* Invalid coreid */
#define SB_CC 0x800 /* chipcommon core */
#define SB_ILINE20 0x801 /* iline20 core */
#define SB_SDRAM 0x803 /* sdram core */
#define SB_PCI 0x804 /* pci core */
#define SB_MIPS 0x805 /* mips core */
#define SB_ENET 0x806 /* enet mac core */
#define SB_CODEC 0x807 /* v90 codec core */
#define SB_USB 0x808 /* usb 1.1 host/device core */
#define SB_ADSL 0x809 /* ADSL core */
#define SB_ILINE100 0x80a /* iline100 core */
#define SB_IPSEC 0x80b /* ipsec core */
#define SB_PCMCIA 0x80d /* pcmcia core */
#define SB_SDIOD SB_PCMCIA /* pcmcia core has sdio device */
#define SB_SOCRAM 0x80e /* internal memory core */
#define SB_MEMC 0x80f /* memc sdram core */
#define SB_EXTIF 0x811 /* external interface core */
#define SB_D11 0x812 /* 802.11 MAC core */
#define SB_MIPS33 0x816 /* mips3302 core */
#define SB_USB11H 0x817 /* usb 1.1 host core */
#define SB_USB11D 0x818 /* usb 1.1 device core */
#define SB_USB20H 0x819 /* usb 2.0 host core */
#define SB_USB20D 0x81a /* usb 2.0 device core */
#define SB_SDIOH 0x81b /* sdio host core */
#define SB_ROBO 0x81c /* roboswitch core */
#define SB_ATA100 0x81d /* parallel ATA core */
#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */
#define SB_GIGETH 0x81f /* gigabit ethernet core */
#define SB_PCIE 0x820 /* pci express core */
#define SB_MIMO 0x821 /* MIMO phy core */
#define SB_SRAMC 0x822 /* SRAM controller core */
#define SB_MINIMAC 0x823 /* MINI MAC/phy core */
#define SB_ARM11 0x824 /* ARM 1176 core */
#define SB_ARM7 0x825 /* ARM 7tdmi core */
#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */
/* Not really related to Silicon Backplane, but a couple of software
* conventions for the use the flash space:
*/
/* Minumum amount of flash we support */
#define FLASH_MIN 0x00020000 /* Minimum flash size */
/* A boot/binary may have an embedded block that describes its size */
#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */
#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */
#define BISZ_MAGIC_IDX 0 /* Word 0: magic */
#define BISZ_TXTST_IDX 1 /* 1: text start */
#define BISZ_TXTEND_IDX 2 /* 2: text start */
#define BISZ_DATAST_IDX 3 /* 3: text start */
#define BISZ_DATAEND_IDX 4 /* 4: text start */
#define BISZ_BSSST_IDX 5 /* 5: text start */
#define BISZ_BSSEND_IDX 6 /* 6: text start */
#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */
#endif /* _SBCONFIG_H */

View file

@ -0,0 +1,243 @@
/*
* Hardware-specific External Interface I/O core definitions
* for the BCM47xx family of SiliconBackplane-based chips.
*
* The External Interface core supports a total of three external chip selects
* supporting external interfaces. One of the external chip selects is
* used for Flash, one is used for PCMCIA, and the other may be
* programmed to support either a synchronous interface or an
* asynchronous interface. The asynchronous interface can be used to
* support external devices such as UARTs and the BCM2019 Bluetooth
* baseband processor.
* The external interface core also contains 2 on-chip 16550 UARTs, clock
* frequency control, a watchdog interrupt timer, and a GPIO interface.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbextif.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _SBEXTIF_H
#define _SBEXTIF_H
/* external interface address space */
#define EXTIF_PCMCIA_MEMBASE(x) (x)
#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000)
#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000)
#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000)
#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000)
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif /* PAD */
/*
* The multiple instances of output and output enable registers
* are present to allow driver software for multiple cores to control
* gpio outputs without needing to share a single register pair.
*/
struct gpiouser {
uint32 out;
uint32 outen;
};
#define NGPIOUSER 5
typedef volatile struct {
uint32 corecontrol;
uint32 extstatus;
uint32 PAD[2];
/* pcmcia control registers */
uint32 pcmcia_config;
uint32 pcmcia_memwait;
uint32 pcmcia_attrwait;
uint32 pcmcia_iowait;
/* programmable interface control registers */
uint32 prog_config;
uint32 prog_waitcount;
/* flash control registers */
uint32 flash_config;
uint32 flash_waitcount;
uint32 PAD[4];
uint32 watchdog;
/* clock control */
uint32 clockcontrol_n;
uint32 clockcontrol_sb;
uint32 clockcontrol_pci;
uint32 clockcontrol_mii;
uint32 PAD[3];
/* gpio */
uint32 gpioin;
struct gpiouser gpio[NGPIOUSER];
uint32 PAD;
uint32 ejtagouten;
uint32 gpiointpolarity;
uint32 gpiointmask;
uint32 PAD[153];
uint8 uartdata;
uint8 PAD[3];
uint8 uartimer;
uint8 PAD[3];
uint8 uartfcr;
uint8 PAD[3];
uint8 uartlcr;
uint8 PAD[3];
uint8 uartmcr;
uint8 PAD[3];
uint8 uartlsr;
uint8 PAD[3];
uint8 uartmsr;
uint8 PAD[3];
uint8 uartscratch;
uint8 PAD[3];
} extifregs_t;
/* corecontrol */
#define CC_UE (1 << 0) /* uart enable */
/* extstatus */
#define ES_EM (1 << 0) /* endian mode (ro) */
#define ES_EI (1 << 1) /* external interrupt pin (ro) */
#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */
/* gpio bit mask */
#define GPIO_BIT0 (1 << 0)
#define GPIO_BIT1 (1 << 1)
#define GPIO_BIT2 (1 << 2)
#define GPIO_BIT3 (1 << 3)
#define GPIO_BIT4 (1 << 4)
#define GPIO_BIT5 (1 << 5)
#define GPIO_BIT6 (1 << 6)
#define GPIO_BIT7 (1 << 7)
/* pcmcia/prog/flash_config */
#define CF_EN (1 << 0) /* enable */
#define CF_EM_MASK 0xe /* mode */
#define CF_EM_SHIFT 1
#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */
#define CF_EM_SYNC 0x2 /* synchronous mode */
#define CF_EM_PCMCIA 0x4 /* pcmcia mode */
#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */
#define CF_BS (1 << 5) /* byteswap */
#define CF_CD_MASK 0xc0 /* clock divider */
#define CF_CD_SHIFT 6
#define CF_CD_DIV2 0x0 /* backplane/2 */
#define CF_CD_DIV3 0x40 /* backplane/3 */
#define CF_CD_DIV4 0x80 /* backplane/4 */
#define CF_CE (1 << 8) /* clock enable */
#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */
/* pcmcia_memwait */
#define PM_W0_MASK 0x3f /* waitcount0 */
#define PM_W1_MASK 0x1f00 /* waitcount1 */
#define PM_W1_SHIFT 8
#define PM_W2_MASK 0x1f0000 /* waitcount2 */
#define PM_W2_SHIFT 16
#define PM_W3_MASK 0x1f000000 /* waitcount3 */
#define PM_W3_SHIFT 24
/* pcmcia_attrwait */
#define PA_W0_MASK 0x3f /* waitcount0 */
#define PA_W1_MASK 0x1f00 /* waitcount1 */
#define PA_W1_SHIFT 8
#define PA_W2_MASK 0x1f0000 /* waitcount2 */
#define PA_W2_SHIFT 16
#define PA_W3_MASK 0x1f000000 /* waitcount3 */
#define PA_W3_SHIFT 24
/* pcmcia_iowait */
#define PI_W0_MASK 0x3f /* waitcount0 */
#define PI_W1_MASK 0x1f00 /* waitcount1 */
#define PI_W1_SHIFT 8
#define PI_W2_MASK 0x1f0000 /* waitcount2 */
#define PI_W2_SHIFT 16
#define PI_W3_MASK 0x1f000000 /* waitcount3 */
#define PI_W3_SHIFT 24
/* prog_waitcount */
#define PW_W0_MASK 0x0000001f /* waitcount0 */
#define PW_W1_MASK 0x00001f00 /* waitcount1 */
#define PW_W1_SHIFT 8
#define PW_W2_MASK 0x001f0000 /* waitcount2 */
#define PW_W2_SHIFT 16
#define PW_W3_MASK 0x1f000000 /* waitcount3 */
#define PW_W3_SHIFT 24
#define PW_W0 0x0000000c
#define PW_W1 0x00000a00
#define PW_W2 0x00020000
#define PW_W3 0x01000000
/* flash_waitcount */
#define FW_W0_MASK 0x1f /* waitcount0 */
#define FW_W1_MASK 0x1f00 /* waitcount1 */
#define FW_W1_SHIFT 8
#define FW_W2_MASK 0x1f0000 /* waitcount2 */
#define FW_W2_SHIFT 16
#define FW_W3_MASK 0x1f000000 /* waitcount3 */
#define FW_W3_SHIFT 24
/* watchdog */
#define WATCHDOG_CLOCK 48000000 /* Hz */
/* clockcontrol_n */
#define CN_N1_MASK 0x3f /* n1 control */
#define CN_N2_MASK 0x3f00 /* n2 control */
#define CN_N2_SHIFT 8
/* clockcontrol_sb/pci/mii */
#define CC_M1_MASK 0x3f /* m1 control */
#define CC_M2_MASK 0x3f00 /* m2 control */
#define CC_M2_SHIFT 8
#define CC_M3_MASK 0x3f0000 /* m3 control */
#define CC_M3_SHIFT 16
#define CC_MC_MASK 0x1f000000 /* mux control */
#define CC_MC_SHIFT 24
/* Clock control default values */
#define CC_DEF_N 0x0009 /* Default values for bcm4710 */
#define CC_DEF_100 0x04020011
#define CC_DEF_33 0x11030011
#define CC_DEF_25 0x11050011
/* Clock control values for 125Mhz */
#define CC_125_N 0x0802
#define CC_125_M 0x04020009
#define CC_125_M25 0x11090009
#define CC_125_M33 0x11090005
/* Clock control magic field values */
#define CC_F6_2 0x02 /* A factor of 2 in */
#define CC_F6_3 0x03 /* 6-bit fields like */
#define CC_F6_4 0x05 /* N1, M1 or M3 */
#define CC_F6_5 0x09
#define CC_F6_6 0x11
#define CC_F6_7 0x21
#define CC_F5_BIAS 5 /* 5-bit fields get this added */
#define CC_MC_BYPASS 0x08
#define CC_MC_M1 0x04
#define CC_MC_M1M2 0x02
#define CC_MC_M1M2M3 0x01
#define CC_MC_M1M3 0x11
#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */
#endif /* _SBEXTIF_H */

View file

@ -0,0 +1,47 @@
/*
* Broadcom SiliconBackplane MIPS definitions
*
* SB MIPS cores are custom MIPS32 processors with SiliconBackplane
* OCP interfaces. The CP0 processor ID is 0x00024000, where bits
* 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP
* interface. The core revision is stored in the SB ID register in SB
* configuration space.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbhndmips.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _sbhndmips_h_
#define _sbhndmips_h_
#include <mipsinc.h>
#ifndef _LANGUAGE_ASSEMBLY
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif /* PAD */
typedef volatile struct {
uint32 corecontrol;
uint32 PAD[2];
uint32 biststatus;
uint32 PAD[4];
uint32 intstatus;
uint32 intmask;
uint32 timer;
} mipsregs_t;
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* _sbhndmips_h_ */

View file

@ -0,0 +1,147 @@
/*
* BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbmemc.h,v 1.6 2006/03/02 12:33:44 honor Exp $
*/
#ifndef _SBMEMC_H
#define _SBMEMC_H
#ifdef _LANGUAGE_ASSEMBLY
#define MEMC_CONTROL 0x00
#define MEMC_CONFIG 0x04
#define MEMC_REFRESH 0x08
#define MEMC_BISTSTAT 0x0c
#define MEMC_MODEBUF 0x10
#define MEMC_BKCLS 0x14
#define MEMC_PRIORINV 0x18
#define MEMC_DRAMTIM 0x1c
#define MEMC_INTSTAT 0x20
#define MEMC_INTMASK 0x24
#define MEMC_INTINFO 0x28
#define MEMC_NCDLCTL 0x30
#define MEMC_RDNCDLCOR 0x34
#define MEMC_WRNCDLCOR 0x38
#define MEMC_MISCDLYCTL 0x3c
#define MEMC_DQSGATENCDL 0x40
#define MEMC_SPARE 0x44
#define MEMC_TPADDR 0x48
#define MEMC_TPDATA 0x4c
#define MEMC_BARRIER 0x50
#define MEMC_CORE 0x54
#else /* !_LANGUAGE_ASSEMBLY */
/* Sonics side: MEMC core registers */
typedef volatile struct sbmemcregs {
uint32 control;
uint32 config;
uint32 refresh;
uint32 biststat;
uint32 modebuf;
uint32 bkcls;
uint32 priorinv;
uint32 dramtim;
uint32 intstat;
uint32 intmask;
uint32 intinfo;
uint32 reserved1;
uint32 ncdlctl;
uint32 rdncdlcor;
uint32 wrncdlcor;
uint32 miscdlyctl;
uint32 dqsgatencdl;
uint32 spare;
uint32 tpaddr;
uint32 tpdata;
uint32 barrier;
uint32 core;
} sbmemcregs_t;
#endif /* _LANGUAGE_ASSEMBLY */
/* MEMC Core Init values (OCP ID 0x80f) */
/* For sdr: */
#define MEMC_SD_CONFIG_INIT 0x00048000
#define MEMC_SD_DRAMTIM2_INIT 0x000754d8
#define MEMC_SD_DRAMTIM3_INIT 0x000754da
#define MEMC_SD_RDNCDLCOR_INIT 0x00000000
#define MEMC_SD_WRNCDLCOR_INIT 0x49351200
#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */
#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b
#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */
#define MEMC_SD_CONTROL_INIT0 0x00000002
#define MEMC_SD_CONTROL_INIT1 0x00000008
#define MEMC_SD_CONTROL_INIT2 0x00000004
#define MEMC_SD_CONTROL_INIT3 0x00000010
#define MEMC_SD_CONTROL_INIT4 0x00000001
#define MEMC_SD_MODEBUF_INIT 0x00000000
#define MEMC_SD_REFRESH_INIT 0x0000840f
/* This is for SDRM8X8X4 */
#define MEMC_SDR_INIT 0x0008
#define MEMC_SDR_MODE 0x32
#define MEMC_SDR_NCDL 0x00020032
#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */
/* For ddr: */
#define MEMC_CONFIG_INIT 0x00048000
#define MEMC_DRAMTIM2_INIT 0x000754d8
#define MEMC_DRAMTIM25_INIT 0x000754d9
#define MEMC_RDNCDLCOR_INIT 0x00000000
#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */
#define MEMC_WRNCDLCOR_INIT 0x49351200
#define MEMC_1_WRNCDLCOR_INIT 0x14500200
#define MEMC_DQSGATENCDL_INIT 0x00030000
#define MEMC_MISCDLYCTL_INIT 0x21061c1b
#define MEMC_1_MISCDLYCTL_INIT 0x21021400
#define MEMC_NCDLCTL_INIT 0x00002001
#define MEMC_CONTROL_INIT0 0x00000002
#define MEMC_CONTROL_INIT1 0x00000008
#define MEMC_MODEBUF_INIT0 0x00004000
#define MEMC_CONTROL_INIT2 0x00000010
#define MEMC_MODEBUF_INIT1 0x00000100
#define MEMC_CONTROL_INIT3 0x00000010
#define MEMC_CONTROL_INIT4 0x00000008
#define MEMC_REFRESH_INIT 0x0000840f
#define MEMC_CONTROL_INIT5 0x00000004
#define MEMC_MODEBUF_INIT2 0x00000000
#define MEMC_CONTROL_INIT6 0x00000010
#define MEMC_CONTROL_INIT7 0x00000001
/* This is for DDRM16X16X2 */
#define MEMC_DDR_INIT 0x0009
#define MEMC_DDR_MODE 0x62
#define MEMC_DDR_NCDL 0x0005050a
#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */
/* mask for sdr/ddr calibration registers */
#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff
#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff
#define MEMC_DQSGATENCDL_G_MASK 0x000000ff
/* masks for miscdlyctl registers */
#define MEMC_MISC_SM_MASK 0x30000000
#define MEMC_MISC_SM_SHIFT 28
#define MEMC_MISC_SD_MASK 0x0f000000
#define MEMC_MISC_SD_SHIFT 24
/* hw threshhold for calculating wr/rd for sdr memc */
#define MEMC_CD_THRESHOLD 128
/* Low bit of init register says if memc is ddr or sdr */
#define MEMC_CONFIG_DDR 0x00000001
#endif /* _SBMEMC_H */

View file

@ -0,0 +1,114 @@
/*
* HND SiliconBackplane PCI core hardware definitions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbpci.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _sbpci_h_
#define _sbpci_h_
#ifndef _LANGUAGE_ASSEMBLY
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif
/* Sonics side: PCI core and host control registers */
typedef struct sbpciregs {
uint32 control; /* PCI control */
uint32 PAD[3];
uint32 arbcontrol; /* PCI arbiter control */
uint32 PAD[3];
uint32 intstatus; /* Interrupt status */
uint32 intmask; /* Interrupt mask */
uint32 sbtopcimailbox; /* Sonics to PCI mailbox */
uint32 PAD[9];
uint32 bcastaddr; /* Sonics broadcast address */
uint32 bcastdata; /* Sonics broadcast data */
uint32 PAD[2];
uint32 gpioin; /* ro: gpio input (>=rev2) */
uint32 gpioout; /* rw: gpio output (>=rev2) */
uint32 gpioouten; /* rw: gpio output enable (>= rev2) */
uint32 gpiocontrol; /* rw: gpio control (>= rev2) */
uint32 PAD[36];
uint32 sbtopci0; /* Sonics to PCI translation 0 */
uint32 sbtopci1; /* Sonics to PCI translation 1 */
uint32 sbtopci2; /* Sonics to PCI translation 2 */
uint32 PAD[189];
uint32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
uint16 sprom[36]; /* SPROM shadow Area */
uint32 PAD[46];
} sbpciregs_t;
#endif /* _LANGUAGE_ASSEMBLY */
/* PCI control */
#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */
#define PCI_RST 0x02 /* Value driven out to pin */
#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */
#define PCI_CLK 0x08 /* Gate for clock driven out to pin */
/* PCI arbiter control */
#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */
#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */
/* ParkID - for PCI corerev >= 8 */
#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */
#define PCI_PARKID_SHIFT 2
#define PCI_PARKID_EXT0 0 /* External master 0 */
#define PCI_PARKID_EXT1 1 /* External master 1 */
#define PCI_PARKID_EXT2 2 /* External master 2 */
#define PCI_PARKID_INT 3 /* Internal master */
#define PCI_PARKID_LAST 4 /* Last active master */
/* Interrupt status/mask */
#define PCI_INTA 0x01 /* PCI INTA# is asserted */
#define PCI_INTB 0x02 /* PCI INTB# is asserted */
#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */
#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */
#define PCI_PME 0x10 /* PCI PME# is asserted */
/* (General) PCI/SB mailbox interrupts, two bits per pci function */
#define MAILBOX_F0_0 0x100 /* function 0, int 0 */
#define MAILBOX_F0_1 0x200 /* function 0, int 1 */
#define MAILBOX_F1_0 0x400 /* function 1, int 0 */
#define MAILBOX_F1_1 0x800 /* function 1, int 1 */
#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */
#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */
#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */
#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */
/* Sonics broadcast address */
#define BCAST_ADDR_MASK 0xff /* Broadcast register address */
/* Sonics to PCI translation types */
#define SBTOPCI0_MASK 0xfc000000
#define SBTOPCI1_MASK 0xfc000000
#define SBTOPCI2_MASK 0xc0000000
#define SBTOPCI_MEM 0
#define SBTOPCI_IO 1
#define SBTOPCI_CFG0 2
#define SBTOPCI_CFG1 3
#define SBTOPCI_PREF 0x4 /* prefetch enable */
#define SBTOPCI_BURST 0x8 /* burst enable */
#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */
#define SBTOPCI_RC_READ 0x00 /* memory read */
#define SBTOPCI_RC_READLINE 0x10 /* memory read line */
#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
/* PCI core index in SROM shadow area */
#define SRSH_PI_OFFSET 0 /* first word */
#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
#define SRSH_PI_SHIFT 12 /* bit 15:12 */
#endif /* _sbpci_h_ */

View file

@ -0,0 +1,200 @@
/*
* BCM43XX SiliconBackplane PCIE core hardware definitions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbpcie.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _SBPCIE_H
#define _SBPCIE_H
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif
/* PCIE Enumeration space offsets */
#define PCIE_CORE_CONFIG_OFFSET 0x0
#define PCIE_FUNC0_CONFIG_OFFSET 0x400
#define PCIE_FUNC1_CONFIG_OFFSET 0x500
#define PCIE_FUNC2_CONFIG_OFFSET 0x600
#define PCIE_FUNC3_CONFIG_OFFSET 0x700
#define PCIE_SPROM_SHADOW_OFFSET 0x800
#define PCIE_SBCONFIG_OFFSET 0xE00
/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */
#define PCIE_DEV_BAR0_SIZE 0x4000
#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0
#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000
#define PCIE_BAR0_PCIECORE_OFFSET 0x2000
#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000
/* SB side: PCIE core and host control registers */
typedef struct sbpcieregs {
uint32 PAD[3];
uint32 biststatus; /* bist Status: 0x00C */
uint32 PAD[6];
uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
uint32 PAD[54];
uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
uint32 PAD[4];
/* pcie core supports in direct access to config space */
uint32 configaddr; /* pcie config space access: Address field: 0x120 */
uint32 configdata; /* pcie config space access: Data field: 0x124 */
/* mdio access to serdes */
uint32 mdiocontrol; /* controls the mdio access: 0x128 */
uint32 mdiodata; /* Data to the mdio access: 0x12c */
/* pcie protocol phy/dllp/tlp register access mechanism */
uint32 pcieaddr; /* address of the internal registeru: 0x130 */
uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */
uint32 PAD[434];
uint16 sprom[36]; /* SPROM shadow Area */
} sbpcieregs_t;
/* SB to PCIE translation masks */
#define SBTOPCIE0_MASK 0xfc000000
#define SBTOPCIE1_MASK 0xfc000000
#define SBTOPCIE2_MASK 0xc0000000
/* Access type bits (0:1) */
#define SBTOPCIE_MEM 0
#define SBTOPCIE_IO 1
#define SBTOPCIE_CFG0 2
#define SBTOPCIE_CFG1 3
/* Prefetch enable bit 2 */
#define SBTOPCIE_PF 4
/* Write Burst enable for memory write bit 3 */
#define SBTOPCIE_WR_BURST 8
/* config access */
#define CONFIGADDR_FUNC_MASK 0x7000
#define CONFIGADDR_FUNC_SHF 12
#define CONFIGADDR_REG_MASK 0x0FFF
#define CONFIGADDR_REG_SHF 0
/* PCIE protocol regs Indirect Address */
#define PCIEADDR_PROT_MASK 0x300
#define PCIEADDR_PROT_SHF 8
#define PCIEADDR_PL_TLP 0
#define PCIEADDR_PL_DLLP 1
#define PCIEADDR_PL_PLP 2
/* PCIE protocol PHY diagnostic registers */
#define PCIE_PLP_MODEREG 0x200 /* Mode */
#define PCIE_PLP_STATUSREG 0x204 /* Status */
#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */
#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */
#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */
#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */
#define PCIE_PLP_ATTNREG 0x218 /* Attention */
#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */
#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */
#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */
#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */
#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg */
#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */
#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */
#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */
#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */
/* PCIE protocol DLLP diagnostic registers */
#define PCIE_DLLP_LCREG 0x100 /* Link Control */
#define PCIE_DLLP_LSREG 0x104 /* Link Status */
#define PCIE_DLLP_LAREG 0x108 /* Link Attention */
#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */
#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */
#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */
#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */
#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */
#define PCIE_DLLP_LRREG 0x120 /* Link Replay */
#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */
#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */
#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */
#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */
#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */
#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */
#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */
#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter */
#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */
#define PCIE_DLLP_TESTREG 0x14C /* Test */
#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST */
/* PCIE protocol TLP diagnostic registers */
#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */
#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address */
#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address */
#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req */
#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address */
#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address */
#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req */
#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address */
#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address */
#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req */
#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len */
#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs */
#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req */
#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len */
#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0 */
#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1 */
#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2 */
#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */
#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */
#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */
#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len */
#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0 */
#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1 */
#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func */
#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter */
#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value */
#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1 */
#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2 */
#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3 */
#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4 */
/* MDIO control */
#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
#define MDIOCTL_DIVISOR_VAL 0x2
#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */
/* MDIO Data */
#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
#define MDIODATA_TA 0x00020000 /* Turnaround */
#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
#define MDIODATA_REGADDR_MASK 0x003c0000 /* Regaddr Mask */
#define MDIODATA_DEVADDR_SHF 22 /* Physmedia devaddr shift */
#define MDIODATA_DEVADDR_MASK 0x0fc00000 /* Physmedia devaddr Mask */
#define MDIODATA_WRITE 0x10000000 /* write Transaction */
#define MDIODATA_READ 0x20000000 /* Read Transaction */
#define MDIODATA_START 0x40000000 /* start of Transaction */
/* MDIO devices (SERDES modules) */
#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
/* SERDES registers */
#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
#define SERDES_RX_CDR 6 /* CDR */
#define SERDES_RX_CDRBW 7 /* CDR BW */
#endif /* _SBPCIE_H */

View file

@ -0,0 +1,147 @@
/*
* BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbpcmcia.h,v 1.1.1.9 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _SBPCMCIA_H
#define _SBPCMCIA_H
/* All the addresses that are offsets in attribute space are divided
* by two to account for the fact that odd bytes are invalid in
* attribute space and our read/write routines make the space appear
* as if they didn't exist. Still we want to show the original numbers
* as documented in the hnd_pcmcia core manual.
*/
/* PCMCIA Function Configuration Registers */
#define PCMCIA_FCR (0x700 / 2)
#define FCR0_OFF 0
#define FCR1_OFF (0x40 / 2)
#define FCR2_OFF (0x80 / 2)
#define FCR3_OFF (0xc0 / 2)
#define PCMCIA_FCR0 (0x700 / 2)
#define PCMCIA_FCR1 (0x740 / 2)
#define PCMCIA_FCR2 (0x780 / 2)
#define PCMCIA_FCR3 (0x7c0 / 2)
/* Standard PCMCIA FCR registers */
#define PCMCIA_COR 0
#define COR_RST 0x80
#define COR_LEV 0x40
#define COR_IRQEN 0x04
#define COR_BLREN 0x01
#define COR_FUNEN 0x01
#define PCICIA_FCSR (2 / 2)
#define PCICIA_PRR (4 / 2)
#define PCICIA_SCR (6 / 2)
#define PCICIA_ESR (8 / 2)
#define PCM_MEMOFF 0x0000
#define F0_MEMOFF 0x1000
#define F1_MEMOFF 0x2000
#define F2_MEMOFF 0x3000
#define F3_MEMOFF 0x4000
/* Memory base in the function fcr's */
#define MEM_ADDR0 (0x728 / 2)
#define MEM_ADDR1 (0x72a / 2)
#define MEM_ADDR2 (0x72c / 2)
/* PCMCIA base plus Srom access in fcr0: */
#define PCMCIA_ADDR0 (0x072e / 2)
#define PCMCIA_ADDR1 (0x0730 / 2)
#define PCMCIA_ADDR2 (0x0732 / 2)
#define MEM_SEG (0x0734 / 2)
#define SROM_CS (0x0736 / 2)
#define SROM_DATAL (0x0738 / 2)
#define SROM_DATAH (0x073a / 2)
#define SROM_ADDRL (0x073c / 2)
#define SROM_ADDRH (0x073e / 2)
/* Values for srom_cs: */
#define SROM_IDLE 0
#define SROM_WRITE 1
#define SROM_READ 2
#define SROM_WEN 4
#define SROM_WDS 7
#define SROM_DONE 8
/* CIS stuff */
/* The CIS stops where the FCRs start */
#define CIS_SIZE PCMCIA_FCR
/* Standard tuples we know about */
#define CISTPL_MANFID 0x20 /* Manufacturer and device id */
#define CISTPL_FUNCE 0x22 /* Function extensions */
#define CISTPL_CFTABLE 0x1b /* Config table entry */
/* Function extensions for LANs */
#define LAN_TECH 1 /* Technology type */
#define LAN_SPEED 2 /* Raw bit rate */
#define LAN_MEDIA 3 /* Transmission media */
#define LAN_NID 4 /* Node identification (aka MAC addr) */
#define LAN_CONN 5 /* Connector standard */
/* CFTable */
#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */
#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */
#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */
/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll
* take one for HNBU, and use "extensions" (a la FUNCE) within it.
*/
#define CISTPL_BRCM_HNBU 0x80
/* Subtypes of BRCM_HNBU: */
#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */
#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */
#define HNBU_BOARDREV 0x02 /* One byte board revision */
#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1)
* or 9 (sromrev > 1) bytes
*/
#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */
#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */
#define HNBU_AA 0x06 /* Antennas available */
#define HNBU_AG 0x07 /* Antenna gain */
#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */
#define HNBU_LEDS 0x09 /* LED set */
#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl)
* in rev 2
*/
#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */
#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */
#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */
/* sbtmstatelow */
#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */
#define SBTML_INT_EN 0x20000 /* enable sb interrupt */
/* sbtmstatehigh */
#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */
#endif /* _SBPCMCIA_H */

View file

@ -0,0 +1,85 @@
/*
* BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbsdram.h,v 1.1.1.9 2006/03/02 13:03:52 honor Exp $
*/
#ifndef _SBSDRAM_H
#define _SBSDRAM_H
#ifndef _LANGUAGE_ASSEMBLY
/* Sonics side: SDRAM core registers */
typedef volatile struct sbsdramregs {
uint32 initcontrol; /* Generates external SDRAM initialization sequence */
uint32 config; /* Initializes external SDRAM mode register */
uint32 refresh; /* Controls external SDRAM refresh rate */
uint32 pad1;
uint32 pad2;
} sbsdramregs_t;
/* SDRAM simulation */
#ifdef RAMSZ
#define SDRAMSZ RAMSZ
#else
#define SDRAMSZ (4 * 1024 * 1024)
#endif
extern uchar sdrambuf[SDRAMSZ];
#endif /* _LANGUAGE_ASSEMBLY */
/* SDRAM initialization control (initcontrol) register bits */
#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */
#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */
#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */
#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */
#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */
#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */
#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */
#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */
#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */
#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */
#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */
#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */
#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */
/* SDRAM configuration (config) register bits */
#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */
#define SDRAM_BURST8 0x0001 /* Use burst of 8 */
#define SDRAM_BURST4 0x0002 /* Use burst of 4 */
#define SDRAM_BURST2 0x0003 /* Use burst of 2 */
#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */
#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */
/* SDRAM refresh control (refresh) register bits */
#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */
#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */
/* SDRAM Core default Init values (OCP ID 0x803) */
#define SDRAM_INIT MEM4MX16X2
#define SDRAM_CONFIG SDRAM_BURSTFULL
#define SDRAM_REFRESH SDRAM_REF(0x40)
#define MEM1MX16 0x009 /* 2 MB */
#define MEM1MX16X2 0x409 /* 4 MB */
#define MEM2MX8X2 0x809 /* 4 MB */
#define MEM2MX8X4 0xc09 /* 8 MB */
#define MEM2MX32 0x439 /* 8 MB */
#define MEM4MX16 0x019 /* 8 MB */
#define MEM4MX16X2 0x419 /* 16 MB */
#define MEM8MX8X2 0x819 /* 16 MB */
#define MEM8MX16 0x829 /* 16 MB */
#define MEM4MX32 0x429 /* 16 MB */
#define MEM8MX8X4 0xc19 /* 32 MB */
#define MEM8MX16X2 0xc29 /* 32 MB */
#endif /* _SBSDRAM_H */

View file

@ -0,0 +1,64 @@
/*
* BCM47XX Sonics SiliconBackplane embedded ram core
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbsocram.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _SBSOCRAM_H
#define _SBSOCRAM_H
#define SR_COREINFO 0x00
#define SR_BWALLOC 0x04
#define SR_BISTSTAT 0x0c
#define SR_BANKINDEX 0x10
#define SR_BANKSTBYCTL 0x14
#ifndef _LANGUAGE_ASSEMBLY
/* Memcsocram core registers */
typedef volatile struct sbsocramregs {
uint32 coreinfo;
uint32 bwalloc;
uint32 PAD;
uint32 biststat;
uint32 bankidx;
uint32 standbyctrl;
} sbsocramregs_t;
#endif
/* Coreinfo register */
#define SRCI_PT_MASK 0x30000
#define SRCI_PT_SHIFT 16
/* In corerev 0, the memory size is 2 to the power of the
* base plus 16 plus to the contents of the memsize field plus 1.
*/
#define SRCI_MS0_MASK 0xf
#define SR_MS0_BASE 16
/*
* In corerev 1 the bank size is 2 ^ the bank size field plus 14,
* the memory size is number of banks times bank size.
* The same applies to rom size.
*/
#define SRCI_ROMNB_MASK 0xf000
#define SRCI_ROMNB_SHIFT 12
#define SRCI_ROMBSZ_MASK 0xf00
#define SRCI_ROMBSZ_SHIFT 8
#define SRCI_SRNB_MASK 0xf0
#define SRCI_SRNB_SHIFT 4
#define SRCI_SRBSZ_MASK 0xf
#define SRCI_SRBSZ_SHIFT 0
#define SR_BSZ_BASE 14
#endif /* _SBSOCRAM_H */

View file

@ -0,0 +1,151 @@
/*
* Misc utility routines for accessing chip-specific features
* of Broadcom HNBU SiliconBackplane-based chips.
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sbutils.h,v 1.4 2006/04/08 07:12:42 honor Exp $
*/
#ifndef _sbutils_h_
#define _sbutils_h_
/*
* Datastructure to export all chip specific common variables
* public (read-only) portion of sbutils handle returned by
* sb_attach()/sb_kattach()
*/
struct sb_pub {
uint bustype; /* SB_BUS, PCI_BUS */
uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE */
uint buscorerev; /* buscore rev */
uint buscoreidx; /* buscore index */
int ccrev; /* chip common core rev */
uint boardtype; /* board type */
uint boardvendor; /* board vendor */
uint chip; /* chip number */
uint chiprev; /* chip revision */
uint chippkg; /* chip package option */
uint sonicsrev; /* sonics backplane rev */
};
typedef const struct sb_pub sb_t;
/*
* Many of the routines below take an 'sbh' handle as their first arg.
* Allocate this by calling sb_attach(). Free it by calling sb_detach().
* At any one time, the sbh is logically focused on one particular sb core
* (the "current core").
* Use sb_setcore() or sb_setcoreidx() to change the association to another core.
*/
#define SB_OSH NULL /* Use for sb_kattach when no osh is available */
/* exported externs */
extern sb_t *sb_attach(uint pcidev, osl_t *osh, void *regs, uint bustype,
void *sdh, char **vars, uint *varsz);
extern sb_t *sb_kattach(void);
extern void sb_detach(sb_t *sbh);
extern uint sb_chip(sb_t *sbh);
extern uint sb_chiprev(sb_t *sbh);
extern uint sb_chipcrev(sb_t *sbh);
extern uint sb_chippkg(sb_t *sbh);
extern uint sb_pcirev(sb_t *sbh);
extern bool sb_war16165(sb_t *sbh);
extern uint sb_pcmciarev(sb_t *sbh);
extern uint sb_boardvendor(sb_t *sbh);
extern uint sb_boardtype(sb_t *sbh);
extern uint sb_bus(sb_t *sbh);
extern uint sb_buscoretype(sb_t *sbh);
extern uint sb_buscorerev(sb_t *sbh);
extern uint sb_corelist(sb_t *sbh, uint coreid[]);
extern uint sb_coreid(sb_t *sbh);
extern uint sb_coreidx(sb_t *sbh);
extern uint sb_coreunit(sb_t *sbh);
extern uint sb_corevendor(sb_t *sbh);
extern uint sb_corerev(sb_t *sbh);
extern void *sb_osh(sb_t *sbh);
extern void sb_setosh(sb_t *sbh, osl_t *osh);
extern void *sb_coreregs(sb_t *sbh);
extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val);
extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val);
extern bool sb_iscoreup(sb_t *sbh);
extern void *sb_setcoreidx(sb_t *sbh, uint coreidx);
extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit);
extern int sb_corebist(sb_t *sbh);
extern void sb_commit(sb_t *sbh);
extern uint32 sb_base(uint32 admatch);
extern uint32 sb_size(uint32 admatch);
extern void sb_core_reset(sb_t *sbh, uint32 bits, uint32 resetbits);
extern void sb_core_tofixup(sb_t *sbh);
extern void sb_core_disable(sb_t *sbh, uint32 bits);
extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m);
extern uint32 sb_clock(sb_t *sbh);
extern void sb_pci_setup(sb_t *sbh, uint coremask);
extern void sb_pcmcia_init(sb_t *sbh);
extern void sb_watchdog(sb_t *sbh, uint ticks);
extern void *sb_gpiosetcore(sb_t *sbh);
extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
extern uint32 sb_gpioin(sb_t *sbh);
extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val);
extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority);
extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority);
extern void sb_clkctl_init(sb_t *sbh);
extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh);
extern bool sb_clkctl_clk(sb_t *sbh, uint mode);
extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on);
extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn,
void *intrsenabled_fn, void *intr_arg);
extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to);
extern int sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice,
uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif,
uint8 *pciheader);
extern uint sb_pcie_readreg(void *sbh, void* arg1, uint offset);
extern uint sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val);
extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val);
extern bool sb_backplane64(sb_t *sbh);
extern void sb_btcgpiowar(sb_t *sbh);
extern bool sb_deviceremoved(sb_t *sbh);
extern uint32 sb_socram_size(sb_t *sbh);
/*
* Build device path. Path size must be >= SB_DEVPATH_BUFSZ.
* The returned path is NULL terminated and has trailing '/'.
* Return 0 on success, nonzero otherwise.
*/
extern int sb_devpath(sb_t *sbh, char *path, int size);
/* clkctl xtal what flags */
#define XTAL 0x1 /* primary crystal oscillator (2050) */
#define PLL 0x2 /* main chip pll */
/* clkctl clk mode */
#define CLK_FAST 0 /* force fast (pll) clock */
#define CLK_DYNAMIC 2 /* enable dynamic clock control */
/* GPIO usage priorities */
#define GPIO_DRV_PRIORITY 0 /* Driver */
#define GPIO_APP_PRIORITY 1 /* Application */
#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO reservation */
/* device path */
#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
#endif /* _sbutils_h_ */

View file

@ -0,0 +1,36 @@
/*
* Broadcom SiliconBackplane chipcommon serial flash interface
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sflash.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $
*/
#ifndef _sflash_h_
#define _sflash_h_
#include <typedefs.h>
#include <sbchipc.h>
struct sflash {
uint blocksize; /* Block size */
uint numblocks; /* Number of blocks */
uint32 type; /* Type */
uint size; /* Total size in bytes */
};
/* Utility functions */
extern int sflash_poll(chipcregs_t *cc, uint offset);
extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf);
extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
extern int sflash_erase(chipcregs_t *cc, uint offset);
extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
extern struct sflash * sflash_init(chipcregs_t *cc);
#endif /* _sflash_h_ */

View file

@ -0,0 +1,33 @@
/*
* TRX image file header format.
*
* Copyright 2005, 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>
#define TRX_MAGIC 0x30524448 /* "HDR0" */
#define TRX_VERSION 1
#define TRX_MAX_LEN 0x3A0000
#define TRX_NO_HEADER 1 /* Do not write TRX header */
#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
#define TRX_MAX_OFFSET 3
struct trx_header {
uint32 magic; /* "HDR0" */
uint32 len; /* Length of file including header */
uint32 crc32; /* 32-bit CRC from flag_version to end of file */
uint32 flag_version; /* 0:15 flags, 16:31 version */
uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
};
/* Compatibility */
typedef struct trx_header TRXHDR, *PTRXHDR;

View file

@ -0,0 +1,361 @@
/*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
* $Id: typedefs.h,v 1.1.1.12 2006/04/08 06:13:40 honor Exp $
*/
#ifndef _TYPEDEFS_H_
#define _TYPEDEFS_H_
/* Define 'SITE_TYPEDEFS' in the compile to include a site specific
* typedef file "site_typedefs.h".
*
* If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs"
* section of this file makes inferences about the compile environment
* based on defined symbols and possibly compiler pragmas.
*
* Following these two sections is the "Default Typedefs"
* section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is
* defined. This section has a default set of typedefs and a few
* proprocessor symbols (TRUE, FALSE, NULL, ...).
*/
#ifdef SITE_TYPEDEFS
/*
* Site Specific Typedefs
*
*/
#include "site_typedefs.h"
#else
/*
* Inferred Typedefs
*
*/
/* Infer the compile environment based on preprocessor symbols and pramas.
* Override type definitions as needed, and include configuration dependent
* header files to define types.
*/
#ifdef __cplusplus
#define TYPEDEF_BOOL
#ifndef FALSE
#define FALSE false
#endif
#ifndef TRUE
#define TRUE true
#endif
#else /* ! __cplusplus */
#if defined(_WIN32)
#define TYPEDEF_BOOL
typedef unsigned char bool; /* consistent w/BOOL */
#endif /* _WIN32 */
#endif /* ! __cplusplus */
/* use the Windows ULONG_PTR type when compiling for 64 bit */
#if defined(_WIN64)
#include <basetsd.h>
#define TYPEDEF_UINTPTR
typedef ULONG_PTR uintptr;
#endif
#if defined(_MINOSL_)
#define _NEED_SIZE_T_
#endif
#if defined(_NEED_SIZE_T_)
typedef long unsigned int size_t;
#endif
#ifdef __DJGPP__
typedef long unsigned int size_t;
#endif /* __DJGPP__ */
#ifdef _MSC_VER /* Microsoft C */
#define TYPEDEF_INT64
#define TYPEDEF_UINT64
typedef signed __int64 int64;
typedef unsigned __int64 uint64;
#endif
#if defined(MACOSX)
#define TYPEDEF_BOOL
#endif
#if defined(__NetBSD__)
#define TYPEDEF_ULONG
#endif
#if defined(linux)
#define TYPEDEF_UINT
#define TYPEDEF_USHORT
#define TYPEDEF_ULONG
#endif
#if !defined(linux) && !defined(_WIN32) && !defined(_CFE_) && \
!defined(_HNDRTE_) && !defined(_MINOSL_) && !defined(__DJGPP__)
#define TYPEDEF_UINT
#define TYPEDEF_USHORT
#endif
/* Do not support the (u)int64 types with strict ansi for GNU C */
#if defined(__GNUC__) && defined(__STRICT_ANSI__)
#define TYPEDEF_INT64
#define TYPEDEF_UINT64
#endif
/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode
* for singned or unsigned
*/
#if defined(__ICL)
#define TYPEDEF_INT64
#if defined(__STDC__)
#define TYPEDEF_UINT64
#endif
#endif /* __ICL */
#if !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && \
!defined(__DJGPP__)
/* pick up ushort & uint from standard types.h */
#if defined(linux) && defined(__KERNEL__)
#include <linux/types.h> /* sys/types.h and linux/types.h are oil and water */
#else
#include <sys/types.h>
#endif
#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ && !__DJGPP__ */
#if defined(MACOSX)
#ifdef __BIG_ENDIAN__
#define IL_BIGENDIAN
#else
#ifdef IL_BIGENDIAN
#error "IL_BIGENDIAN was defined for a little-endian compile"
#endif
#endif /* __BIG_ENDIAN__ */
#if !defined(__cplusplus)
#if defined(__i386__)
typedef unsigned char bool;
#else
typedef unsigned int bool;
#endif
#define TYPE_BOOL 1
enum {
false = 0,
true = 1
};
#if defined(KERNEL)
#include <IOKit/IOTypes.h>
#endif /* KERNEL */
#endif /* __cplusplus */
#endif /* MACOSX */
/* use the default typedefs in the next section of this file */
#define USE_TYPEDEF_DEFAULTS
#endif /* SITE_TYPEDEFS */
/*
* Default Typedefs
*
*/
#ifdef USE_TYPEDEF_DEFAULTS
#undef USE_TYPEDEF_DEFAULTS
#ifndef TYPEDEF_BOOL
typedef /* @abstract@ */ unsigned char bool;
#endif
/* define uchar, ushort, uint, ulong */
#ifndef TYPEDEF_UCHAR
typedef unsigned char uchar;
#endif
#ifndef TYPEDEF_USHORT
typedef unsigned short ushort;
#endif
#ifndef TYPEDEF_UINT
typedef unsigned int uint;
#endif
#ifndef TYPEDEF_ULONG
typedef unsigned long ulong;
#endif
/* define [u]int8/16/32/64, uintptr */
#ifndef TYPEDEF_UINT8
typedef unsigned char uint8;
#endif
#ifndef TYPEDEF_UINT16
typedef unsigned short uint16;
#endif
#ifndef TYPEDEF_UINT32
typedef unsigned int uint32;
#endif
#ifndef TYPEDEF_UINT64
typedef unsigned long long uint64;
#endif
#ifndef TYPEDEF_UINTPTR
typedef unsigned int uintptr;
#endif
#ifndef TYPEDEF_INT8
typedef signed char int8;
#endif
#ifndef TYPEDEF_INT16
typedef signed short int16;
#endif
#ifndef TYPEDEF_INT32
typedef signed int int32;
#endif
#ifndef TYPEDEF_INT64
typedef signed long long int64;
#endif
/* define float32/64, float_t */
#ifndef TYPEDEF_FLOAT32
typedef float float32;
#endif
#ifndef TYPEDEF_FLOAT64
typedef double float64;
#endif
/*
* abstracted floating point type allows for compile time selection of
* single or double precision arithmetic. Compiling with -DFLOAT32
* selects single precision; the default is double precision.
*/
#ifndef TYPEDEF_FLOAT_T
#if defined(FLOAT32)
typedef float32 float_t;
#else /* default to double precision floating point */
typedef float64 float_t;
#endif
#endif /* TYPEDEF_FLOAT_T */
/* define macro values */
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1 /* TRUE */
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef OFF
#define OFF 0
#endif
#ifndef ON
#define ON 1 /* ON = 1 */
#endif
#define AUTO (-1) /* Auto = -1 */
/* define PTRSZ, INLINE */
#ifndef PTRSZ
#define PTRSZ sizeof(char*)
#endif
#ifndef INLINE
#ifdef _MSC_VER
#define INLINE __inline
#elif __GNUC__
#define INLINE __inline__
#else
#define INLINE
#endif /* _MSC_VER */
#endif /* INLINE */
#undef TYPEDEF_BOOL
#undef TYPEDEF_UCHAR
#undef TYPEDEF_USHORT
#undef TYPEDEF_UINT
#undef TYPEDEF_ULONG
#undef TYPEDEF_UINT8
#undef TYPEDEF_UINT16
#undef TYPEDEF_UINT32
#undef TYPEDEF_UINT64
#undef TYPEDEF_UINTPTR
#undef TYPEDEF_INT8
#undef TYPEDEF_INT16
#undef TYPEDEF_INT32
#undef TYPEDEF_INT64
#undef TYPEDEF_FLOAT32
#undef TYPEDEF_FLOAT64
#undef TYPEDEF_FLOAT_T
#endif /* USE_TYPEDEF_DEFAULTS */
/*
* Including the bcmdefs.h here, to make sure everyone including typedefs.h
* gets this automatically
*/
#include "bcmdefs.h"
#endif /* _TYPEDEFS_H_ */

View file

@ -0,0 +1,315 @@
/*
* NVRAM variable manipulation (common)
*
* Copyright 2004, 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.
*
*/
#include <typedefs.h>
#include <osl.h>
#include <bcmendian.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <sbsdram.h>
extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value);
extern void BCMINIT(_nvram_free)(struct nvram_tuple *t);
extern int BCMINIT(_nvram_read)(void *buf);
char * BCMINIT(_nvram_get)(const char *name);
int BCMINIT(_nvram_set)(const char *name, const char *value);
int BCMINIT(_nvram_unset)(const char *name);
int BCMINIT(_nvram_getall)(char *buf, int count);
int BCMINIT(_nvram_commit)(struct nvram_header *header);
int BCMINIT(_nvram_init)(void);
void BCMINIT(_nvram_exit)(void);
static struct nvram_tuple * BCMINITDATA(nvram_hash)[257];
static struct nvram_tuple * nvram_dead;
/* Free all tuples. Should be locked. */
static void
BCMINITFN(nvram_free)(void)
{
uint i;
struct nvram_tuple *t, *next;
/* Free hash table */
for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
for (t = BCMINIT(nvram_hash)[i]; t; t = next) {
next = t->next;
BCMINIT(_nvram_free)(t);
}
BCMINIT(nvram_hash)[i] = NULL;
}
/* Free dead table */
for (t = nvram_dead; t; t = next) {
next = t->next;
BCMINIT(_nvram_free)(t);
}
nvram_dead = NULL;
/* Indicate to per-port code that all tuples have been freed */
BCMINIT(_nvram_free)(NULL);
}
/* String hash */
static INLINE uint
hash(const char *s)
{
uint hash = 0;
while (*s)
hash = 31 * hash + *s++;
return hash;
}
/* (Re)initialize the hash table. Should be locked. */
static int
BCMINITFN(nvram_rehash)(struct nvram_header *header)
{
char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq;
/* (Re)initialize hash table */
BCMINIT(nvram_free)();
/* Parse and set "name=value\0 ... \0\0" */
name = (char *) &header[1];
end = (char *) header + NVRAM_SPACE - 2;
end[0] = end[1] = '\0';
for (; *name; name = value + strlen(value) + 1) {
if (!(eq = strchr(name, '=')))
break;
*eq = '\0';
value = eq + 1;
BCMINIT(_nvram_set)(name, value);
*eq = '=';
}
/* Set special SDRAM parameters */
if (!BCMINIT(_nvram_get)("sdram_init")) {
sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16));
BCMINIT(_nvram_set)("sdram_init", buf);
}
if (!BCMINIT(_nvram_get)("sdram_config")) {
sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff));
BCMINIT(_nvram_set)("sdram_config", buf);
}
if (!BCMINIT(_nvram_get)("sdram_refresh")) {
sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff));
BCMINIT(_nvram_set)("sdram_refresh", buf);
}
if (!BCMINIT(_nvram_get)("sdram_ncdl")) {
sprintf(buf, "0x%08X", header->config_ncdl);
BCMINIT(_nvram_set)("sdram_ncdl", buf);
}
return 0;
}
/* Get the value of an NVRAM variable. Should be locked. */
char *
BCMINITFN(_nvram_get)(const char *name)
{
uint i;
struct nvram_tuple *t;
char *value;
if (!name)
return NULL;
/* Hash the name */
i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
/* Find the associated tuple in the hash table */
for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next);
value = t ? t->value : NULL;
return value;
}
/* Get the value of an NVRAM variable. Should be locked. */
int
BCMINITFN(_nvram_set)(const char *name, const char *value)
{
uint i;
struct nvram_tuple *t, *u, **prev;
/* Hash the name */
i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
/* Find the associated tuple in the hash table */
for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
/* (Re)allocate tuple */
if (!(u = BCMINIT(_nvram_realloc)(t, name, value)))
return -12; /* -ENOMEM */
/* Value reallocated */
if (t && t == u)
return 0;
/* Move old tuple to the dead table */
if (t) {
*prev = t->next;
t->next = nvram_dead;
nvram_dead = t;
}
/* Add new tuple to the hash table */
u->next = BCMINIT(nvram_hash)[i];
BCMINIT(nvram_hash)[i] = u;
return 0;
}
/* Unset the value of an NVRAM variable. Should be locked. */
int
BCMINITFN(_nvram_unset)(const char *name)
{
uint i;
struct nvram_tuple *t, **prev;
if (!name)
return 0;
/* Hash the name */
i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
/* Find the associated tuple in the hash table */
for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
/* Move it to the dead table */
if (t) {
*prev = t->next;
t->next = nvram_dead;
nvram_dead = t;
}
return 0;
}
/* Get all NVRAM variables. Should be locked. */
int
BCMINITFN(_nvram_getall)(char *buf, int count)
{
uint i;
struct nvram_tuple *t;
int len = 0;
bzero(buf, count);
/* Write name=value\0 ... \0\0 */
for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) {
if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1))
len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1;
else
break;
}
}
return 0;
}
/* Regenerate NVRAM. Should be locked. */
int
BCMINITFN(_nvram_commit)(struct nvram_header *header)
{
char *init, *config, *refresh, *ncdl;
char *ptr, *end;
int i;
struct nvram_tuple *t;
struct nvram_header tmp;
uint8 crc;
/* Regenerate header */
header->magic = NVRAM_MAGIC;
header->crc_ver_init = (NVRAM_VERSION << 8);
if (!(init = BCMINIT(_nvram_get)("sdram_init")) ||
!(config = BCMINIT(_nvram_get)("sdram_config")) ||
!(refresh = BCMINIT(_nvram_get)("sdram_refresh")) ||
!(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) {
header->crc_ver_init |= SDRAM_INIT << 16;
header->config_refresh = SDRAM_CONFIG;
header->config_refresh |= SDRAM_REFRESH << 16;
header->config_ncdl = 0;
} else {
header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16;
header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff;
header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16;
header->config_ncdl = bcm_strtoul(ncdl, NULL, 0);
}
/* Clear data area */
ptr = (char *) header + sizeof(struct nvram_header);
bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header));
/* Leave space for a double NUL at the end */
end = (char *) header + NVRAM_SPACE - 2;
/* Write out all tuples */
for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) {
if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end)
break;
ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1;
}
}
/* End with a double NUL */
ptr += 2;
/* Set new length */
header->len = ROUNDUP(ptr - (char *) header, 4);
/* Little-endian CRC8 over the last 11 bytes of the header */
tmp.crc_ver_init = htol32(header->crc_ver_init);
tmp.config_refresh = htol32(header->config_refresh);
tmp.config_ncdl = htol32(header->config_ncdl);
crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);
/* Continue CRC8 over data bytes */
crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc);
/* Set new CRC8 */
header->crc_ver_init |= crc;
/* Reinitialize hash table */
return BCMINIT(nvram_rehash)(header);
}
/* Initialize hash table. Should be locked. */
int
BCMINITFN(_nvram_init)(void)
{
struct nvram_header *header;
int ret;
if (!(header = (struct nvram_header *) kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
return -12; /* -ENOMEM */
}
if ((ret = BCMINIT(_nvram_read)(header)) == 0 &&
header->magic == NVRAM_MAGIC)
BCMINIT(nvram_rehash)(header);
kfree(header);
return ret;
}
/* Free hash table. Should be locked. */
void
BCMINITFN(_nvram_exit)(void)
{
BCMINIT(nvram_free)();
}

View file

@ -0,0 +1,716 @@
/*
* NVRAM variable manipulation (Linux kernel half)
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: nvram_linux.c,v 1.19 2006/04/08 07:12:42 honor Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/bootmem.h>
#include <linux/wrapper.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/mtd/mtd.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <typedefs.h>
#include <osl.h>
#include <bcmendian.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sbutils.h>
#include <hndmips.h>
#include <sflash.h>
/* In BSS to minimize text size and page aligned so it can be mmap()-ed */
static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
#ifdef MODULE
#define early_nvram_get(name) nvram_get(name)
#else /* !MODULE */
/* Global SB handle */
extern void *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
#define KB * 1024
#define MB * 1024 * 1024
/* Probe for NVRAM header */
static void __init
early_nvram_init(void)
{
struct nvram_header *header;
chipcregs_t *cc;
struct sflash *info = NULL;
int i;
uint32 base, off, lim;
u32 *src, *dst;
if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
base = KSEG1ADDR(SB_FLASH2);
switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
case PFLASH:
lim = SB_FLASH2_SZ;
break;
case SFLASH_ST:
case SFLASH_AT:
if ((info = sflash_init(cc)) == NULL)
return;
lim = info->size;
break;
case FLASH_NONE:
default:
return;
}
} else {
/* extif assumed, Stop at 4 MB */
base = KSEG1ADDR(SB_FLASH1);
lim = SB_FLASH1_SZ;
}
/* XXX: hack for supporting the CFE environment stuff on WGT634U */
src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000);
dst = (u32 *) nvram_buf;
if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) {
printk("early_nvram_init: WGT634U NVRAM found.\n");
for (i = 0; i < 0x1ff0; i++) {
if (*src == 0xFFFFFFFF)
break;
*dst++ = *src++;
}
return;
}
off = FLASH_MIN;
while (off <= lim) {
/* Windowed flash access */
header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
if (header->magic == NVRAM_MAGIC)
goto found;
off <<= 1;
}
/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
header = (struct nvram_header *) KSEG1ADDR(base + 4 KB);
if (header->magic == NVRAM_MAGIC)
goto found;
header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
if (header->magic == NVRAM_MAGIC)
goto found;
printk("early_nvram_init: NVRAM not found\n");
return;
found:
src = (u32 *) header;
dst = (u32 *) nvram_buf;
for (i = 0; i < sizeof(struct nvram_header); i += 4)
*dst++ = *src++;
for (; i < header->len && i < NVRAM_SPACE; i += 4)
*dst++ = ltoh32(*src++);
}
/* Early (before mm or mtd) read-only access to NVRAM */
static char * __init
early_nvram_get(const char *name)
{
char *var, *value, *end, *eq;
if (!name)
return NULL;
/* Too early? */
if (sbh == NULL)
return NULL;
if (!nvram_buf[0])
early_nvram_init();
/* Look for name=value and return value */
var = &nvram_buf[sizeof(struct nvram_header)];
end = nvram_buf + sizeof(nvram_buf) - 2;
end[0] = end[1] = '\0';
for (; *var; var = value + strlen(value) + 1) {
if (!(eq = strchr(var, '=')))
break;
value = eq + 1;
if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
return value;
}
return NULL;
}
static int __init
early_nvram_getall(char *buf, int count)
{
char *var, *end;
int len = 0;
/* Too early? */
if (sbh == NULL)
return -1;
if (!nvram_buf[0])
early_nvram_init();
bzero(buf, count);
/* Write name=value\0 ... \0\0 */
var = &nvram_buf[sizeof(struct nvram_header)];
end = nvram_buf + sizeof(nvram_buf) - 2;
end[0] = end[1] = '\0';
for (; *var; var += strlen(var) + 1) {
if ((count - len) <= (strlen(var) + 1))
break;
len += sprintf(buf + len, "%s", var) + 1;
}
return 0;
}
#endif /* !MODULE */
extern char * _nvram_get(const char *name);
extern int _nvram_set(const char *name, const char *value);
extern int _nvram_unset(const char *name);
extern int _nvram_getall(char *buf, int count);
extern int _nvram_commit(struct nvram_header *header);
extern int _nvram_init(void *sbh);
extern void _nvram_exit(void);
/* Globals */
static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
static struct semaphore nvram_sem;
static unsigned long nvram_offset = 0;
static int nvram_major = -1;
static devfs_handle_t nvram_handle = NULL;
static struct mtd_info *nvram_mtd = NULL;
int
_nvram_read(char *buf)
{
struct nvram_header *header = (struct nvram_header *) buf;
size_t len;
if (!nvram_mtd ||
MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
len != NVRAM_SPACE ||
header->magic != NVRAM_MAGIC) {
/* Maybe we can recover some data from early initialization */
memcpy(buf, nvram_buf, NVRAM_SPACE);
}
return 0;
}
struct nvram_tuple *
_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
{
if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE)
return NULL;
if (!t) {
if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
return NULL;
/* Copy name */
t->name = (char *) &t[1];
strcpy(t->name, name);
t->value = NULL;
}
/* Copy value */
if (!t->value || strcmp(t->value, value)) {
t->value = &nvram_buf[nvram_offset];
strcpy(t->value, value);
nvram_offset += strlen(value) + 1;
}
return t;
}
void
_nvram_free(struct nvram_tuple *t)
{
if (!t)
nvram_offset = 0;
else
kfree(t);
}
int
nvram_set(const char *name, const char *value)
{
unsigned long flags;
int ret;
struct nvram_header *header;
spin_lock_irqsave(&nvram_lock, flags);
if ((ret = _nvram_set(name, value))) {
/* Consolidate space and try again */
if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
if (_nvram_commit(header) == 0)
ret = _nvram_set(name, value);
kfree(header);
}
}
spin_unlock_irqrestore(&nvram_lock, flags);
return ret;
}
char *
real_nvram_get(const char *name)
{
unsigned long flags;
char *value;
spin_lock_irqsave(&nvram_lock, flags);
value = _nvram_get(name);
spin_unlock_irqrestore(&nvram_lock, flags);
return value;
}
char *
nvram_get(const char *name)
{
if (nvram_major >= 0)
return real_nvram_get(name);
else
return early_nvram_get(name);
}
int
nvram_unset(const char *name)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&nvram_lock, flags);
ret = _nvram_unset(name);
spin_unlock_irqrestore(&nvram_lock, flags);
return ret;
}
static void
erase_callback(struct erase_info *done)
{
wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
wake_up(wait_q);
}
int
nvram_commit(void)
{
char *buf;
size_t erasesize, len, magic_len;
unsigned int i;
int ret;
struct nvram_header *header;
unsigned long flags;
u_int32_t offset;
DECLARE_WAITQUEUE(wait, current);
wait_queue_head_t wait_q;
struct erase_info erase;
u_int32_t magic_offset = 0; /* Offset for writing MAGIC # */
if (!nvram_mtd) {
printk("nvram_commit: NVRAM not found\n");
return -ENODEV;
}
if (in_interrupt()) {
printk("nvram_commit: not committing in interrupt\n");
return -EINVAL;
}
/* Backup sector blocks to be erased */
erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
printk("nvram_commit: out of memory\n");
return -ENOMEM;
}
down(&nvram_sem);
if ((i = erasesize - NVRAM_SPACE) > 0) {
offset = nvram_mtd->size - erasesize;
len = 0;
ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
if (ret || len != i) {
printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
ret = -EIO;
goto done;
}
header = (struct nvram_header *)(buf + i);
magic_offset = i + ((void *)&header->magic - (void *)header);
} else {
offset = nvram_mtd->size - NVRAM_SPACE;
magic_offset = ((void *)&header->magic - (void *)header);
header = (struct nvram_header *)buf;
}
/* clear the existing magic # to mark the NVRAM as unusable
we can pull MAGIC bits low without erase */
header->magic = NVRAM_CLEAR_MAGIC; /* All zeros magic */
/* Unlock sector blocks (for Intel 28F320C3B flash) , 20060309 */
if(nvram_mtd->unlock)
nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
ret = MTD_WRITE(nvram_mtd, offset + magic_offset, sizeof(header->magic),
&magic_len, (char *)&header->magic);
if (ret || magic_len != sizeof(header->magic)) {
printk("nvram_commit: clear MAGIC error\n");
ret = -EIO;
goto done;
}
header->magic = NVRAM_MAGIC; /* reset MAGIC before we regenerate the NVRAM,
otherwise we'll have an incorrect CRC */
/* Regenerate NVRAM */
spin_lock_irqsave(&nvram_lock, flags);
ret = _nvram_commit(header);
spin_unlock_irqrestore(&nvram_lock, flags);
if (ret)
goto done;
/* Erase sector blocks */
init_waitqueue_head(&wait_q);
for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
erase.mtd = nvram_mtd;
erase.addr = offset;
erase.len = nvram_mtd->erasesize;
erase.callback = erase_callback;
erase.priv = (u_long) &wait_q;
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wait_q, &wait);
/* Unlock sector blocks */
if (nvram_mtd->unlock)
nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&wait_q, &wait);
printk("nvram_commit: erase error\n");
goto done;
}
/* Wait for erase to finish */
schedule();
remove_wait_queue(&wait_q, &wait);
}
/* Write partition up to end of data area */
header->magic = NVRAM_INVALID_MAGIC; /* All ones magic */
offset = nvram_mtd->size - erasesize;
i = erasesize - NVRAM_SPACE + header->len;
ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
if (ret || len != i) {
printk("nvram_commit: write error\n");
ret = -EIO;
goto done;
}
/* Now mark the NVRAM in flash as "valid" by setting the correct
MAGIC # */
header->magic = NVRAM_MAGIC;
ret = MTD_WRITE(nvram_mtd, offset + magic_offset, sizeof(header->magic),
&magic_len, (char *)&header->magic);
if (ret || magic_len != sizeof(header->magic)) {
printk("nvram_commit: write MAGIC error\n");
ret = -EIO;
goto done;
}
/*
* Reading a few bytes back here will put the device
* back to the correct mode on certain flashes */
offset = nvram_mtd->size - erasesize;
ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);
done:
up(&nvram_sem);
kfree(buf);
return ret;
}
int
nvram_getall(char *buf, int count)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&nvram_lock, flags);
if (nvram_major >= 0)
ret = _nvram_getall(buf, count);
else
ret = early_nvram_getall(buf, count);
spin_unlock_irqrestore(&nvram_lock, flags);
return ret;
}
/* User mode interface below */
static ssize_t
dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
char tmp[100], *name = tmp, *value;
ssize_t ret;
unsigned long off;
if (count > sizeof(tmp)) {
if (!(name = kmalloc(count, GFP_KERNEL)))
return -ENOMEM;
}
if (copy_from_user(name, buf, count)) {
ret = -EFAULT;
goto done;
}
if (*name == '\0') {
/* Get all variables */
ret = nvram_getall(name, count);
if (ret == 0) {
if (copy_to_user(buf, name, count)) {
ret = -EFAULT;
goto done;
}
ret = count;
}
} else {
if (!(value = nvram_get(name))) {
ret = 0;
goto done;
}
/* Provide the offset into mmap() space */
off = (unsigned long) value - (unsigned long) nvram_buf;
if (put_user(off, (unsigned long *) buf)) {
ret = -EFAULT;
goto done;
}
ret = sizeof(unsigned long);
}
flush_cache_all();
done:
if (name != tmp)
kfree(name);
return ret;
}
static ssize_t
dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
char tmp[100], *name = tmp, *value;
ssize_t ret;
if (count > sizeof(tmp)) {
if (!(name = kmalloc(count, GFP_KERNEL)))
return -ENOMEM;
}
if (copy_from_user(name, buf, count)) {
ret = -EFAULT;
goto done;
}
value = name;
name = strsep(&value, "=");
if (value)
ret = nvram_set(name, value) ? : count;
else
ret = nvram_unset(name) ? : count;
done:
if (name != tmp)
kfree(name);
return ret;
}
static int
dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
if (cmd != NVRAM_MAGIC)
return -EINVAL;
return nvram_commit();
}
static int
dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long offset = virt_to_phys(nvram_buf);
if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
return 0;
}
static int
dev_nvram_open(struct inode *inode, struct file * file)
{
MOD_INC_USE_COUNT;
return 0;
}
static int
dev_nvram_release(struct inode *inode, struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations dev_nvram_fops = {
owner: THIS_MODULE,
open: dev_nvram_open,
release: dev_nvram_release,
read: dev_nvram_read,
write: dev_nvram_write,
ioctl: dev_nvram_ioctl,
mmap: dev_nvram_mmap,
};
static void
dev_nvram_exit(void)
{
int order = 0;
struct page *page, *end;
if (nvram_handle)
devfs_unregister(nvram_handle);
if (nvram_major >= 0)
devfs_unregister_chrdev(nvram_major, "nvram");
if (nvram_mtd)
put_mtd_device(nvram_mtd);
while ((PAGE_SIZE << order) < NVRAM_SPACE)
order++;
end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
for (page = virt_to_page(nvram_buf); page <= end; page++)
mem_map_unreserve(page);
_nvram_exit();
}
static int __init
dev_nvram_init(void)
{
int order = 0, ret = 0;
struct page *page, *end;
unsigned int i;
/* Allocate and reserve memory to mmap() */
while ((PAGE_SIZE << order) < NVRAM_SPACE)
order++;
end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
for (page = virt_to_page(nvram_buf); page <= end; page++)
mem_map_reserve(page);
#ifdef CONFIG_MTD
/* Find associated MTD device */
for (i = 0; i < MAX_MTD_DEVICES; i++) {
nvram_mtd = get_mtd_device(NULL, i);
if (nvram_mtd) {
if (!strcmp(nvram_mtd->name, "nvram") &&
nvram_mtd->size >= NVRAM_SPACE)
break;
put_mtd_device(nvram_mtd);
}
}
if (i >= MAX_MTD_DEVICES)
nvram_mtd = NULL;
#endif
/* Initialize hash table lock */
spin_lock_init(&nvram_lock);
/* Initialize commit semaphore */
init_MUTEX(&nvram_sem);
/* Register char device */
if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
ret = nvram_major;
goto err;
}
/* Initialize hash table */
_nvram_init(sbh);
/* Create /dev/nvram handle */
nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL);
/* Set the SDRAM NCDL value into NVRAM if not already done */
if (getintvar(NULL, "sdram_ncdl") == 0) {
unsigned int ncdl;
char buf[] = "0x00000000";
if ((ncdl = sb_memc_get_ncdl(sbh))) {
sprintf(buf, "0x%08x", ncdl);
nvram_set("sdram_ncdl", buf);
nvram_commit();
}
}
return 0;
err:
dev_nvram_exit();
return ret;
}
module_init(dev_nvram_init);
module_exit(dev_nvram_exit);

View file

@ -0,0 +1,386 @@
/*
* Low-Level PCI and SB support for BCM47xx (Linux support code)
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: pcibios.c,v 1.1.1.9 2006/02/27 03:42:55 honor Exp $
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/paccess.h>
#include <typedefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <sbconfig.h>
#include <sbutils.h>
#include <hndpci.h>
#include <pcicfg.h>
#include <bcmdevs.h>
#include <bcmnvram.h>
/* Global SB handle */
extern sb_t *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
static int
sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, value, sizeof(*value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, value, sizeof(*value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, value, sizeof(*value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, &value, sizeof(value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, &value, sizeof(value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, &value, sizeof(value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pcibios_ops = {
sbpci_read_config_byte,
sbpci_read_config_word,
sbpci_read_config_dword,
sbpci_write_config_byte,
sbpci_write_config_word,
sbpci_write_config_dword
};
void __init
pcibios_init(void)
{
ulong flags;
if (!(sbh = sb_kattach()))
panic("sb_kattach failed");
spin_lock_init(&sbh_lock);
spin_lock_irqsave(&sbh_lock, flags);
sbpci_init(sbh);
spin_unlock_irqrestore(&sbh_lock, flags);
set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
/* Scan the SB bus */
pci_scan_bus(0, &pcibios_ops, NULL);
}
char * __init
pcibios_setup(char *str)
{
if (!strncmp(str, "ban=", 4)) {
sbpci_ban(simple_strtoul(str + 4, NULL, 0));
return NULL;
}
return (str);
}
static u32 pci_iobase = 0x100;
static u32 pci_membase = SB_PCI_DMA;
static u32 pcmcia_membase = 0x40004000;
void __init
pcibios_fixup_bus(struct pci_bus *b)
{
struct list_head *ln;
struct pci_dev *d;
struct resource *res;
int pos, size;
u32 *base;
u8 irq;
printk("PCI: Fixing up bus %d\n", b->number);
/* Fix up SB */
if (b->number == 0) {
for (ln = b->devices.next; ln != &b->devices; ln = ln->next) {
d = pci_dev_b(ln);
/* Fix up interrupt lines */
pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq);
d->irq = irq + 2;
pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
}
}
/* Fix up external PCI */
else {
for (ln = b->devices.next; ln != &b->devices; ln = ln->next) {
d = pci_dev_b(ln);
/* Fix up resource bases */
for (pos = 0; pos < 6; pos++) {
res = &d->resource[pos];
base = (res->flags & IORESOURCE_IO) ? &pci_iobase : ((b->number == 2) ? &pcmcia_membase : &pci_membase);
if (res->end) {
size = res->end - res->start + 1;
if (*base & (size - 1))
*base = (*base + size) & ~(size - 1);
res->start = *base;
res->end = res->start + size - 1;
*base += size;
pci_write_config_dword(d,
PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
}
/* Fix up PCI bridge BAR0 only */
if (b->number == 1 && PCI_SLOT(d->devfn) == 0)
break;
}
/* Fix up interrupt lines */
if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
}
}
}
unsigned int
pcibios_assign_all_busses(void)
{
return 1;
}
void
pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
}
int
pcibios_enable_resources(struct pci_dev *dev)
{
u16 cmd, old_cmd;
int idx;
struct resource *r;
/* External PCI only */
if (dev->bus->number == 0)
return 0;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
for (idx = 0; idx < 6; idx++) {
r = &dev->resource[idx];
if (r->flags & IORESOURCE_IO)
cmd |= PCI_COMMAND_IO;
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
if (dev->resource[PCI_ROM_RESOURCE].start)
cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
return 0;
}
int
pcibios_enable_device(struct pci_dev *dev, int mask)
{
ulong flags;
uint coreidx;
void *regs;
/* External PCI device enable */
if (dev->bus->number != 0)
return pcibios_enable_resources(dev);
/* These cores come out of reset enabled */
if (dev->device == SB_MIPS ||
dev->device == SB_MIPS33 ||
dev->device == SB_EXTIF ||
dev->device == SB_CC)
return 0;
spin_lock_irqsave(&sbh_lock, flags);
coreidx = sb_coreidx(sbh);
regs = sb_setcoreidx(sbh, PCI_SLOT(dev->devfn));
if (!regs)
return PCIBIOS_DEVICE_NOT_FOUND;
/*
* The USB core requires a special bit to be set during core
* reset to enable host (OHCI) mode. Resetting the SB core in
* pcibios_enable_device() is a hack for compatibility with
* vanilla usb-ohci so that it does not have to know about
* SB. A driver that wants to use the USB core in device mode
* should know about SB and should reset the bit back to 0
* after calling pcibios_enable_device().
*/
if (sb_coreid(sbh) == SB_USB) {
sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
sb_core_reset(sbh, 1 << 29, 0);
}
/*
* USB 2.0 special considerations:
*
* 1. Since the core supports both OHCI and EHCI functions, it must
* only be reset once.
*
* 2. In addition to the standard SB reset sequence, the Host Control
* Register must be programmed to bring the USB core and various
* phy components out of reset.
*/
else if (sb_coreid(sbh) == SB_USB20H) {
if (!sb_iscoreup(sbh)) {
sb_core_reset(sbh, 0, 0);
writel(0x7FF, (ulong)regs + 0x200);
udelay(1);
}
} else
sb_core_reset(sbh, 0, 0);
sb_setcoreidx(sbh, coreidx);
spin_unlock_irqrestore(&sbh_lock, flags);
return 0;
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
unsigned long where, size;
u32 reg;
/* External PCI only */
if (dev->bus->number == 0)
return;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
if (dev->bus->number == 1)
reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
else
reg = res->start;
pci_write_config_dword(dev, where, reg);
}
static void __init
quirk_sbpci_bridge(struct pci_dev *dev)
{
if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
return;
printk("PCI: Fixing up bridge\n");
/* Enable PCI bridge bus mastering and memory space */
pci_set_master(dev);
pcibios_enable_resources(dev);
/* Enable PCI bridge BAR1 prefetch and burst */
pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
}
struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge },
{ 0 }
};
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain crappy BIOSes forget to set it properly.
*/
unsigned int pcibios_max_latency = 255;
void pcibios_set_master(struct pci_dev *dev)
{
u8 lat;
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
if (lat < 16)
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
else if (lat > pcibios_max_latency)
lat = pcibios_max_latency;
else
return;
printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}

View file

@ -0,0 +1,41 @@
/*
* Early initialization code for BCM94710 boards
*
* Copyright 2004, 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: prom.c,v 1.1 2005/03/16 13:49:59 wbx Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/bootinfo.h>
void __init
prom_init(int argc, const char **argv)
{
unsigned long mem;
mips_machgroup = MACH_GROUP_BRCM;
mips_machtype = MACH_BCM947XX;
/* Figure out memory size by finding aliases */
for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
*(unsigned long *)(prom_init))
break;
}
add_memory_region(0, mem, BOOT_MEM_RAM);
}
void __init
prom_free_prom_memory(void)
{
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,768 @@
/*
* Low-Level PCI and SB support for BCM47xx
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: hndpci.c,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $
*/
#include <typedefs.h>
#include <osl.h>
#include <pcicfg.h>
#include <bcmdevs.h>
#include <sbconfig.h>
#include <bcmutils.h>
#include <sbutils.h>
#include <sbpci.h>
#include <bcmendian.h>
#include <bcmnvram.h>
#include <hndcpu.h>
#include <hndmips.h>
#include <hndpci.h>
/* debug/trace */
#ifdef BCMDBG_PCI
#define PCI_MSG(args) printf args
#else
#define PCI_MSG(args)
#endif /* BCMDBG_PCI */
/* Can free sbpci_init() memory after boot */
#ifndef linux
#define __init
#endif /* linux */
/* Emulated configuration space */
typedef struct {
int n;
uint size0;
uint size1;
uint size2;
uint size3;
} sb_bar_cfg_t;
static pci_config_regs sb_config_regs[SB_MAXCORES];
static sb_bar_cfg_t sb_bar_cfg[SB_MAXCORES];
/* Links to emulated and real PCI configuration spaces */
#define MAXFUNCS 2
typedef struct {
pci_config_regs *emu; /* emulated PCI config */
pci_config_regs *pci; /* real PCI config */
sb_bar_cfg_t *bar; /* region sizes */
} sb_pci_cfg_t;
static sb_pci_cfg_t sb_pci_cfg[SB_MAXCORES][MAXFUNCS];
/* Special emulated config space for non-existing device */
static pci_config_regs sb_pci_null = { 0xffff, 0xffff };
/* Banned cores */
static uint16 pci_ban[SB_MAXCORES] = { 0 };
static uint pci_banned = 0;
/* CardBus mode */
static bool cardbus = FALSE;
/* Disable PCI host core */
static bool pci_disabled = FALSE;
/* Host bridge slot #, default to 0 */
static uint8 pci_hbslot = 0;
/* Internal macros */
#define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
#define PCI_HBSBCFG_REV 8 /* MIN. core rev. required to
* access host bridge PCI cfg space
* from SB
*/
/*
* Functions for accessing external PCI configuration space
*/
/* Assume one-hot slot wiring */
#define PCI_SLOT_MAX 16 /* Max. PCI Slots */
static uint32
config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
{
uint coreidx;
sbpciregs_t *regs;
uint32 addr = 0;
osl_t *osh;
/* CardBusMode supports only one device */
if (cardbus && dev > 1)
return 0;
osh = sb_osh(sbh);
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) {
uint32 win;
/* Slide the PCI window to the appropriate slot */
win = (SBTOPCI_CFG0 | ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
W_REG(osh, &regs->sbtopci1, win);
addr = SB_PCI_CFG |
((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
(func << PCICFG_FUN_SHIFT) |
(off & ~3);
}
} else {
/* Type 1 transaction */
W_REG(osh, &regs->sbtopci1, SBTOPCI_CFG1);
addr = SB_PCI_CFG |
(bus << PCICFG_BUS_SHIFT) |
(dev << PCICFG_SLOT_SHIFT) |
(func << PCICFG_FUN_SHIFT) |
(off & ~3);
}
sb_setcoreidx(sbh, coreidx);
return addr;
}
/*
* Read host bridge PCI config registers from Silicon Backplane (>=rev8).
*
* It returns TRUE to indicate that access to the host bridge's pci config
* from SB is ok, and values in 'addr' and 'val' are valid.
*
* It can only read registers at multiple of 4-bytes. Callers must pick up
* needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
* the register address where value in 'val' is read.
*/
static bool
sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off,
uint32 **addr, uint32 *val)
{
sbpciregs_t *regs;
osl_t *osh;
uint coreidx;
bool ret = FALSE;
/* sanity check */
ASSERT(bus == 1);
ASSERT(dev == pci_hbslot);
ASSERT(func == 0);
osh = sb_osh(sbh);
/* read pci config when core rev >= 8 */
coreidx = sb_coreidx(sbh);
regs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
if (regs && sb_corerev(sbh) >= PCI_HBSBCFG_REV) {
*addr = (uint32 *)&regs->pcicfg[func][off >> 2];
*val = R_REG(osh, *addr);
ret = TRUE;
}
sb_setcoreidx(sbh, coreidx);
return ret;
}
int
extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
uint32 addr = 0, *reg = NULL, val;
int ret = 0;
/*
* Set value to -1 when:
* flag 'pci_disabled' is true;
* value of 'addr' is zero;
* REG_MAP() fails;
* BUSPROBE() fails;
*/
if (pci_disabled)
val = 0xffffffff;
else if (bus == 1 && dev == pci_hbslot && func == 0 &&
sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
;
else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
(BUSPROBE(val, reg) != 0))
val = 0xffffffff;
PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
__FUNCTION__, val, reg, addr, len, off, buf));
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 && addr)
REG_UNMAP(reg);
return ret;
}
int
extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
osl_t *osh;
uint32 addr = 0, *reg = NULL, val;
int ret = 0;
osh = sb_osh(sbh);
/*
* Ignore write attempt when:
* flag 'pci_disabled' is true;
* value of 'addr' is zero;
* REG_MAP() fails;
* BUSPROBE() fails;
*/
if (pci_disabled)
return 0;
else if (bus == 1 && dev == pci_hbslot && func == 0 &&
sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
;
else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
((reg = (uint32 *) REG_MAP(addr, len)) == 0) ||
(BUSPROBE(val, reg) != 0))
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;
goto done;
}
PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg));
W_REG(osh, reg, val);
done:
if (reg && addr)
REG_UNMAP(reg);
return ret;
}
/*
* Must access emulated PCI configuration at these locations even when
* the real PCI config space exists and is accessible.
*
* PCI_CFG_VID (0x00)
* PCI_CFG_DID (0x02)
* PCI_CFG_PROGIF (0x09)
* PCI_CFG_SUBCL (0x0a)
* PCI_CFG_BASECL (0x0b)
* PCI_CFG_HDR (0x0e)
* PCI_CFG_INT (0x3c)
* PCI_CFG_PIN (0x3d)
*/
#define FORCE_EMUCFG(off, len) \
((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
(off == PCI_CFG_PROGIF) || \
(off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
(off == PCI_CFG_HDR) || \
(off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
/* Sync the emulation registers and the real PCI config registers. */
static void
sb_pcid_read_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
uint off, uint len)
{
osl_t *osh;
uint oldidx;
ASSERT(cfg);
ASSERT(cfg->emu);
ASSERT(cfg->pci);
/* decide if real PCI config register access is necessary */
if (FORCE_EMUCFG(off, len))
return;
osh = sb_osh(sbh);
/* access to the real pci config space only when the core is up */
oldidx = sb_coreidx(sbh);
sb_setcoreidx(sbh, coreidx);
if (sb_iscoreup(sbh)) {
if (len == 4)
*(uint32 *)((ulong)cfg->emu + off) =
htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off)));
else if (len == 2)
*(uint16 *)((ulong)cfg->emu + off) =
htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off)));
else if (len == 1)
*(uint8 *)((ulong)cfg->emu + off) =
R_REG(osh, (uint8 *)((ulong)cfg->pci + off));
}
sb_setcoreidx(sbh, oldidx);
}
static void
sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
uint off, uint len)
{
osl_t *osh;
uint oldidx;
ASSERT(cfg);
ASSERT(cfg->emu);
ASSERT(cfg->pci);
osh = sb_osh(sbh);
/* decide if real PCI config register access is necessary */
if (FORCE_EMUCFG(off, len))
return;
/* access to the real pci config space only when the core is up */
oldidx = sb_coreidx(sbh);
sb_setcoreidx(sbh, coreidx);
if (sb_iscoreup(sbh)) {
if (len == 4)
W_REG(osh, (uint32 *)((ulong)cfg->pci + off),
ltoh32(*(uint32 *)((ulong)cfg->emu + off)));
else if (len == 2)
W_REG(osh, (uint16 *)((ulong)cfg->pci + off),
ltoh16(*(uint16 *)((ulong)cfg->emu + off)));
else if (len == 1)
W_REG(osh, (uint8 *)((ulong)cfg->pci + off),
*(uint8 *)((ulong)cfg->emu + off));
}
sb_setcoreidx(sbh, oldidx);
}
/*
* Functions for accessing translated SB configuration space
*/
static int
sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
pci_config_regs *cfg;
if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
return -1;
cfg = sb_pci_cfg[dev][func].emu;
ASSERT(ISALIGNED(off, len));
ASSERT(ISALIGNED((uintptr)buf, len));
/* use special config space if the device does not exist */
if (!cfg)
cfg = &sb_pci_null;
/* sync emulation with real PCI config if necessary */
else if (sb_pci_cfg[dev][func].pci)
sb_pcid_read_config(sbh, dev, &sb_pci_cfg[dev][func], off, 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(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
uint coreidx;
void *regs;
pci_config_regs *cfg;
osl_t *osh;
sb_bar_cfg_t *bar;
if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
return -1;
cfg = sb_pci_cfg[dev][func].emu;
if (!cfg)
return -1;
ASSERT(ISALIGNED(off, len));
ASSERT(ISALIGNED((uintptr)buf, len));
osh = sb_osh(sbh);
/* 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))) {
bar = sb_pci_cfg[dev][func].bar;
/* Highest numbered address match register */
if (off == OFFSETOF(pci_config_regs, base[0]))
cfg->base[0] = ~(bar->size0 - 1);
else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1)
cfg->base[1] = ~(bar->size1 - 1);
else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2)
cfg->base[2] = ~(bar->size2 - 1);
else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3)
cfg->base[3] = ~(bar->size3 - 1);
}
sb_setcoreidx(sbh, coreidx);
}
else 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;
/* sync emulation with real PCI config if necessary */
if (sb_pci_cfg[dev][func].pci)
sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
return 0;
}
int
sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
if (bus == 0)
return sb_read_config(sbh, bus, dev, func, off, buf, len);
else
return extpci_read_config(sbh, bus, dev, func, off, buf, len);
}
int
sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
if (bus == 0)
return sb_write_config(sbh, bus, dev, func, off, buf, len);
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;
}
/*
* Initiliaze PCI core. Return 0 after a successful initialization.
* Otherwise return -1 to indicate there is no PCI core and return 1
* to indicate PCI core is disabled.
*/
int __init
sbpci_init_pci(sb_t *sbh)
{
uint chip, chiprev, chippkg, host;
uint32 boardflags;
sbpciregs_t *pci;
sbconfig_t *sb;
uint32 val;
int ret = 0;
char *hbslot;
osl_t *osh;
chip = sb_chip(sbh);
chiprev = sb_chiprev(sbh);
chippkg = sb_chippkg(sbh);
osh = sb_osh(sbh);
if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) {
printk("PCI: no core\n");
pci_disabled = TRUE;
return -1;
}
if ((chip == 0x4310) && (chiprev == 0))
pci_disabled = TRUE;
sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
boardflags = (uint32) getintvar(NULL, "boardflags");
/*
* The 200-pin BCM4712 package does not bond out PCI. Even when
* PCI is bonded out, some boards may leave the pins
* floating.
*/
if (((chip == BCM4712_CHIP_ID) &&
((chippkg == BCM4712SMALL_PKG_ID) ||
(chippkg == BCM4712MID_PKG_ID))) ||
(boardflags & BFL_NOPCI))
pci_disabled = TRUE;
/* Enable the core */
sb_core_reset(sbh, 0, 0);
/*
* If the PCI core should not be touched (disabled, not bonded
* out, or pins floating), do not even attempt to access core
* registers. Otherwise, try to determine if it is in host
* mode.
*/
if (pci_disabled)
host = 0;
else
host = !BUSPROBE(val, &pci->control);
if (!host) {
ret = 1;
/* Disable PCI interrupts in client mode */
W_REG(osh, &sb->sbintvec, 0);
/* Disable the PCI bridge in client mode */
sbpci_ban(SB_PCI);
sb_core_disable(sbh, 0);
printk("PCI: Disabled\n");
} else {
printk("PCI: Initializing host\n");
/* Disable PCI SBReqeustTimeout for BCM4785 */
if (chip == BCM4785_CHIP_ID) {
AND_REG(osh, &sb->sbimconfiglow, ~0x00000070);
sb_commit(sbh);
}
/* Reset the external PCI bus and enable the clock */
W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */
W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */
OSL_DELAY(150); /* delay > 100 us */
W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */
/* Use internal arbiter and park REQ/GRNT at external master 0 */
W_REG(osh, &pci->arbcontrol, PCI_INT_ARB);
OSL_DELAY(1); /* delay 1 us */
if (sb_corerev(sbh) >= 8) {
val = getintvar(NULL, "parkid");
ASSERT(val <= PCI_PARKID_LAST);
OR_REG(osh, &pci->arbcontrol, val << PCI_PARKID_SHIFT);
OSL_DELAY(1);
}
/* Enable CardBusMode */
cardbus = getintvar(NULL, "cardbus") == 1;
if (cardbus) {
printk("PCI: Enabling CardBus\n");
/* GPIO 1 resets the CardBus device on bcm94710ap */
sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY);
sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY);
W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400);
}
/* 64 MB I/O access window */
W_REG(osh, &pci->sbtopci0, SBTOPCI_IO);
/* 64 MB configuration access window */
W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0);
/* 1 GB memory access window */
W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA);
/* Host bridge slot # nvram overwrite */
if ((hbslot = nvram_get("pcihbslot"))) {
pci_hbslot = bcm_strtoul(hbslot, NULL, 0);
ASSERT(pci_hbslot < PCI_MAX_DEVICES);
}
/* Enable PCI bridge BAR0 prefetch and burst */
val = 6;
sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val));
/* Enable PCI interrupts */
W_REG(osh, &pci->intmask, PCI_INTA);
}
return ret;
}
/*
* Get the PCI region address and size information.
*/
static void __init
sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar)
{
osl_t *osh;
uint16 coreid;
void *regs;
sbconfig_t *sb;
uint32 base;
osh = sb_osh(sbh);
coreid = sb_coreid(sbh);
regs = sb_coreregs(sbh);
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
switch (coreid) {
case SB_USB20H:
base = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */
cfg->base[1] = 0;
cfg->base[2] = 0;
cfg->base[3] = 0;
cfg->base[4] = 0;
cfg->base[5] = 0;
bar->n = 1;
bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */
bar->size1 = 0;
bar->size2 = 0;
bar->size3 = 0;
break;
default:
cfg->base[0] = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
cfg->base[1] = htol32(sb_base(R_REG(osh, &sb->sbadmatch1)));
cfg->base[2] = htol32(sb_base(R_REG(osh, &sb->sbadmatch2)));
cfg->base[3] = htol32(sb_base(R_REG(osh, &sb->sbadmatch3)));
cfg->base[4] = 0;
cfg->base[5] = 0;
bar->n = (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0));
bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1));
bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2));
bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3));
break;
}
}
/*
* Construct PCI config spaces for SB cores so that they
* can be accessed as if they were PCI devices.
*/
static void __init
sbpci_init_cores(sb_t *sbh)
{
uint chiprev, coreidx, i;
sbconfig_t *sb;
pci_config_regs *cfg, *pci;
sb_bar_cfg_t *bar;
void *regs;
osl_t *osh;
uint16 vendor, device;
uint16 coreid;
uint8 class, subclass, progif;
uint dev;
uint8 header;
uint func;
chiprev = sb_chiprev(sbh);
coreidx = sb_coreidx(sbh);
osh = sb_osh(sbh);
/* Scan the SB bus */
bzero(sb_config_regs, sizeof(sb_config_regs));
bzero(sb_bar_cfg, sizeof(sb_bar_cfg));
bzero(sb_pci_cfg, sizeof(sb_pci_cfg));
memset(&sb_pci_null, -1, sizeof(sb_pci_null));
cfg = sb_config_regs;
bar = sb_bar_cfg;
for (dev = 0; dev < SB_MAXCORES; dev ++) {
/* Check if the core exists */
if (!(regs = sb_setcoreidx(sbh, dev)))
continue;
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
/* Check if this core is banned */
coreid = sb_coreid(sbh);
for (i = 0; i < pci_banned; i++)
if (coreid == pci_ban[i])
break;
if (i < pci_banned)
continue;
for (func = 0; func < MAXFUNCS; ++func) {
/* Make sure we won't go beyond the limit */
if (cfg >= &sb_config_regs[SB_MAXCORES]) {
printk("PCI: too many emulated devices\n");
goto done;
}
/* Convert core id to pci id */
if (sb_corepciid(sbh, func, &vendor, &device, &class, &subclass,
&progif, &header))
continue;
/*
* Differentiate real PCI config from emulated.
* non zero 'pci' indicate there is a real PCI config space
* for this device.
*/
switch (device) {
case BCM47XX_GIGETH_ID:
pci = (pci_config_regs *)((uint32)regs + 0x800);
break;
case BCM47XX_SATAXOR_ID:
pci = (pci_config_regs *)((uint32)regs + 0x400);
break;
case BCM47XX_ATA100_ID:
pci = (pci_config_regs *)((uint32)regs + 0x800);
break;
default:
pci = NULL;
break;
}
/* Supported translations */
cfg->vendor = htol16(vendor);
cfg->device = htol16(device);
cfg->rev_id = chiprev;
cfg->prog_if = progif;
cfg->sub_class = subclass;
cfg->base_class = class;
cfg->header_type = header;
sbpci_init_regions(sbh, func, cfg, bar);
/* Save core interrupt flag */
cfg->int_pin = R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
/* Save core interrupt assignment */
cfg->int_line = sb_irq(sbh);
/* Indicate there is no SROM */
*((uint32 *) &cfg->sprom_control) = 0xffffffff;
/* Point to the PCI config spaces */
sb_pci_cfg[dev][func].emu = cfg;
sb_pci_cfg[dev][func].pci = pci;
sb_pci_cfg[dev][func].bar = bar;
cfg ++;
bar ++;
}
}
done:
sb_setcoreidx(sbh, coreidx);
}
/*
* Initialize PCI core and construct PCI config spaces for SB cores.
* Must propagate sbpci_init_pci() return value to the caller to let
* them know the PCI core initialization status.
*/
int __init
sbpci_init(sb_t *sbh)
{
int status = sbpci_init_pci(sbh);
sbpci_init_cores(sbh);
return status;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,241 @@
/*
* Generic setup routines for Broadcom MIPS boards
*
* Copyright (C) 2005 Felix Fietkau <nbd@openwrt.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.
*
*
* Copyright 2005, 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.
*
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/serialP.h>
#include <linux/ide.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/time.h>
#include <asm/reboot.h>
#include <typedefs.h>
#include <osl.h>
#include <sbutils.h>
#include <bcmutils.h>
#include <bcmnvram.h>
#include <sbhndmips.h>
#include <hndmips.h>
#include <trxhdr.h>
/* Virtual IRQ base, after last hw IRQ */
#define SBMIPS_VIRTIRQ_BASE 6
/* # IRQs, hw and sw IRQs */
#define SBMIPS_NUMIRQS 8
/* Global SB handle */
sb_t *bcm947xx_sbh = NULL;
spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
extern void bcm947xx_time_init(void);
extern void bcm947xx_timer_setup(struct irqaction *irq);
#ifdef CONFIG_REMOTE_DEBUG
extern void set_debug_traps(void);
extern void rs_kgdb_hook(struct serial_state *);
extern void breakpoint(void);
#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
extern struct ide_ops std_ide_ops;
#endif
/* Kernel command line */
char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE;
extern void sb_serial_init(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift));
void
bcm947xx_machine_restart(char *command)
{
printk("Please stand by while rebooting the system...\n");
/* Set the watchdog timer to reset immediately */
__cli();
sb_watchdog(sbh, 1);
while (1);
}
void
bcm947xx_machine_halt(void)
{
printk("System halted\n");
/* Disable interrupts and watchdog and spin forever */
__cli();
sb_watchdog(sbh, 0);
while (1);
}
#ifdef CONFIG_SERIAL
static int ser_line = 0;
typedef struct {
void *regs;
uint irq;
uint baud_base;
uint reg_shift;
} serial_port;
static serial_port ports[4];
static int num_ports = 0;
static void
serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
{
ports[num_ports].regs = regs;
ports[num_ports].irq = irq;
ports[num_ports].baud_base = baud_base;
ports[num_ports].reg_shift = reg_shift;
num_ports++;
}
static void
do_serial_add(serial_port *port)
{
void *regs;
uint irq;
uint baud_base;
uint reg_shift;
struct serial_struct s;
regs = port->regs;
irq = port->irq;
baud_base = port->baud_base;
reg_shift = port->reg_shift;
memset(&s, 0, sizeof(s));
s.line = ser_line++;
s.iomem_base = regs;
s.irq = irq + 2;
s.baud_base = baud_base / 16;
s.flags = ASYNC_BOOT_AUTOCONF;
s.io_type = SERIAL_IO_MEM;
s.iomem_reg_shift = reg_shift;
if (early_serial_setup(&s) != 0) {
printk(KERN_ERR "Serial setup failed!\n");
}
}
#endif /* CONFIG_SERIAL */
void __init
brcm_setup(void)
{
char *s;
int i;
char *value;
/* Get global SB handle */
sbh = sb_kattach();
/* Initialize clocks and interrupts */
sb_mips_init(sbh, SBMIPS_VIRTIRQ_BASE);
if (BCM330X(current_cpu_data.processor_id) &&
(read_c0_diag() & BRCM_PFC_AVAIL)) {
/*
* Now that the sbh is inited set the proper PFC value
*/
printk("Setting the PFC to its default value\n");
enable_pfc(PFC_AUTO);
}
#ifdef CONFIG_SERIAL
sb_serial_init(sbh, serial_add);
/* reverse serial ports if nvram variable starts with console=ttyS1 */
/* Initialize UARTs */
s = nvram_get("kernel_args");
if (!s) s = "";
if (!strncmp(s, "console=ttyS1", 13)) {
for (i = num_ports; i; i--)
do_serial_add(&ports[i - 1]);
} else {
for (i = 0; i < num_ports; i++)
do_serial_add(&ports[i]);
}
#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ide_ops = &std_ide_ops;
#endif
/* Override default command line arguments */
value = nvram_get("kernel_cmdline");
if (value && strlen(value) && strncmp(value, "empty", 5))
strncpy(arcs_cmdline, value, sizeof(arcs_cmdline));
/* Generic setup */
_machine_restart = bcm947xx_machine_restart;
_machine_halt = bcm947xx_machine_halt;
_machine_power_off = bcm947xx_machine_halt;
board_time_init = bcm947xx_time_init;
board_timer_setup = bcm947xx_timer_setup;
}
const char *
get_system_type(void)
{
static char s[32];
if (bcm947xx_sbh) {
sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh),
sb_chiprev(bcm947xx_sbh));
return s;
}
else
return "Broadcom BCM947XX";
}
void __init
bus_error_init(void)
{
}

View file

@ -0,0 +1,422 @@
/*
* Broadcom SiliconBackplane chipcommon serial flash interface
*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sflash.c,v 1.1.1.13 2006/02/27 03:43:16 honor Exp $
*/
#include <osl.h>
#include <typedefs.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <mipsinc.h>
#include <bcmutils.h>
#include <bcmdevs.h>
#include <sflash.h>
/* Private global state */
static struct sflash sflash;
/* Issue a serial flash command */
static INLINE void
sflash_cmd(chipcregs_t *cc, uint opcode)
{
W_REG(NULL, &cc->flashcontrol, SFLASH_START | opcode);
while (R_REG(NULL, &cc->flashcontrol) & SFLASH_BUSY);
}
/* Initialize serial flash access */
struct sflash *
sflash_init(chipcregs_t *cc)
{
uint32 id, id2;
bzero(&sflash, sizeof(sflash));
sflash.type = R_REG(NULL, &cc->capabilities) & CAP_FLASH_MASK;
switch (sflash.type) {
case SFLASH_ST:
/* Probe for ST chips */
sflash_cmd(cc, SFLASH_ST_DP);
sflash_cmd(cc, SFLASH_ST_RES);
id = R_REG(NULL, &cc->flashdata);
switch (id) {
case 0x11:
/* ST M25P20 2 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 4;
break;
case 0x12:
/* ST M25P40 4 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 8;
break;
case 0x13:
/* ST M25P80 8 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 16;
break;
case 0x14:
/* ST M25P16 16 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 32;
break;
case 0x15:
/* ST M25P32 32 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 64;
break;
case 0x16:
/* ST M25P64 64 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 128;
break;
case 0xbf:
W_REG(NULL, &cc->flashaddress, 1);
sflash_cmd(cc, SFLASH_ST_RES);
id2 = R_REG(NULL, &cc->flashdata);
if (id2 == 0x44) {
/* SST M25VF80 4 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 8;
}
break;
}
break;
case SFLASH_AT:
/* Probe for Atmel chips */
sflash_cmd(cc, SFLASH_AT_STATUS);
id = R_REG(NULL, &cc->flashdata) & 0x3c;
switch (id) {
case 0xc:
/* Atmel AT45DB011 1Mbit Serial Flash */
sflash.blocksize = 256;
sflash.numblocks = 512;
break;
case 0x14:
/* Atmel AT45DB021 2Mbit Serial Flash */
sflash.blocksize = 256;
sflash.numblocks = 1024;
break;
case 0x1c:
/* Atmel AT45DB041 4Mbit Serial Flash */
sflash.blocksize = 256;
sflash.numblocks = 2048;
break;
case 0x24:
/* Atmel AT45DB081 8Mbit Serial Flash */
sflash.blocksize = 256;
sflash.numblocks = 4096;
break;
case 0x2c:
/* Atmel AT45DB161 16Mbit Serial Flash */
sflash.blocksize = 512;
sflash.numblocks = 4096;
break;
case 0x34:
/* Atmel AT45DB321 32Mbit Serial Flash */
sflash.blocksize = 512;
sflash.numblocks = 8192;
break;
case 0x3c:
/* Atmel AT45DB642 64Mbit Serial Flash */
sflash.blocksize = 1024;
sflash.numblocks = 8192;
break;
}
break;
}
sflash.size = sflash.blocksize * sflash.numblocks;
return sflash.size ? &sflash : NULL;
}
/* Read len bytes starting at offset into buf. Returns number of bytes read. */
int
sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf)
{
int cnt;
uint32 *from, *to;
if (!len)
return 0;
if ((offset + len) > sflash.size)
return -22;
if ((len >= 4) && (offset & 3))
cnt = 4 - (offset & 3);
else if ((len >= 4) && ((uint32)buf & 3))
cnt = 4 - ((uint32)buf & 3);
else
cnt = len;
from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset);
to = (uint32 *)buf;
if (cnt < 4) {
bcopy(from, to, cnt);
return cnt;
}
while (cnt >= 4) {
*to++ = *from++;
cnt -= 4;
}
return (len - cnt);
}
/* Poll for command completion. Returns zero when complete. */
int
sflash_poll(chipcregs_t *cc, uint offset)
{
if (offset >= sflash.size)
return -22;
switch (sflash.type) {
case SFLASH_ST:
/* Check for ST Write In Progress bit */
sflash_cmd(cc, SFLASH_ST_RDSR);
return R_REG(NULL, &cc->flashdata) & SFLASH_ST_WIP;
case SFLASH_AT:
/* Check for Atmel Ready bit */
sflash_cmd(cc, SFLASH_AT_STATUS);
return !(R_REG(NULL, &cc->flashdata) & SFLASH_AT_READY);
}
return 0;
}
/* Write len bytes starting at offset into buf. Returns number of bytes
* written. Caller should poll for completion.
*/
int
sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
{
struct sflash *sfl;
int ret = 0;
bool is4712b0;
uint32 page, byte, mask;
if (!len)
return 0;
if ((offset + len) > sflash.size)
return -22;
sfl = &sflash;
switch (sfl->type) {
case SFLASH_ST:
mask = R_REG(NULL, &cc->chipid);
is4712b0 = (((mask & CID_ID_MASK) == BCM4712_CHIP_ID) &&
((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT)));
/* Enable writes */
sflash_cmd(cc, SFLASH_ST_WREN);
if (is4712b0) {
mask = 1 << 14;
W_REG(NULL, &cc->flashaddress, offset);
W_REG(NULL, &cc->flashdata, *buf++);
/* Set chip select */
OR_REG(NULL, &cc->gpioout, mask);
/* Issue a page program with the first byte */
sflash_cmd(cc, SFLASH_ST_PP);
ret = 1;
offset++;
len--;
while (len > 0) {
if ((offset & 255) == 0) {
/* Page boundary, drop cs and return */
AND_REG(NULL, &cc->gpioout, ~mask);
if (!sflash_poll(cc, offset)) {
/* Flash rejected command */
return -11;
}
return ret;
} else {
/* Write single byte */
sflash_cmd(cc, *buf++);
}
ret++;
offset++;
len--;
}
/* All done, drop cs if needed */
if ((offset & 255) != 1) {
/* Drop cs */
AND_REG(NULL, &cc->gpioout, ~mask);
if (!sflash_poll(cc, offset)) {
/* Flash rejected command */
return -12;
}
}
} else {
ret = 1;
W_REG(NULL, &cc->flashaddress, offset);
W_REG(NULL, &cc->flashdata, *buf);
/* Page program */
sflash_cmd(cc, SFLASH_ST_PP);
}
break;
case SFLASH_AT:
mask = sfl->blocksize - 1;
page = (offset & ~mask) << 1;
byte = offset & mask;
/* Read main memory page into buffer 1 */
if (byte || (len < sfl->blocksize)) {
W_REG(NULL, &cc->flashaddress, page);
sflash_cmd(cc, SFLASH_AT_BUF1_LOAD);
/* 250 us for AT45DB321B */
SPINWAIT(sflash_poll(cc, offset), 1000);
ASSERT(!sflash_poll(cc, offset));
}
/* Write into buffer 1 */
for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) {
W_REG(NULL, &cc->flashaddress, byte++);
W_REG(NULL, &cc->flashdata, *buf++);
sflash_cmd(cc, SFLASH_AT_BUF1_WRITE);
}
/* Write buffer 1 into main memory page */
W_REG(NULL, &cc->flashaddress, page);
sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM);
break;
}
return ret;
}
/* Erase a region. Returns number of bytes scheduled for erasure.
* Caller should poll for completion.
*/
int
sflash_erase(chipcregs_t *cc, uint offset)
{
struct sflash *sfl;
if (offset >= sflash.size)
return -22;
sfl = &sflash;
switch (sfl->type) {
case SFLASH_ST:
sflash_cmd(cc, SFLASH_ST_WREN);
W_REG(NULL, &cc->flashaddress, offset);
sflash_cmd(cc, SFLASH_ST_SE);
return sfl->blocksize;
case SFLASH_AT:
W_REG(NULL, &cc->flashaddress, offset << 1);
sflash_cmd(cc, SFLASH_AT_PAGE_ERASE);
return sfl->blocksize;
}
return 0;
}
/*
* writes the appropriate range of flash, a NULL buf simply erases
* the region of flash
*/
int
sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
{
struct sflash *sfl;
uchar *block = NULL, *cur_ptr, *blk_ptr;
uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
uint blk_offset, blk_len, copied;
int bytes, ret = 0;
/* Check address range */
if (len <= 0)
return 0;
sfl = &sflash;
if ((offset + len) > sfl->size)
return -1;
blocksize = sfl->blocksize;
mask = blocksize - 1;
/* Allocate a block of mem */
if (!(block = MALLOC(NULL, blocksize)))
return -1;
while (len) {
/* Align offset */
cur_offset = offset & ~mask;
cur_length = blocksize;
cur_ptr = block;
remainder = blocksize - (offset & mask);
if (len < remainder)
cur_retlen = len;
else
cur_retlen = remainder;
/* buf == NULL means erase only */
if (buf) {
/* Copy existing data into holding block if necessary */
if ((offset & mask) || (len < blocksize)) {
blk_offset = cur_offset;
blk_len = cur_length;
blk_ptr = cur_ptr;
/* Copy entire block */
while (blk_len) {
copied = sflash_read(cc, blk_offset, blk_len, blk_ptr);
blk_offset += copied;
blk_len -= copied;
blk_ptr += copied;
}
}
/* Copy input data into holding block */
memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
}
/* Erase block */
if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0)
goto done;
while (sflash_poll(cc, (uint) cur_offset));
/* buf == NULL means erase only */
if (!buf) {
offset += cur_retlen;
len -= cur_retlen;
continue;
}
/* Write holding block */
while (cur_length > 0) {
if ((bytes = sflash_write(cc,
(uint) cur_offset,
(uint) cur_length,
(uchar *) cur_ptr)) < 0) {
ret = bytes;
goto done;
}
while (sflash_poll(cc, (uint) cur_offset));
cur_offset += bytes;
cur_length -= bytes;
cur_ptr += bytes;
}
offset += cur_retlen;
len -= cur_retlen;
buf += cur_retlen;
}
ret = len;
done:
if (block)
MFREE(NULL, block, blocksize);
return ret;
}

View file

@ -0,0 +1,104 @@
/*
* Copyright 2006, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: time.c,v 1.1.1.10 2006/02/27 03:42:55 honor Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/serial_reg.h>
#include <linux/interrupt.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/time.h>
#include <typedefs.h>
#include <osl.h>
#include <bcmnvram.h>
#include <sbconfig.h>
#include <sbextif.h>
#include <sbutils.h>
#include <hndmips.h>
#include <mipsinc.h>
#include <hndcpu.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
bcm947xx_time_init(void)
{
unsigned int hz;
extifregs_t *eir;
/*
* Use deterministic values for initial counter interrupt
* so that calibrate delay avoids encountering a counter wrap.
*/
write_c0_count(0);
write_c0_compare(0xffff);
if (!(hz = sb_cpu_clock(sbh)))
hz = 100000000;
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;
/* Set watchdog interval in ms */
watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0);
/* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */
if (watchdog > 0) {
if (watchdog < 3000)
watchdog = 3000;
}
/* Set panic timeout in seconds */
panic_timeout = watchdog / 1000;
}
static void
bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* Generic MIPS timer code */
timer_interrupt(irq, dev_id, regs);
/* Set the watchdog timer to reset after the specified number of ms */
if (watchdog > 0)
sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
}
static struct irqaction bcm947xx_timer_irqaction = {
bcm947xx_timer_interrupt,
SA_INTERRUPT,
0,
"timer",
NULL,
NULL
};
void __init
bcm947xx_timer_setup(struct irqaction *irq)
{
/* Enable the timer interrupt */
setup_irq(7, &bcm947xx_timer_irqaction);
}

View file

@ -0,0 +1,298 @@
/*
* Broadcom SiliconBackplane chipcommon serial flash interface
*
* Copyright 2001-2003, Broadcom Corporation
* All Rights Reserved.
*
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
*
* $Id: sflash.c,v 1.1.1.3 2003/11/10 17:43:38 hyin Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/io.h>
#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/minix_fs.h>
#include <linux/ext2_fs.h>
#include <linux/romfs_fs.h>
#include <linux/cramfs_fs.h>
#include <linux/jffs2.h>
#endif
#include <typedefs.h>
#include <bcmdevs.h>
#include <bcmutils.h>
#include <osl.h>
#include <bcmutils.h>
#include <bcmnvram.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sflash.h>
#include <trxhdr.h>
#ifdef CONFIG_MTD_PARTITIONS
extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
#endif
struct sflash_mtd {
chipcregs_t *cc;
struct semaphore lock;
struct mtd_info mtd;
struct mtd_erase_region_info regions[1];
};
/* Private global state */
static struct sflash_mtd sflash;
static int
sflash_mtd_poll(struct sflash_mtd *sflash, unsigned int offset, int timeout)
{
int now = jiffies;
int ret = 0;
for (;;) {
if (!sflash_poll(sflash->cc, offset)) {
ret = 0;
break;
}
if (time_after(jiffies, now + timeout)) {
printk(KERN_ERR "sflash: timeout\n");
ret = -ETIMEDOUT;
break;
}
if (current->need_resched) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(timeout / 10);
} else
udelay(1);
}
return ret;
}
static int
sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
int bytes, ret = 0;
/* Check address range */
if (!len)
return 0;
if ((from + len) > mtd->size)
return -EINVAL;
down(&sflash->lock);
*retlen = 0;
while (len) {
if ((bytes = sflash_read(sflash->cc, (uint) from, len, buf)) < 0) {
ret = bytes;
break;
}
from += (loff_t) bytes;
len -= bytes;
buf += bytes;
*retlen += bytes;
}
up(&sflash->lock);
return ret;
}
static int
sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{
struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
int bytes, ret = 0;
/* Check address range */
if (!len)
return 0;
if ((to + len) > mtd->size)
return -EINVAL;
down(&sflash->lock);
*retlen = 0;
while (len) {
if ((bytes = sflash_write(sflash->cc, (uint) to, len, buf)) < 0) {
ret = bytes;
break;
}
if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10)))
break;
to += (loff_t) bytes;
len -= bytes;
buf += bytes;
*retlen += bytes;
}
up(&sflash->lock);
return ret;
}
static int
sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
{
struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
int i, j, ret = 0;
unsigned int addr, len;
/* Check address range */
if (!erase->len)
return 0;
if ((erase->addr + erase->len) > mtd->size)
return -EINVAL;
addr = erase->addr;
len = erase->len;
down(&sflash->lock);
/* Ensure that requested region is aligned */
for (i = 0; i < mtd->numeraseregions; i++) {
for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
if (addr == mtd->eraseregions[i].offset + mtd->eraseregions[i].erasesize * j &&
len >= mtd->eraseregions[i].erasesize) {
if ((ret = sflash_erase(sflash->cc, addr)) < 0)
break;
if ((ret = sflash_mtd_poll(sflash, addr, 10 * HZ)))
break;
addr += mtd->eraseregions[i].erasesize;
len -= mtd->eraseregions[i].erasesize;
}
}
if (ret)
break;
}
up(&sflash->lock);
/* Set erase status */
if (ret)
erase->state = MTD_ERASE_FAILED;
else
erase->state = MTD_ERASE_DONE;
/* Call erase callback */
if (erase->callback)
erase->callback(erase);
return ret;
}
#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
#define sflash_mtd_init init_module
#define sflash_mtd_exit cleanup_module
#endif
mod_init_t
sflash_mtd_init(void)
{
struct pci_dev *pdev;
int ret = 0;
struct sflash *info;
uint bank, i;
#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *parts;
#endif
if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_CC, NULL))) {
printk(KERN_ERR "sflash: chipcommon not found\n");
return -ENODEV;
}
memset(&sflash, 0, sizeof(struct sflash_mtd));
init_MUTEX(&sflash.lock);
/* Map registers and flash base */
if (!(sflash.cc = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)))) {
printk(KERN_ERR "sflash: error mapping registers\n");
ret = -EIO;
goto fail;
}
/* Initialize serial flash access */
info = sflash_init(sflash.cc);
if (!info) {
printk(KERN_ERR "sflash: found no supported devices\n");
ret = -ENODEV;
goto fail;
}
/* Setup banks */
sflash.regions[0].offset = 0;
sflash.regions[0].erasesize = info->blocksize;
sflash.regions[0].numblocks = info->numblocks;
if (sflash.regions[0].erasesize > sflash.mtd.erasesize)
sflash.mtd.erasesize = sflash.regions[0].erasesize;
if (sflash.regions[0].erasesize * sflash.regions[0].numblocks) {
sflash.mtd.size += sflash.regions[0].erasesize * sflash.regions[0].numblocks;
}
sflash.mtd.numeraseregions = 1;
ASSERT(sflash.mtd.size == info->size);
/* Register with MTD */
sflash.mtd.name = "sflash";
sflash.mtd.type = MTD_NORFLASH;
sflash.mtd.flags = MTD_CAP_NORFLASH;
sflash.mtd.eraseregions = sflash.regions;
sflash.mtd.module = THIS_MODULE;
sflash.mtd.erase = sflash_mtd_erase;
sflash.mtd.read = sflash_mtd_read;
sflash.mtd.write = sflash_mtd_write;
sflash.mtd.priv = &sflash;
#ifdef CONFIG_MTD_PARTITIONS
parts = init_mtd_partitions(&sflash.mtd, sflash.mtd.size);
for (i = 0; parts[i].name; i++);
ret = add_mtd_partitions(&sflash.mtd, parts, i);
#else
ret = add_mtd_device(&sflash.mtd);
#endif
if (ret) {
printk(KERN_ERR "sflash: add_mtd failed\n");
goto fail;
}
return 0;
fail:
if (sflash.cc)
iounmap((void *) sflash.cc);
return ret;
}
mod_exit_t
sflash_mtd_exit(void)
{
#ifdef CONFIG_MTD_PARTITIONS
del_mtd_partitions(&sflash.mtd);
#else
del_mtd_device(&sflash.mtd);
#endif
iounmap((void *) sflash.cc);
}
module_init(sflash_mtd_init);
module_exit(sflash_mtd_exit);

View file

@ -0,0 +1,504 @@
/*
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
*
* original functions for finding root filesystem from Mike Baker
*
* 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.
*
*
* Copyright 2004, 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.
*
* Flash mapping for BCM947XX boards
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/wait.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif
#include <linux/config.h>
#include <linux/squashfs_fs.h>
#include <linux/jffs2.h>
#include <linux/crc32.h>
#include <asm/io.h>
#include <typedefs.h>
#include <osl.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sbutils.h>
#include <trxhdr.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
#define WINDOW_ADDR 0x1fc00000
#define WINDOW_SIZE 0x400000
#define BUSWIDTH 2
static struct mtd_info *bcm947xx_mtd;
__u8 bcm947xx_map_read8(struct map_info *map, unsigned long ofs)
{
if (map->map_priv_2 == 1)
return __raw_readb(map->map_priv_1 + ofs);
u16 val = __raw_readw(map->map_priv_1 + (ofs & ~1));
if (ofs & 1)
return ((val >> 8) & 0xff);
else
return (val & 0xff);
}
__u16 bcm947xx_map_read16(struct map_info *map, unsigned long ofs)
{
return __raw_readw(map->map_priv_1 + ofs);
}
__u32 bcm947xx_map_read32(struct map_info *map, unsigned long ofs)
{
return __raw_readl(map->map_priv_1 + ofs);
}
void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
if (len==1) {
memcpy_fromio(to, map->map_priv_1 + from, len);
} else {
int i;
u16 *dest = (u16 *) to;
u16 *src = (u16 *) (map->map_priv_1 + from);
for (i = 0; i < (len / 2); i++) {
dest[i] = src[i];
}
if (len & 1)
*((u8 *)dest+len-1) = src[i] & 0xff;
}
}
void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr)
{
__raw_writeb(d, map->map_priv_1 + adr);
mb();
}
void bcm947xx_map_write16(struct map_info *map, __u16 d, unsigned long adr)
{
__raw_writew(d, map->map_priv_1 + adr);
mb();
}
void bcm947xx_map_write32(struct map_info *map, __u32 d, unsigned long adr)
{
__raw_writel(d, map->map_priv_1 + adr);
mb();
}
void bcm947xx_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
memcpy_toio(map->map_priv_1 + to, from, len);
}
struct map_info bcm947xx_map = {
name: "Physically mapped flash",
size: WINDOW_SIZE,
buswidth: BUSWIDTH,
read8: bcm947xx_map_read8,
read16: bcm947xx_map_read16,
read32: bcm947xx_map_read32,
copy_from: bcm947xx_map_copy_from,
write8: bcm947xx_map_write8,
write16: bcm947xx_map_write16,
write32: bcm947xx_map_write32,
copy_to: bcm947xx_map_copy_to
};
#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition bcm947xx_parts[] = {
{ name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
{ name: "linux", offset: 0, size: 0, },
{ name: "rootfs", offset: 0, size: 0, },
{ name: "nvram", offset: 0, size: 0, },
{ name: NULL, },
};
static int __init
find_cfe_size(struct mtd_info *mtd, size_t size)
{
struct trx_header *trx;
unsigned char buf[512];
int off;
size_t len;
int blocksize;
trx = (struct trx_header *) buf;
blocksize = mtd->erasesize;
if (blocksize < 0x10000)
blocksize = 0x10000;
for (off = (128*1024); off < size; off += blocksize) {
memset(buf, 0xe5, sizeof(buf));
/*
* Read into buffer
*/
if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
len != sizeof(buf))
continue;
/* found a TRX header */
if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
goto found;
}
}
printk(KERN_NOTICE
"%s: Couldn't find bootloader size\n",
mtd->name);
return -1;
found:
printk(KERN_NOTICE "bootloader size: %d\n", off);
return off;
}
/*
* Copied from mtdblock.c
*
* Cache stuff...
*
* Since typical flash erasable sectors are much larger than what Linux's
* buffer cache can handle, we must implement read-modify-write on flash
* sectors for each block write requests. To avoid over-erasing flash sectors
* and to speed things up, we locally cache a whole flash sector while it is
* being written to until a different sector is required.
*/
static void erase_callback(struct erase_info *done)
{
wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
wake_up(wait_q);
}
static int erase_write (struct mtd_info *mtd, unsigned long pos,
int len, const char *buf)
{
struct erase_info erase;
DECLARE_WAITQUEUE(wait, current);
wait_queue_head_t wait_q;
size_t retlen;
int ret;
/*
* First, let's erase the flash block.
*/
init_waitqueue_head(&wait_q);
erase.mtd = mtd;
erase.callback = erase_callback;
erase.addr = pos;
erase.len = len;
erase.priv = (u_long)&wait_q;
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wait_q, &wait);
ret = MTD_ERASE(mtd, &erase);
if (ret) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&wait_q, &wait);
printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
"on \"%s\" failed\n",
pos, len, mtd->name);
return ret;
}
schedule(); /* Wait for erase to finish. */
remove_wait_queue(&wait_q, &wait);
/*
* Next, writhe data to flash.
*/
ret = MTD_WRITE (mtd, pos, len, &retlen, buf);
if (ret)
return ret;
if (retlen != len)
return -EIO;
return 0;
}
static int __init
find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
{
struct trx_header trx, *trx2;
unsigned char buf[512], *block;
int off, blocksize;
u32 i, crc = ~0;
size_t len;
struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
blocksize = mtd->erasesize;
if (blocksize < 0x10000)
blocksize = 0x10000;
for (off = (128*1024); off < size; off += blocksize) {
memset(&trx, 0xe5, sizeof(trx));
/*
* Read into buffer
*/
if (MTD_READ(mtd, off, sizeof(trx), &len, (char *) &trx) ||
len != sizeof(trx))
continue;
/* found a TRX header */
if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
part->offset = le32_to_cpu(trx.offsets[2]) ? :
le32_to_cpu(trx.offsets[1]);
part->size = le32_to_cpu(trx.len);
part->size -= part->offset;
part->offset += off;
goto found;
}
}
printk(KERN_NOTICE
"%s: Couldn't find root filesystem\n",
mtd->name);
return -1;
found:
if (part->size == 0)
return 0;
if (MTD_READ(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
return 0;
/* Move the filesystem outside of the trx */
part->size = 0;
if (trx.len != part->offset + part->size - off) {
/* Update the trx offsets and length */
trx.len = part->offset + part->size - off;
/* Update the trx crc32 */
for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
if (MTD_READ(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
return 0;
crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
}
trx.crc32 = crc;
/* read first eraseblock from the trx */
trx2 = block = kmalloc(mtd->erasesize, GFP_KERNEL);
if (MTD_READ(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
printk("Error accessing the first trx eraseblock\n");
return 0;
}
printk("Updating TRX offsets and length:\n");
printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32);
/* Write updated trx header to the flash */
memcpy(block, &trx, sizeof(trx));
if (mtd->unlock)
mtd->unlock(mtd, off, mtd->erasesize);
erase_write(mtd, off, mtd->erasesize, block);
if (mtd->sync)
mtd->sync(mtd);
kfree(block);
printk("Done\n");
}
return part->size;
}
struct mtd_partition * __init
init_mtd_partitions(struct mtd_info *mtd, size_t size)
{
int cfe_size;
if ((cfe_size = find_cfe_size(mtd,size)) < 0)
return NULL;
/* boot loader */
bcm947xx_parts[0].offset = 0;
bcm947xx_parts[0].size = cfe_size;
/* nvram */
if (cfe_size != 384 * 1024) {
bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
} else {
/* nvram (old 128kb config partition on netgear wgt634u) */
bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
}
/* linux (kernel and rootfs) */
if (cfe_size != 384 * 1024) {
bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
bcm947xx_parts[1].size = bcm947xx_parts[3].offset -
bcm947xx_parts[1].offset;
} else {
/* do not count the elf loader, which is on one block */
bcm947xx_parts[1].offset = bcm947xx_parts[0].size +
bcm947xx_parts[3].size + mtd->erasesize;
bcm947xx_parts[1].size = size -
bcm947xx_parts[0].size -
(2*bcm947xx_parts[3].size) -
mtd->erasesize;
}
find_root(mtd,size,&bcm947xx_parts[2]);
bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - bcm947xx_parts[3].size;
return bcm947xx_parts;
}
#endif
mod_init_t init_bcm947xx_map(void)
{
ulong flags;
uint coreidx;
chipcregs_t *cc;
uint32 fltype;
uint window_addr = 0, window_size = 0;
size_t size;
int ret = 0;
#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *parts;
int i;
#endif
spin_lock_irqsave(&sbh_lock, flags);
coreidx = sb_coreidx(sbh);
/* Check strapping option if chipcommon exists */
if ((cc = sb_setcore(sbh, SB_CC, 0))) {
fltype = readl(&cc->capabilities) & CAP_FLASH_MASK;
if (fltype == PFLASH) {
bcm947xx_map.map_priv_2 = 1;
window_addr = 0x1c000000;
bcm947xx_map.size = window_size = 32 * 1024 * 1024;
if ((readl(&cc->flash_config) & CC_CFG_DS) == 0)
bcm947xx_map.buswidth = 1;
}
} else {
fltype = PFLASH;
bcm947xx_map.map_priv_2 = 0;
window_addr = WINDOW_ADDR;
window_size = WINDOW_SIZE;
}
sb_setcoreidx(sbh, coreidx);
spin_unlock_irqrestore(&sbh_lock, flags);
if (fltype != PFLASH) {
printk(KERN_ERR "pflash: found no supported devices\n");
ret = -ENODEV;
goto fail;
}
bcm947xx_map.map_priv_1 = (unsigned long) ioremap(window_addr, window_size);
if (!bcm947xx_map.map_priv_1) {
printk(KERN_ERR "Failed to ioremap\n");
return -EIO;
}
if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
printk(KERN_ERR "pflash: cfi_probe failed\n");
iounmap((void *)bcm947xx_map.map_priv_1);
return -ENXIO;
}
bcm947xx_mtd->module = THIS_MODULE;
size = bcm947xx_mtd->size;
printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr);
#ifdef CONFIG_MTD_PARTITIONS
parts = init_mtd_partitions(bcm947xx_mtd, size);
for (i = 0; parts[i].name; i++);
ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
if (ret) {
printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
goto fail;
}
#endif
return 0;
fail:
if (bcm947xx_mtd)
map_destroy(bcm947xx_mtd);
if (bcm947xx_map.map_priv_1)
iounmap((void *) bcm947xx_map.map_priv_1);
bcm947xx_map.map_priv_1 = 0;
return ret;
}
mod_exit_t cleanup_bcm947xx_map(void)
{
#ifdef CONFIG_MTD_PARTITIONS
del_mtd_partitions(bcm947xx_mtd);
#endif
map_destroy(bcm947xx_mtd);
iounmap((void *) bcm947xx_map.map_priv_1);
bcm947xx_map.map_priv_1 = 0;
}
module_init(init_bcm947xx_map);
module_exit(cleanup_bcm947xx_map);

View file

@ -0,0 +1,345 @@
/* Low-level parallel port routines for the ASUS WL-500g built-in port
*
* Author: Nuno Grilo <nuno.grilo@netcabo.pt>
* Based on parport_pc source
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#define SPLINK_ADDRESS 0xBF800010
#undef DEBUG
#ifdef DEBUG
#define DPRINTK printk
#else
#define DPRINTK(stuff...)
#endif
/* __parport_splink_frob_control differs from parport_splink_frob_control in that
* it doesn't do any extra masking. */
static __inline__ unsigned char __parport_splink_frob_control (struct parport *p,
unsigned char mask,
unsigned char val)
{
struct parport_pc_private *priv = p->physport->private_data;
unsigned char *io = (unsigned char *) p->base;
unsigned char ctr = priv->ctr;
#ifdef DEBUG_PARPORT
printk (KERN_DEBUG
"__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n",
mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
#endif
ctr = (ctr & ~mask) ^ val;
ctr &= priv->ctr_writable; /* only write writable bits. */
*(io+2) = ctr;
priv->ctr = ctr; /* Update soft copy */
return ctr;
}
static void parport_splink_data_forward (struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n");
__parport_splink_frob_control (p, 0x20, 0);
}
static void parport_splink_data_reverse (struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n");
__parport_splink_frob_control (p, 0x20, 0x20);
}
/*
static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n");
parport_generic_irq(irq, (struct parport *) dev_id, regs);
}
*/
static void parport_splink_enable_irq(struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n");
__parport_splink_frob_control (p, 0x10, 0x10);
}
static void parport_splink_disable_irq(struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n");
__parport_splink_frob_control (p, 0x10, 0);
}
static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n");
s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
if (dev->irq_func &&
dev->port->irq != PARPORT_IRQ_NONE)
/* Set ackIntEn */
s->u.pc.ctr |= 0x10;
}
static void parport_splink_save_state(struct parport *p, struct parport_state *s)
{
const struct parport_pc_private *priv = p->physport->private_data;
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n");
s->u.pc.ctr = priv->ctr;
}
static void parport_splink_restore_state(struct parport *p, struct parport_state *s)
{
struct parport_pc_private *priv = p->physport->private_data;
unsigned char *io = (unsigned char *) p->base;
unsigned char ctr = s->u.pc.ctr;
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n");
*(io+2) = ctr;
priv->ctr = ctr;
}
static void parport_splink_setup_interrupt(void) {
return;
}
static void parport_splink_write_data(struct parport *p, unsigned char d) {
DPRINTK(KERN_DEBUG "parport_splink: write data called\n");
unsigned char *io = (unsigned char *) p->base;
*io = d;
}
static unsigned char parport_splink_read_data(struct parport *p) {
DPRINTK(KERN_DEBUG "parport_splink: read data called\n");
unsigned char *io = (unsigned char *) p->base;
return *io;
}
static void parport_splink_write_control(struct parport *p, unsigned char d)
{
const unsigned char wm = (PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_INIT |
PARPORT_CONTROL_SELECT);
DPRINTK(KERN_DEBUG "parport_splink: write control called\n");
/* Take this out when drivers have adapted to the newer interface. */
if (d & 0x20) {
printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
p->name, p->cad->name);
parport_splink_data_reverse (p);
}
__parport_splink_frob_control (p, wm, d & wm);
}
static unsigned char parport_splink_read_control(struct parport *p)
{
const unsigned char wm = (PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_INIT |
PARPORT_CONTROL_SELECT);
DPRINTK(KERN_DEBUG "parport_splink: read control called\n");
const struct parport_pc_private *priv = p->physport->private_data;
return priv->ctr & wm; /* Use soft copy */
}
static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask,
unsigned char val)
{
const unsigned char wm = (PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_INIT |
PARPORT_CONTROL_SELECT);
DPRINTK(KERN_DEBUG "parport_splink: frob control called\n");
/* Take this out when drivers have adapted to the newer interface. */
if (mask & 0x20) {
printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
p->name, p->cad->name,
(val & 0x20) ? "reverse" : "forward");
if (val & 0x20)
parport_splink_data_reverse (p);
else
parport_splink_data_forward (p);
}
/* Restrict mask and val to control lines. */
mask &= wm;
val &= wm;
return __parport_splink_frob_control (p, mask, val);
}
static unsigned char parport_splink_read_status(struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: read status called\n");
unsigned char *io = (unsigned char *) p->base;
return *(io+1);
}
static void parport_splink_inc_use_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
static void parport_splink_dec_use_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_splink_ops =
{
parport_splink_write_data,
parport_splink_read_data,
parport_splink_write_control,
parport_splink_read_control,
parport_splink_frob_control,
parport_splink_read_status,
parport_splink_enable_irq,
parport_splink_disable_irq,
parport_splink_data_forward,
parport_splink_data_reverse,
parport_splink_init_state,
parport_splink_save_state,
parport_splink_restore_state,
parport_splink_inc_use_count,
parport_splink_dec_use_count,
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
parport_ieee1284_epp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data,
parport_ieee1284_ecp_read_data,
parport_ieee1284_ecp_write_addr,
parport_ieee1284_write_compat,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
};
/* --- Initialisation code -------------------------------- */
static struct parport *parport_splink_probe_port (unsigned long int base)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
struct parport *p;
if (check_mem_region(base, 3)) {
printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base);
return NULL;
}
priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
if (!priv) {
printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
return NULL;
}
ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
if (!ops) {
printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
base);
kfree (priv);
return NULL;
}
memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations));
priv->ctr = 0xc;
priv->ctr_writable = 0xff;
if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
PARPORT_DMA_NONE, ops))) {
printk (KERN_DEBUG "parport (0x%lx): registration failed!\n",
base);
kfree (priv);
kfree (ops);
return NULL;
}
p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
p->private_data = priv;
parport_proc_register(p);
request_mem_region (p->base, 3, p->name);
/* Done probing. Now put the port into a sensible start-up state. */
parport_splink_write_data(p, 0);
parport_splink_data_forward (p);
/* Now that we've told the sharing engine about the port, and
found out its characteristics, let the high-level drivers
know about it. */
parport_announce_port (p);
DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n",
base);
return p;
}
static void parport_splink_unregister_port(struct parport *p) {
struct parport_pc_private *priv = p->private_data;
struct parport_operations *ops = p->ops;
if (p->irq != PARPORT_IRQ_NONE)
free_irq(p->irq, p);
release_mem_region(p->base, 3);
parport_proc_unregister(p);
kfree (priv);
parport_unregister_port(p);
kfree (ops);
}
int parport_splink_init(void)
{
int ret;
DPRINTK(KERN_DEBUG "parport_splink init called\n");
parport_splink_setup_interrupt();
ret = !parport_splink_probe_port(SPLINK_ADDRESS);
return ret;
}
void parport_splink_cleanup(void) {
struct parport *p = parport_enumerate(), *tmp;
DPRINTK(KERN_DEBUG "parport_splink cleanup called\n");
if (p->size) {
if (p->modes & PARPORT_MODE_PCSPP) {
while(p) {
tmp = p->next;
parport_splink_unregister_port(p);
p = tmp;
}
}
}
}
MODULE_AUTHOR("Nuno Grilo <nuno.grilo@netcabo.pt>");
MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port");
MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port");
MODULE_LICENSE("GPL");
module_init(parport_splink_init)
module_exit(parport_splink_cleanup)

File diff suppressed because it is too large Load diff

View file

@ -29,860 +29,6 @@ diff -urN linux.old/drivers/mtd/devices/Makefile linux.dev/drivers/mtd/devices/M
obj-$(CONFIG_MTD_DOC1000) += doc1000.o
obj-$(CONFIG_MTD_DOC2000) += doc2000.o
obj-$(CONFIG_MTD_DOC2001) += doc2001.o
diff -urN linux.old/drivers/mtd/devices/sflash.c linux.dev/drivers/mtd/devices/sflash.c
--- linux.old/drivers/mtd/devices/sflash.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/mtd/devices/sflash.c 2006-06-21 21:41:24.000000000 +0200
@@ -0,0 +1,298 @@
+/*
+ * Broadcom SiliconBackplane chipcommon serial flash interface
+ *
+ * Copyright 2001-2003, Broadcom Corporation
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: sflash.c,v 1.1.1.3 2003/11/10 17:43:38 hyin Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/mtd/compatmac.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/romfs_fs.h>
+#include <linux/cramfs_fs.h>
+#include <linux/jffs2.h>
+#endif
+
+#include <typedefs.h>
+#include <bcmdevs.h>
+#include <bcmutils.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmnvram.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <sflash.h>
+#include <trxhdr.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
+#endif
+
+struct sflash_mtd {
+ chipcregs_t *cc;
+ struct semaphore lock;
+ struct mtd_info mtd;
+ struct mtd_erase_region_info regions[1];
+};
+
+/* Private global state */
+static struct sflash_mtd sflash;
+
+static int
+sflash_mtd_poll(struct sflash_mtd *sflash, unsigned int offset, int timeout)
+{
+ int now = jiffies;
+ int ret = 0;
+
+ for (;;) {
+ if (!sflash_poll(sflash->cc, offset)) {
+ ret = 0;
+ break;
+ }
+ if (time_after(jiffies, now + timeout)) {
+ printk(KERN_ERR "sflash: timeout\n");
+ ret = -ETIMEDOUT;
+ break;
+ }
+ if (current->need_resched) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(timeout / 10);
+ } else
+ udelay(1);
+ }
+
+ return ret;
+}
+
+static int
+sflash_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
+ int bytes, ret = 0;
+
+ /* Check address range */
+ if (!len)
+ return 0;
+ if ((from + len) > mtd->size)
+ return -EINVAL;
+
+ down(&sflash->lock);
+
+ *retlen = 0;
+ while (len) {
+ if ((bytes = sflash_read(sflash->cc, (uint) from, len, buf)) < 0) {
+ ret = bytes;
+ break;
+ }
+ from += (loff_t) bytes;
+ len -= bytes;
+ buf += bytes;
+ *retlen += bytes;
+ }
+
+ up(&sflash->lock);
+
+ return ret;
+}
+
+static int
+sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+ struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
+ int bytes, ret = 0;
+
+ /* Check address range */
+ if (!len)
+ return 0;
+ if ((to + len) > mtd->size)
+ return -EINVAL;
+
+ down(&sflash->lock);
+
+ *retlen = 0;
+ while (len) {
+ if ((bytes = sflash_write(sflash->cc, (uint) to, len, buf)) < 0) {
+ ret = bytes;
+ break;
+ }
+ if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10)))
+ break;
+ to += (loff_t) bytes;
+ len -= bytes;
+ buf += bytes;
+ *retlen += bytes;
+ }
+
+ up(&sflash->lock);
+
+ return ret;
+}
+
+static int
+sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
+{
+ struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
+ int i, j, ret = 0;
+ unsigned int addr, len;
+
+ /* Check address range */
+ if (!erase->len)
+ return 0;
+ if ((erase->addr + erase->len) > mtd->size)
+ return -EINVAL;
+
+ addr = erase->addr;
+ len = erase->len;
+
+ down(&sflash->lock);
+
+ /* Ensure that requested region is aligned */
+ for (i = 0; i < mtd->numeraseregions; i++) {
+ for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
+ if (addr == mtd->eraseregions[i].offset + mtd->eraseregions[i].erasesize * j &&
+ len >= mtd->eraseregions[i].erasesize) {
+ if ((ret = sflash_erase(sflash->cc, addr)) < 0)
+ break;
+ if ((ret = sflash_mtd_poll(sflash, addr, 10 * HZ)))
+ break;
+ addr += mtd->eraseregions[i].erasesize;
+ len -= mtd->eraseregions[i].erasesize;
+ }
+ }
+ if (ret)
+ break;
+ }
+
+ up(&sflash->lock);
+
+ /* Set erase status */
+ if (ret)
+ erase->state = MTD_ERASE_FAILED;
+ else
+ erase->state = MTD_ERASE_DONE;
+
+ /* Call erase callback */
+ if (erase->callback)
+ erase->callback(erase);
+
+ return ret;
+}
+
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define sflash_mtd_init init_module
+#define sflash_mtd_exit cleanup_module
+#endif
+
+mod_init_t
+sflash_mtd_init(void)
+{
+ struct pci_dev *pdev;
+ int ret = 0;
+ struct sflash *info;
+ uint bank, i;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *parts;
+#endif
+
+ if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_CC, NULL))) {
+ printk(KERN_ERR "sflash: chipcommon not found\n");
+ return -ENODEV;
+ }
+
+ memset(&sflash, 0, sizeof(struct sflash_mtd));
+ init_MUTEX(&sflash.lock);
+
+ /* Map registers and flash base */
+ if (!(sflash.cc = ioremap_nocache(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0)))) {
+ printk(KERN_ERR "sflash: error mapping registers\n");
+ ret = -EIO;
+ goto fail;
+ }
+
+ /* Initialize serial flash access */
+ info = sflash_init(sflash.cc);
+
+ if (!info) {
+ printk(KERN_ERR "sflash: found no supported devices\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ /* Setup banks */
+ sflash.regions[0].offset = 0;
+ sflash.regions[0].erasesize = info->blocksize;
+ sflash.regions[0].numblocks = info->numblocks;
+ if (sflash.regions[0].erasesize > sflash.mtd.erasesize)
+ sflash.mtd.erasesize = sflash.regions[0].erasesize;
+ if (sflash.regions[0].erasesize * sflash.regions[0].numblocks) {
+ sflash.mtd.size += sflash.regions[0].erasesize * sflash.regions[0].numblocks;
+ }
+ sflash.mtd.numeraseregions = 1;
+ ASSERT(sflash.mtd.size == info->size);
+
+ /* Register with MTD */
+ sflash.mtd.name = "sflash";
+ sflash.mtd.type = MTD_NORFLASH;
+ sflash.mtd.flags = MTD_CAP_NORFLASH;
+ sflash.mtd.eraseregions = sflash.regions;
+ sflash.mtd.module = THIS_MODULE;
+ sflash.mtd.erase = sflash_mtd_erase;
+ sflash.mtd.read = sflash_mtd_read;
+ sflash.mtd.write = sflash_mtd_write;
+ sflash.mtd.priv = &sflash;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ parts = init_mtd_partitions(&sflash.mtd, sflash.mtd.size);
+ for (i = 0; parts[i].name; i++);
+ ret = add_mtd_partitions(&sflash.mtd, parts, i);
+#else
+ ret = add_mtd_device(&sflash.mtd);
+#endif
+ if (ret) {
+ printk(KERN_ERR "sflash: add_mtd failed\n");
+ goto fail;
+ }
+
+ return 0;
+
+ fail:
+ if (sflash.cc)
+ iounmap((void *) sflash.cc);
+ return ret;
+}
+
+mod_exit_t
+sflash_mtd_exit(void)
+{
+#ifdef CONFIG_MTD_PARTITIONS
+ del_mtd_partitions(&sflash.mtd);
+#else
+ del_mtd_device(&sflash.mtd);
+#endif
+ iounmap((void *) sflash.cc);
+}
+
+module_init(sflash_mtd_init);
+module_exit(sflash_mtd_exit);
diff -urN linux.old/drivers/mtd/maps/bcm947xx-flash.c linux.dev/drivers/mtd/maps/bcm947xx-flash.c
--- linux.old/drivers/mtd/maps/bcm947xx-flash.c 1970-01-01 01:00:00.000000000 +0100
+++ linux.dev/drivers/mtd/maps/bcm947xx-flash.c 2006-06-23 18:08:46.000000000 +0200
@@ -0,0 +1,548 @@
+/*
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
+ *
+ * original functions for finding root filesystem from Mike Baker
+ *
+ * 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.
+ *
+ *
+ * Copyright 2004, 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.
+ *
+ * Flash mapping for BCM947XX boards
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#ifdef CONFIG_MTD_PARTITIONS
+#include <linux/mtd/partitions.h>
+#endif
+#include <linux/config.h>
+#include <linux/squashfs_fs.h>
+#include <linux/jffs2.h>
+#include <linux/crc32.h>
+#include <asm/io.h>
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmnvram.h>
+#include <bcmutils.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <sbutils.h>
+#include <trxhdr.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
+
+#define WINDOW_ADDR 0x1fc00000
+#define WINDOW_SIZE 0x400000
+#define BUSWIDTH 2
+
+static struct mtd_info *bcm947xx_mtd;
+
+__u8 bcm947xx_map_read8(struct map_info *map, unsigned long ofs)
+{
+ if (map->map_priv_2 == 1)
+ return __raw_readb(map->map_priv_1 + ofs);
+
+ u16 val = __raw_readw(map->map_priv_1 + (ofs & ~1));
+ if (ofs & 1)
+ return ((val >> 8) & 0xff);
+ else
+ return (val & 0xff);
+}
+
+__u16 bcm947xx_map_read16(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readw(map->map_priv_1 + ofs);
+}
+
+__u32 bcm947xx_map_read32(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readl(map->map_priv_1 + ofs);
+}
+
+void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+ if (len==1) {
+ memcpy_fromio(to, map->map_priv_1 + from, len);
+ } else {
+ int i;
+ u16 *dest = (u16 *) to;
+ u16 *src = (u16 *) (map->map_priv_1 + from);
+ for (i = 0; i < (len / 2); i++) {
+ dest[i] = src[i];
+ }
+ if (len & 1)
+ *((u8 *)dest+len-1) = src[i] & 0xff;
+ }
+}
+
+void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+ __raw_writeb(d, map->map_priv_1 + adr);
+ mb();
+}
+
+void bcm947xx_map_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+ __raw_writew(d, map->map_priv_1 + adr);
+ mb();
+}
+
+void bcm947xx_map_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+ __raw_writel(d, map->map_priv_1 + adr);
+ mb();
+}
+
+void bcm947xx_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+ memcpy_toio(map->map_priv_1 + to, from, len);
+}
+
+struct map_info bcm947xx_map = {
+ name: "Physically mapped flash",
+ size: WINDOW_SIZE,
+ buswidth: BUSWIDTH,
+ read8: bcm947xx_map_read8,
+ read16: bcm947xx_map_read16,
+ read32: bcm947xx_map_read32,
+ copy_from: bcm947xx_map_copy_from,
+ write8: bcm947xx_map_write8,
+ write16: bcm947xx_map_write16,
+ write32: bcm947xx_map_write32,
+ copy_to: bcm947xx_map_copy_to
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+
+static struct mtd_partition bcm947xx_parts[] = {
+ { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
+ { name: "linux", offset: 0, size: 0, },
+ { name: "rootfs", offset: 0, size: 0, },
+ { name: "nvram", offset: 0, size: 0, },
+ { name: "OpenWrt", offset: 0, size: 0, },
+ { name: NULL, },
+};
+
+static int __init
+find_cfe_size(struct mtd_info *mtd, size_t size)
+{
+ struct trx_header *trx;
+ unsigned char buf[512];
+ int off;
+ size_t len;
+ int blocksize;
+
+ trx = (struct trx_header *) buf;
+
+ blocksize = mtd->erasesize;
+ if (blocksize < 0x10000)
+ blocksize = 0x10000;
+
+ for (off = (128*1024); off < size; off += blocksize) {
+ memset(buf, 0xe5, sizeof(buf));
+
+ /*
+ * Read into buffer
+ */
+ if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
+ len != sizeof(buf))
+ continue;
+
+ /* found a TRX header */
+ if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
+ goto found;
+ }
+ }
+
+ printk(KERN_NOTICE
+ "%s: Couldn't find bootloader size\n",
+ mtd->name);
+ return -1;
+
+ found:
+ printk(KERN_NOTICE "bootloader size: %d\n", off);
+ return off;
+
+}
+
+/*
+ * Copied from mtdblock.c
+ *
+ * Cache stuff...
+ *
+ * Since typical flash erasable sectors are much larger than what Linux's
+ * buffer cache can handle, we must implement read-modify-write on flash
+ * sectors for each block write requests. To avoid over-erasing flash sectors
+ * and to speed things up, we locally cache a whole flash sector while it is
+ * being written to until a different sector is required.
+ */
+
+static void erase_callback(struct erase_info *done)
+{
+ wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
+ wake_up(wait_q);
+}
+
+static int erase_write (struct mtd_info *mtd, unsigned long pos,
+ int len, const char *buf)
+{
+ struct erase_info erase;
+ DECLARE_WAITQUEUE(wait, current);
+ wait_queue_head_t wait_q;
+ size_t retlen;
+ int ret;
+
+ /*
+ * First, let's erase the flash block.
+ */
+
+ init_waitqueue_head(&wait_q);
+ erase.mtd = mtd;
+ erase.callback = erase_callback;
+ erase.addr = pos;
+ erase.len = len;
+ erase.priv = (u_long)&wait_q;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&wait_q, &wait);
+
+ ret = MTD_ERASE(mtd, &erase);
+ if (ret) {
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&wait_q, &wait);
+ printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
+ "on \"%s\" failed\n",
+ pos, len, mtd->name);
+ return ret;
+ }
+
+ schedule(); /* Wait for erase to finish. */
+ remove_wait_queue(&wait_q, &wait);
+
+ /*
+ * Next, writhe data to flash.
+ */
+
+ ret = MTD_WRITE (mtd, pos, len, &retlen, buf);
+ if (ret)
+ return ret;
+ if (retlen != len)
+ return -EIO;
+ return 0;
+}
+
+
+
+
+static int __init
+find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
+{
+ struct trx_header trx, *trx2;
+ unsigned char buf[512], *block;
+ int off, blocksize;
+ u32 i, crc = ~0;
+ size_t len;
+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
+
+ blocksize = mtd->erasesize;
+ if (blocksize < 0x10000)
+ blocksize = 0x10000;
+
+ for (off = (128*1024); off < size; off += blocksize) {
+ memset(&trx, 0xe5, sizeof(trx));
+
+ /*
+ * Read into buffer
+ */
+ if (MTD_READ(mtd, off, sizeof(trx), &len, (char *) &trx) ||
+ len != sizeof(trx))
+ continue;
+
+ /* found a TRX header */
+ if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
+ part->offset = le32_to_cpu(trx.offsets[2]) ? :
+ le32_to_cpu(trx.offsets[1]);
+ part->size = le32_to_cpu(trx.len);
+
+ part->size -= part->offset;
+ part->offset += off;
+
+ goto found;
+ }
+ }
+
+ printk(KERN_NOTICE
+ "%s: Couldn't find root filesystem\n",
+ mtd->name);
+ return -1;
+
+ found:
+ if (part->size == 0)
+ return 0;
+
+ if (MTD_READ(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
+ return 0;
+
+ if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
+ printk(KERN_INFO "%s: Filesystem type: squashfs, size=0x%x\n", mtd->name, (u32) sb->bytes_used);
+
+ /* Update the squashfs partition size based on the superblock info */
+ part->size = sb->bytes_used;
+ len = part->offset + part->size;
+ len += (mtd->erasesize - 1);
+ len &= ~(mtd->erasesize - 1);
+ part->size = len - part->offset;
+ } else if (*((__u16 *) buf) == JFFS2_MAGIC_BITMASK) {
+ printk(KERN_INFO "%s: Filesystem type: jffs2\n", mtd->name);
+
+ /* Move the squashfs outside of the trx */
+ part->size = 0;
+ } else {
+ printk(KERN_INFO "%s: Filesystem type: unknown\n", mtd->name);
+ return 0;
+ }
+
+ if (trx.len != part->offset + part->size - off) {
+ /* Update the trx offsets and length */
+ trx.len = part->offset + part->size - off;
+
+ /* Update the trx crc32 */
+ for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
+ if (MTD_READ(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
+ return 0;
+ crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
+ }
+ trx.crc32 = crc;
+
+ /* read first eraseblock from the trx */
+ trx2 = block = kmalloc(mtd->erasesize, GFP_KERNEL);
+ if (MTD_READ(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
+ printk("Error accessing the first trx eraseblock\n");
+ return 0;
+ }
+
+ printk("Updating TRX offsets and length:\n");
+ printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
+ printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32);
+
+ /* Write updated trx header to the flash */
+ memcpy(block, &trx, sizeof(trx));
+ if (mtd->unlock)
+ mtd->unlock(mtd, off, mtd->erasesize);
+ erase_write(mtd, off, mtd->erasesize, block);
+ if (mtd->sync)
+ mtd->sync(mtd);
+ kfree(block);
+ printk("Done\n");
+ }
+
+ return part->size;
+}
+
+struct mtd_partition * __init
+init_mtd_partitions(struct mtd_info *mtd, size_t size)
+{
+ int cfe_size;
+
+ if ((cfe_size = find_cfe_size(mtd,size)) < 0)
+ return NULL;
+
+ /* boot loader */
+ bcm947xx_parts[0].offset = 0;
+ bcm947xx_parts[0].size = cfe_size;
+
+ /* nvram */
+ if (cfe_size != 384 * 1024) {
+ bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+ bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+ } else {
+ /* nvram (old 128kb config partition on netgear wgt634u) */
+ bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
+ bcm947xx_parts[3].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
+ }
+
+ /* linux (kernel and rootfs) */
+ if (cfe_size != 384 * 1024) {
+ bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
+ bcm947xx_parts[1].size = bcm947xx_parts[3].offset -
+ bcm947xx_parts[1].offset;
+ } else {
+ /* do not count the elf loader, which is on one block */
+ bcm947xx_parts[1].offset = bcm947xx_parts[0].size +
+ bcm947xx_parts[3].size + mtd->erasesize;
+ bcm947xx_parts[1].size = size -
+ bcm947xx_parts[0].size -
+ (2*bcm947xx_parts[3].size) -
+ mtd->erasesize;
+ }
+
+ /* find and size rootfs */
+ if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
+ /* entirely jffs2 */
+ bcm947xx_parts[4].name = NULL;
+ bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset -
+ bcm947xx_parts[3].size;
+ } else {
+ /* legacy setup */
+ /* calculate leftover flash, and assign it to the jffs2 partition */
+ if (cfe_size != 384 * 1024) {
+ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
+ bcm947xx_parts[2].size;
+ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
+ bcm947xx_parts[4].offset += mtd->erasesize -
+ (bcm947xx_parts[4].offset % mtd->erasesize);
+ }
+ bcm947xx_parts[4].size = bcm947xx_parts[3].offset -
+ bcm947xx_parts[4].offset;
+ } else {
+ bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
+ bcm947xx_parts[2].size;
+ if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
+ bcm947xx_parts[4].offset += mtd->erasesize -
+ (bcm947xx_parts[4].offset % mtd->erasesize);
+ }
+ bcm947xx_parts[4].size = size - bcm947xx_parts[3].size -
+ bcm947xx_parts[4].offset;
+ }
+ }
+
+ return bcm947xx_parts;
+}
+
+#endif
+
+
+mod_init_t init_bcm947xx_map(void)
+{
+ ulong flags;
+ uint coreidx;
+ chipcregs_t *cc;
+ uint32 fltype;
+ uint window_addr = 0, window_size = 0;
+ size_t size;
+ int ret = 0;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *parts;
+ int i;
+#endif
+
+ spin_lock_irqsave(&sbh_lock, flags);
+ coreidx = sb_coreidx(sbh);
+
+ /* Check strapping option if chipcommon exists */
+ if ((cc = sb_setcore(sbh, SB_CC, 0))) {
+ fltype = readl(&cc->capabilities) & CAP_FLASH_MASK;
+ if (fltype == PFLASH) {
+ bcm947xx_map.map_priv_2 = 1;
+ window_addr = 0x1c000000;
+ bcm947xx_map.size = window_size = 32 * 1024 * 1024;
+ if ((readl(&cc->flash_config) & CC_CFG_DS) == 0)
+ bcm947xx_map.buswidth = 1;
+ }
+ } else {
+ fltype = PFLASH;
+ bcm947xx_map.map_priv_2 = 0;
+ window_addr = WINDOW_ADDR;
+ window_size = WINDOW_SIZE;
+ }
+
+ sb_setcoreidx(sbh, coreidx);
+ spin_unlock_irqrestore(&sbh_lock, flags);
+
+ if (fltype != PFLASH) {
+ printk(KERN_ERR "pflash: found no supported devices\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ bcm947xx_map.map_priv_1 = (unsigned long) ioremap(window_addr, window_size);
+
+ if (!bcm947xx_map.map_priv_1) {
+ printk(KERN_ERR "Failed to ioremap\n");
+ return -EIO;
+ }
+
+ if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
+ printk(KERN_ERR "pflash: cfi_probe failed\n");
+ iounmap((void *)bcm947xx_map.map_priv_1);
+ return -ENXIO;
+ }
+
+ bcm947xx_mtd->module = THIS_MODULE;
+
+ size = bcm947xx_mtd->size;
+
+ printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr);
+
+#ifdef CONFIG_MTD_PARTITIONS
+ parts = init_mtd_partitions(bcm947xx_mtd, size);
+ for (i = 0; parts[i].name; i++);
+ ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
+ if (ret) {
+ printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
+ goto fail;
+ }
+#endif
+
+ return 0;
+
+ fail:
+ if (bcm947xx_mtd)
+ map_destroy(bcm947xx_mtd);
+ if (bcm947xx_map.map_priv_1)
+ iounmap((void *) bcm947xx_map.map_priv_1);
+ bcm947xx_map.map_priv_1 = 0;
+ return ret;
+}
+
+mod_exit_t cleanup_bcm947xx_map(void)
+{
+#ifdef CONFIG_MTD_PARTITIONS
+ del_mtd_partitions(bcm947xx_mtd);
+#endif
+ map_destroy(bcm947xx_mtd);
+ iounmap((void *) bcm947xx_map.map_priv_1);
+ bcm947xx_map.map_priv_1 = 0;
+}
+
+module_init(init_bcm947xx_map);
+module_exit(cleanup_bcm947xx_map);
diff -urN linux.old/drivers/mtd/maps/Config.in linux.dev/drivers/mtd/maps/Config.in
--- linux.old/drivers/mtd/maps/Config.in 2006-06-22 17:35:39.000000000 +0200
+++ linux.dev/drivers/mtd/maps/Config.in 2006-06-21 21:41:24.000000000 +0200

View file

@ -1,37 +1,3 @@
diff -urN linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c
--- linux.old/arch/mips/bcm947xx/pcibios.c 2006-04-07 21:20:59.000000000 +0200
+++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-08 03:17:59.000000000 +0200
@@ -157,6 +157,7 @@
static u32 pci_iobase = 0x100;
static u32 pci_membase = SB_PCI_DMA;
+static u32 pcmcia_membase = 0x40004000;
void __init
pcibios_fixup_bus(struct pci_bus *b)
@@ -188,7 +189,7 @@
/* Fix up resource bases */
for (pos = 0; pos < 6; pos++) {
res = &d->resource[pos];
- base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase;
+ base = (res->flags & IORESOURCE_IO) ? &pci_iobase : ((b->number == 2) ? &pcmcia_membase : &pci_membase);
if (res->end) {
size = res->end - res->start + 1;
if (*base & (size - 1))
@@ -308,7 +309,12 @@
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
- reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+
+ if (dev->bus->number == 1)
+ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+ else
+ reg = res->start;
+
pci_write_config_dword(dev, where, reg);
}
diff -urN linux.old/drivers/pcmcia/yenta.c linux.dev/drivers/pcmcia/yenta.c
--- linux.old/drivers/pcmcia/yenta.c 2004-11-17 12:54:21.000000000 +0100
+++ linux.dev/drivers/pcmcia/yenta.c 2006-04-11 17:47:45.000000000 +0200