source: clfs-embedded/patches/linux-2.6.19-bcm947xx.patch@ 405463f

Last change on this file since 405463f was 21e0fdf, checked in by Maarten Lankhorst <m.b.lankhorst@…>, 18 years ago

Add required patches

  • Property mode set to 100644
File size: 226.7 KB
  • arch/mips/Kconfig

    diff -Nru linux-2.6.19.ori/arch/mips/Kconfig linux-2.6.19/arch/mips/Kconfig
    old new  
    44        # Horrible source of confusion.  Die, die, die ...
    55        select EMBEDDED
    66
     7config CFE
     8        bool
     9        # Common Firmware Environment
     10
    711mainmenu "Linux/MIPS Kernel Configuration"
    812
    913menu "Machine selection"
     
    222226         Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
    223227         Olivetti M700-10 workstations.
    224228
     229config BCM947XX
     230        bool "Support for BCM947xx based boards"
     231        select DMA_NONCOHERENT
     232        select HW_HAS_PCI
     233        select IRQ_CPU
     234        select SYS_HAS_CPU_MIPS32_R1
     235        select SYS_SUPPORTS_32BIT_KERNEL
     236        select SYS_SUPPORTS_LITTLE_ENDIAN
     237        select MIPS_CPU_SCACHE
     238        select SSB
     239        select SSB_DRIVER_MIPS
     240        select SSB_DRIVER_EXTIF
     241        select CFE
     242        help
     243         Support for BCM947xx based boards
     244
    225245config LASAT
    226246        bool "LASAT Networks platforms"
    227247        select DMA_NONCOHERENT
  • arch/mips/Makefile

    diff -Nru linux-2.6.19.ori/arch/mips/Makefile linux-2.6.19/arch/mips/Makefile
    old new  
    571571load-$(CONFIG_SIBYTE_BIGSUR)    := 0xffffffff80100000
    572572
    573573#
     574# Broadcom BCM47XX boards
     575#
     576core-$(CONFIG_BCM947XX)         += arch/mips/bcm947xx/
     577cflags-$(CONFIG_BCM947XX)       += -Iarch/mips/bcm947xx/include -Iinclude/asm-mips/mach-bcm947xx
     578load-$(CONFIG_BCM947XX)         := 0xffffffff80001000
     579
     580#
     581# Common Firmware Environment
     582#
     583core-$(CONFIG_CFE)              += arch/mips/cfe/
     584
     585#
    574586# SNI RM200 PCI
    575587#
    576588core-$(CONFIG_SNI_RM200_PCI)    += arch/mips/sni/
  • arch/mips/bcm947xx/Makefile

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/Makefile linux-2.6.19/arch/mips/bcm947xx/Makefile
    old new  
     1#
     2# Makefile for the BCM47xx specific kernel interface routines
     3# under Linux.
     4#
     5
     6obj-y := irq.o prom.o setup.o time.o
     7obj-y += nvram.o cfe_env.o
     8#obj-y += pci.o
  • arch/mips/bcm947xx/cfe_env.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/cfe_env.c linux-2.6.19/arch/mips/bcm947xx/cfe_env.c
    old new  
     1/*
     2 * CFE environment varialble access
     3 *
     4 * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
     5 *
     6 * This program is free software; you can redistribute  it and/or modify it
     7 * under  the terms of  the GNU General  Public License as published by the
     8 * Free Software Foundation;  either version 2 of the  License, or (at your
     9 * option) any later version.
     10 *
     11 * Copyright 2001-2003, Broadcom Corporation
     12 *
     13 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
     14 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
     15 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
     16 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
     17 */
     18
     19#include <linux/init.h>
     20#include <linux/module.h>
     21#include <linux/kernel.h>
     22#include <linux/string.h>
     23#include <asm/io.h>
     24#include <asm/uaccess.h>
     25
     26#define NVRAM_SIZE       (0x1ff0)
     27static char _nvdata[NVRAM_SIZE] __initdata;
     28static char _valuestr[256] __initdata;
     29
     30/*
     31 * TLV types.  These codes are used in the "type-length-value"
     32 * encoding of the items stored in the NVRAM device (flash or EEPROM)
     33 *
     34 * The layout of the flash/nvram is as follows:
     35 *
     36 * <type> <length> <data ...> <type> <length> <data ...> <type_end>
     37 *
     38 * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
     39 * The "length" field marks the length of the data section, not
     40 * including the type and length fields.
     41 *
     42 * Environment variables are stored as follows:
     43 *
     44 * <type_env> <length> <flags> <name> = <value>
     45 *
     46 * If bit 0 (low bit) is set, the length is an 8-bit value.
     47 * If bit 0 (low bit) is clear, the length is a 16-bit value
     48 *
     49 * Bit 7 set indicates "user" TLVs.  In this case, bit 0 still
     50 * indicates the size of the length field. 
     51 *
     52 * Flags are from the constants below:
     53 *
     54 */
     55#define ENV_LENGTH_16BITS       0x00    /* for low bit */
     56#define ENV_LENGTH_8BITS        0x01
     57
     58#define ENV_TYPE_USER           0x80
     59
     60#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
     61#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
     62
     63/*
     64 * The actual TLV types we support
     65 */
     66
     67#define ENV_TLV_TYPE_END        0x00   
     68#define ENV_TLV_TYPE_ENV        ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
     69
     70/*
     71 * Environment variable flags
     72 */
     73
     74#define ENV_FLG_NORMAL          0x00    /* normal read/write */
     75#define ENV_FLG_BUILTIN         0x01    /* builtin - not stored in flash */
     76#define ENV_FLG_READONLY        0x02    /* read-only - cannot be changed */
     77
     78#define ENV_FLG_MASK            0xFF    /* mask of attributes we keep */
     79#define ENV_FLG_ADMIN           0x100   /* lets us internally override permissions */
     80
     81
     82/*  *********************************************************************
     83    *  _nvram_read(buffer,offset,length)
     84    * 
     85    *  Read data from the NVRAM device
     86    * 
     87    *  Input parameters:
     88    *      buffer - destination buffer
     89    *      offset - offset of data to read
     90    *      length - number of bytes to read
     91    *     
     92    *  Return value:
     93    *      number of bytes read, or <0 if error occured
     94    ********************************************************************* */
     95static int
     96_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
     97{
     98    int i;
     99    if (offset > NVRAM_SIZE)
     100        return -1;
     101
     102    for ( i = 0; i < length; i++) {
     103        buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
     104    }
     105    return length;
     106}
     107
     108
     109static char*
     110_strnchr(const char *dest,int c,size_t cnt)
     111{
     112        while (*dest && (cnt > 0)) {
     113        if (*dest == c) return (char *) dest;
     114        dest++;
     115        cnt--;
     116        }
     117        return NULL;
     118}
     119
     120
     121
     122/*
     123 * Core support API: Externally visible.
     124 */
     125
     126/*
     127 * Get the value of an NVRAM variable
     128 * @param       name    name of variable to get
     129 * @return      value of variable or NULL if undefined
     130 */
     131
     132char*
     133cfe_env_get(unsigned char *nv_buf, char* name)
     134{
     135    int size;
     136    unsigned char *buffer;
     137    unsigned char *ptr;
     138    unsigned char *envval;
     139    unsigned int reclen;
     140    unsigned int rectype;
     141    int offset;
     142    int flg;
     143   
     144    size = NVRAM_SIZE;
     145    buffer = &_nvdata[0];
     146
     147    ptr = buffer;
     148    offset = 0;
     149
     150    /* Read the record type and length */
     151    if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
     152        goto error;
     153    }
     154   
     155    while ((*ptr != ENV_TLV_TYPE_END)  && (size > 1)) {
     156
     157        /* Adjust pointer for TLV type */
     158        rectype = *(ptr);
     159        offset++;
     160        size--;
     161
     162        /*
     163         * Read the length.  It can be either 1 or 2 bytes
     164         * depending on the code
     165         */
     166        if (rectype & ENV_LENGTH_8BITS) {
     167            /* Read the record type and length - 8 bits */
     168            if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
     169                goto error;
     170            }
     171            reclen = *(ptr);
     172            size--;
     173            offset++;
     174        }
     175        else {
     176            /* Read the record type and length - 16 bits, MSB first */
     177            if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
     178                goto error;
     179            }
     180            reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
     181            size -= 2;
     182            offset += 2;
     183        }
     184
     185        if (reclen > size)
     186            break;      /* should not happen, bad NVRAM */
     187
     188        switch (rectype) {
     189            case ENV_TLV_TYPE_ENV:
     190                /* Read the TLV data */
     191                if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
     192                    goto error;
     193                flg = *ptr++;
     194                envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
     195                if (envval) {
     196                    *envval++ = '\0';
     197                    memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
     198                    _valuestr[(reclen-1)-(envval-ptr)] = '\0';
     199#if 0                   
     200                    printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
     201#endif
     202                    if(!strcmp(ptr, name)){
     203                        return _valuestr;
     204                    }
     205                    if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
     206                        return _valuestr;
     207                }
     208                break;
     209               
     210            default:
     211                /* Unknown TLV type, skip it. */
     212                break;
     213            }
     214
     215        /*
     216         * Advance to next TLV
     217         */
     218               
     219        size -= (int)reclen;
     220        offset += reclen;
     221
     222        /* Read the next record type */
     223        ptr = buffer;
     224        if (_nvram_read(nv_buf, ptr,offset,1) != 1)
     225            goto error;
     226        }
     227
     228error:
     229    return NULL;
     230
     231}
     232
  • arch/mips/bcm947xx/include/nvram.h

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/include/nvram.h linux-2.6.19/arch/mips/bcm947xx/include/nvram.h
    old new  
     1/*
     2 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 */
     9
     10#ifndef __NVRAM_H
     11#define __NVRAM_H
     12
     13struct nvram_header {
     14        u32 magic;
     15        u32 len;
     16        u32 crc_ver_init;       /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
     17        u32 config_refresh;     /* 0:15 sdram_config, 16:31 sdram_refresh */
     18        u32 config_ncdl;        /* ncdl values for memc */
     19};
     20
     21struct nvram_tuple {
     22        char *name;
     23        char *value;
     24        struct nvram_tuple *next;
     25};
     26
     27#define NVRAM_HEADER            0x48534C46      /* 'FLSH' */
     28#define NVRAM_VERSION           1
     29#define NVRAM_HEADER_SIZE       20
     30#define NVRAM_SPACE             0x8000
     31
     32#define NVRAM_MAX_VALUE_LEN 255
     33#define NVRAM_MAX_PARAM_LEN 64
     34
     35char *nvram_get(const char *name);
     36
     37#endif
  • arch/mips/bcm947xx/irq.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/irq.c linux-2.6.19/arch/mips/bcm947xx/irq.c
    old new  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 *
     9 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     10 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     11 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     12 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     13 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     14 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     15 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     16 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     17 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     18 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     19 *
     20 *  You should have received a copy of the  GNU General Public License along
     21 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     22 *  675 Mass Ave, Cambridge, MA 02139, USA.
     23 */
     24
     25#include <linux/errno.h>
     26#include <linux/init.h>
     27#include <linux/interrupt.h>
     28#include <linux/irq.h>
     29#include <linux/module.h>
     30#include <linux/smp.h>
     31#include <linux/types.h>
     32
     33#include <asm/cpu.h>
     34#include <asm/io.h>
     35#include <asm/irq.h>
     36#include <asm/irq_cpu.h>
     37
     38void plat_irq_dispatch(void)
     39{
     40        u32 cause;
     41
     42        cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
     43
     44        clear_c0_status(cause);
     45
     46        if (cause & CAUSEF_IP7)
     47                do_IRQ(7);
     48        if (cause & CAUSEF_IP2)
     49                do_IRQ(2);
     50        if (cause & CAUSEF_IP3)
     51                do_IRQ(3);
     52        if (cause & CAUSEF_IP4)
     53                do_IRQ(4);
     54        if (cause & CAUSEF_IP5)
     55                do_IRQ(5);
     56        if (cause & CAUSEF_IP6)
     57                do_IRQ(6);
     58}
     59
     60void __init arch_init_irq(void)
     61{
     62        mips_cpu_irq_init(0);
     63}
  • arch/mips/bcm947xx/nvram.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/nvram.c linux-2.6.19/arch/mips/bcm947xx/nvram.c
    old new  
     1/*
     2 * BCM947xx nvram variable access
     3 *
     4 * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
     5 *
     6 * This program is free software; you can redistribute  it and/or modify it
     7 * under  the terms of  the GNU General  Public License as published by the
     8 * Free Software Foundation;  either version 2 of the  License, or (at your
     9 * option) any later version.
     10 *
     11 *
     12 * Copyright 2005, Broadcom Corporation
     13 *
     14 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
     15 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
     16 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
     17 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
     18 *
     19 */
     20
     21#include <linux/init.h>
     22#include <linux/module.h>
     23#include <linux/ssb.h>
     24#include <linux/kernel.h>
     25#include <linux/string.h>
     26#include <linux/interrupt.h>
     27#include <linux/spinlock.h>
     28#include <linux/slab.h>
     29#include <asm/byteorder.h>
     30#include <asm/bootinfo.h>
     31#include <asm/addrspace.h>
     32#include <asm/io.h>
     33#include <asm/uaccess.h>
     34
     35#include <nvram.h>
     36
     37#define MB * 1048576
     38extern struct ssb_bus ssb;
     39
     40static char nvram_buf[NVRAM_SPACE];
     41static int cfe_env;
     42extern char *cfe_env_get(char *nv_buf, const char *name);
     43               
     44/* Probe for NVRAM header */
     45static void __init early_nvram_init(void)
     46{
     47        struct ssb_mipscore *mcore = &ssb.mipscore;
     48        struct nvram_header *header;
     49        int i;
     50        u32 base, lim, off;
     51        u32 *src, *dst;
     52       
     53        base = mcore->flash_window;
     54        lim = mcore->flash_window_size;
     55        cfe_env = 0;
     56
     57       
     58        /* XXX: hack for supporting the CFE environment stuff on WGT634U */
     59        if (lim >= 8 MB) {
     60                src = (u32 *) KSEG1ADDR(base + 8 MB - 0x2000);
     61                dst = (u32 *) nvram_buf;
     62
     63                if ((*src & 0xff00ff) == 0x000001) {
     64                        printk("early_nvram_init: WGT634U NVRAM found.\n");
     65
     66                        for (i = 0; i < 0x1ff0; i++) {
     67                                if (*src == 0xFFFFFFFF)
     68                                        break;
     69                                *dst++ = *src++;
     70                        }
     71                        cfe_env = 1;
     72                        return;
     73                }
     74        }
     75
     76        off = 0x20000;
     77        while (off <= lim) {
     78                /* Windowed flash access */
     79                header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
     80                if (header->magic == NVRAM_HEADER)
     81                        goto found;
     82                off <<= 1;
     83        }
     84
     85        /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
     86        header = (struct nvram_header *) KSEG1ADDR(base + 4096);
     87        if (header->magic == NVRAM_HEADER)
     88                goto found;
     89       
     90        header = (struct nvram_header *) KSEG1ADDR(base + 1024);
     91        if (header->magic == NVRAM_HEADER)
     92                goto found;
     93       
     94        return;
     95
     96found:
     97        src = (u32 *) header;
     98        dst = (u32 *) nvram_buf;
     99        for (i = 0; i < sizeof(struct nvram_header); i += 4)
     100                *dst++ = *src++;
     101        for (; i < header->len && i < NVRAM_SPACE; i += 4)
     102                *dst++ = le32_to_cpu(*src++);
     103}
     104
     105char *nvram_get(const char *name)
     106{
     107        char *var, *value, *end, *eq;
     108
     109        if (!name)
     110                return NULL;
     111
     112        if (!nvram_buf[0])
     113                early_nvram_init();
     114
     115        if (cfe_env)
     116                return cfe_env_get(nvram_buf, name);
     117
     118        /* Look for name=value and return value */
     119        var = &nvram_buf[sizeof(struct nvram_header)];
     120        end = nvram_buf + sizeof(nvram_buf) - 2;
     121        end[0] = end[1] = '\0';
     122        for (; *var; var = value + strlen(value) + 1) {
     123                if (!(eq = strchr(var, '=')))
     124                        break;
     125                value = eq + 1;
     126                if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
     127                        return value;
     128        }
     129
     130        return NULL;
     131}
  • arch/mips/bcm947xx/pci.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/pci.c linux-2.6.19/arch/mips/bcm947xx/pci.c
    old new  
     1#include <linux/kernel.h>
     2#include <linux/init.h>
     3#include <linux/pci.h>
     4#include <linux/types.h>
     5
     6#include <asm/cpu.h>
     7#include <asm/io.h>
     8
     9#include <typedefs.h>
     10#include <osl.h>
     11#include <sbutils.h>
     12#include <sbmips.h>
     13#include <sbconfig.h>
     14#include <sbpci.h>
     15#include <bcmdevs.h>
     16#include <pcicfg.h>
     17
     18extern sb_t *sbh;
     19extern spinlock_t sbh_lock;
     20
     21
     22static int
     23sb_pci_read_config(struct pci_bus *bus, unsigned int devfn,
     24                                int reg, int size, u32 *val)
     25{
     26        int ret;
     27        unsigned long flags;
     28       
     29        spin_lock_irqsave(&sbh_lock, flags);
     30        ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size);
     31        spin_unlock_irqrestore(&sbh_lock, flags);
     32
     33        return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
     34}
     35
     36static int
     37sb_pci_write_config(struct pci_bus *bus, unsigned int devfn,
     38                                int reg, int size, u32 val)
     39{
     40        int ret;
     41        unsigned long flags;
     42       
     43        spin_lock_irqsave(&sbh_lock, flags);
     44        ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size);
     45        spin_unlock_irqrestore(&sbh_lock, flags);
     46
     47        return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
     48}
     49
     50
     51static struct pci_ops sb_pci_ops = {
     52        .read   = sb_pci_read_config,
     53        .write  = sb_pci_write_config,
     54};
     55
     56static struct resource sb_pci_mem_resource = {
     57        .name   = "SB PCI Memory resources",
     58        .start  = SB_ENUM_BASE,
     59        .end    = SB_ENUM_LIM - 1,
     60        .flags  = IORESOURCE_MEM,
     61};
     62
     63static struct resource sb_pci_io_resource = {
     64        .name   = "SB PCI I/O resources",
     65        .start  = 0x000,
     66        .end    = 0x0FF,
     67        .flags  = IORESOURCE_IO,
     68};
     69
     70static struct pci_controller bcm47xx_sb_pci_controller = {
     71        .pci_ops        = &sb_pci_ops,
     72        .mem_resource   = &sb_pci_mem_resource,
     73        .io_resource    = &sb_pci_io_resource,
     74};
     75
     76static struct resource ext_pci_mem_resource = {
     77        .name   = "Ext PCI Memory resources",
     78        .start  = 0x40000000,
     79        .end    = 0x7fffffff,
     80        .flags  = IORESOURCE_MEM,
     81};
     82
     83static struct resource ext_pci_io_resource = {
     84        .name   = "Ext PCI I/O resources",
     85        .start  = 0x100,
     86        .end    = 0x7FF,
     87        .flags  = IORESOURCE_IO,
     88};
     89
     90static struct pci_controller bcm47xx_ext_pci_controller = {
     91        .pci_ops        = &sb_pci_ops,
     92        .io_resource    = &ext_pci_io_resource,
     93        .mem_resource   = &ext_pci_mem_resource,
     94        .mem_offset             = 0x24000000,
     95};
     96
     97void bcm47xx_pci_init(void)
     98{
     99        unsigned long flags;
     100       
     101        spin_lock_irqsave(&sbh_lock, flags);
     102        sbpci_init(sbh);
     103        spin_unlock_irqrestore(&sbh_lock, flags);
     104
     105        set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
     106
     107        register_pci_controller(&bcm47xx_sb_pci_controller);
     108        register_pci_controller(&bcm47xx_ext_pci_controller);
     109}
     110
     111int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
     112{
     113        unsigned long flags;
     114        u8 irq;
     115        uint idx;
     116       
     117        /* external: use the irq of the pci core */
     118        if (dev->bus->number >= 1) {
     119                spin_lock_irqsave(&sbh_lock, flags);
     120                idx = sb_coreidx(sbh);
     121                sb_setcore(sbh, SB_PCI, 0);
     122                irq = sb_irq(sbh);
     123                sb_setcoreidx(sbh, idx);
     124                spin_unlock_irqrestore(&sbh_lock, flags);
     125               
     126                return irq + 2;
     127        }
     128       
     129        /* internal */
     130        pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
     131        return irq + 2;
     132}
     133
     134u32 pci_iobase = 0x100;
     135u32 pci_membase = SB_PCI_DMA;
     136
     137static void bcm47xx_fixup_device(struct pci_dev *d)
     138{
     139        struct resource *res;
     140        int pos, size;
     141        u32 *base;
     142
     143        if (d->bus->number == 0)
     144                return;
     145       
     146        printk("PCI: Fixing up device %s\n", pci_name(d));
     147
     148        /* Fix up resource bases */
     149        for (pos = 0; pos < 6; pos++) {
     150                res = &d->resource[pos];
     151                base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
     152                if (res->end) {
     153                        size = res->end - res->start + 1;
     154                        if (*base & (size - 1))
     155                                *base = (*base + size) & ~(size - 1);
     156                        res->start = *base;
     157                        res->end = res->start + size - 1;
     158                        *base += size;
     159                        pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
     160                }
     161                /* Fix up PCI bridge BAR0 only */
     162                if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
     163                        break;
     164        }
     165        /* Fix up interrupt lines */
     166        if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
     167                d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
     168        pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
     169}
     170
     171
     172static void bcm47xx_fixup_bridge(struct pci_dev *dev)
     173{
     174        if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
     175                return;
     176       
     177        printk("PCI: fixing up bridge\n");
     178
     179        /* Enable PCI bridge bus mastering and memory space */
     180        pci_set_master(dev);
     181        pcibios_enable_device(dev, ~0);
     182       
     183        /* Enable PCI bridge BAR1 prefetch and burst */
     184        pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
     185}
     186
     187/* Do platform specific device initialization at pci_enable_device() time */
     188int pcibios_plat_dev_init(struct pci_dev *dev)
     189{
     190        uint coreidx;
     191        unsigned long flags;
     192       
     193        bcm47xx_fixup_device(dev);
     194
     195        /* These cores come out of reset enabled */
     196        if ((dev->bus->number != 0) ||
     197                (dev->device == SB_MIPS) ||
     198                (dev->device == SB_MIPS33) ||
     199                (dev->device == SB_EXTIF) ||
     200                (dev->device == SB_CC))
     201                return 0;
     202
     203        /* Do a core reset */
     204        spin_lock_irqsave(&sbh_lock, flags);
     205        coreidx = sb_coreidx(sbh);
     206        if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) {
     207                /*
     208                 * The USB core requires a special bit to be set during core
     209                 * reset to enable host (OHCI) mode. Resetting the SB core in
     210                 * pcibios_enable_device() is a hack for compatibility with
     211                 * vanilla usb-ohci so that it does not have to know about
     212                 * SB. A driver that wants to use the USB core in device mode
     213                 * should know about SB and should reset the bit back to 0
     214                 * after calling pcibios_enable_device().
     215                 */
     216                sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
     217                sb_core_reset(sbh, 1 << 29);
     218        } else {
     219                sb_core_reset(sbh, 0);
     220        }
     221        sb_setcoreidx(sbh, coreidx);
     222        spin_unlock_irqrestore(&sbh_lock, flags);
     223       
     224        return 0;
     225}
     226
     227DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);
  • arch/mips/bcm947xx/prom.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/prom.c linux-2.6.19/arch/mips/bcm947xx/prom.c
    old new  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 *
     9 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     10 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     11 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     12 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     13 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     14 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     15 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     16 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     17 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     18 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     19 *
     20 *  You should have received a copy of the  GNU General Public License along
     21 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     22 *  675 Mass Ave, Cambridge, MA 02139, USA.
     23 */
     24
     25#include <linux/init.h>
     26#include <linux/mm.h>
     27#include <linux/sched.h>
     28#include <linux/bootmem.h>
     29
     30#include <asm/addrspace.h>
     31#include <asm/bootinfo.h>
     32#include <asm/pmon.h>
     33
     34const char *get_system_type(void)
     35{
     36        return "Broadcom BCM47xx";
     37}
     38
     39void __init prom_init(void)
     40{
     41        unsigned long mem;
     42
     43        mips_machgroup = MACH_GROUP_BRCM;
     44        mips_machtype = MACH_BCM47XX;
     45
     46        /* Figure out memory size by finding aliases */
     47        for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
     48                if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
     49                    *(unsigned long *)(prom_init))
     50                        break;
     51        }
     52
     53        add_memory_region(0, mem, BOOT_MEM_RAM);
     54}
     55
     56unsigned long __init prom_free_prom_memory(void)
     57{
     58        return 0;
     59}
  • arch/mips/bcm947xx/setup.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/setup.c linux-2.6.19/arch/mips/bcm947xx/setup.c
    old new  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
     4 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
     5 *  Copyright (C) 2006 Michael Buesch
     6 *
     7 *  This program is free software; you can redistribute  it and/or modify it
     8 *  under  the terms of  the GNU General  Public License as published by the
     9 *  Free Software Foundation;  either version 2 of the  License, or (at your
     10 *  option) any later version.
     11 *
     12 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     13 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     14 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     15 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     16 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     17 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     18 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     19 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     20 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     21 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     22 *
     23 *  You should have received a copy of the  GNU General Public License along
     24 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     25 *  675 Mass Ave, Cambridge, MA 02139, USA.
     26 */
     27
     28#include <linux/init.h>
     29#include <linux/types.h>
     30#include <linux/tty.h>
     31#include <linux/serial.h>
     32#include <linux/serial_core.h>
     33#include <linux/serial_reg.h>
     34#include <asm/bootinfo.h>
     35#include <asm/time.h>
     36#include <asm/reboot.h>
     37#include <asm/cfe.h>
     38#include <linux/pm.h>
     39#include <linux/ssb.h>
     40
     41#include <nvram.h>
     42
     43extern void bcm47xx_pci_init(void);
     44extern void bcm47xx_time_init(void);
     45
     46struct ssb_bus ssb;
     47
     48static void bcm47xx_machine_restart(char *command)
     49{
     50        printk(KERN_ALERT "Please stand by while rebooting the system...\n");
     51        local_irq_disable();
     52        /* CFE has a reboot callback, but that does not work.
     53         * Oopses with: Reserved instruction in kernel code.
     54         */
     55
     56        /* Set the watchdog timer to reset immediately */
     57//TODO  sb_watchdog(sbh, 1);
     58        while (1)
     59                cpu_relax();
     60}
     61
     62static void bcm47xx_machine_halt(void)
     63{
     64        /* Disable interrupts and watchdog and spin forever */
     65        local_irq_disable();
     66//TODO  sb_watchdog(sbh, 0);
     67        while (1)
     68                cpu_relax();
     69}
     70
     71static void e_aton(char *str, char *dest)
     72{
     73        int i = 0;
     74
     75        if (str == NULL) {
     76                memset(dest, 0, 6);
     77                return;
     78        }
     79       
     80        for (;;) {
     81                dest[i++] = (char) simple_strtoul(str, NULL, 16);
     82                str += 2;
     83                if (!*str++ || i == 6)
     84                        break;
     85        }
     86}
     87
     88static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
     89{
     90        // TODO
     91}
     92
     93static void bcm47xx_fill_sprom_nvram(struct ssb_sprom *sprom)
     94{
     95        char *s;
     96
     97        memset(sprom, 0, sizeof(struct ssb_sprom));
     98       
     99        sprom->revision = 3;
     100        if ((s = nvram_get("et0macaddr")))
     101                e_aton(s, sprom->r1.et0mac);
     102        if ((s = nvram_get("et1macaddr")))
     103                e_aton(s, sprom->r1.et1mac);
     104        if ((s = nvram_get("et0phyaddr")))
     105                sprom->r1.et0phyaddr = simple_strtoul(s, NULL, 10);
     106        if ((s = nvram_get("et1phyaddr")))
     107                sprom->r1.et1phyaddr = simple_strtoul(s, NULL, 10);
     108}
     109
     110void __init plat_mem_setup(void)
     111{
     112        int i, err;
     113        char *s;
     114        struct ssb_mipscore *mcore;
     115
     116        err = ssb_bus_ssbbus_register(&ssb, SSB_ENUM_BASE, bcm47xx_fill_sprom);
     117        if (err) {
     118                const char *msg = "Failed to initialize SSB bus (err %d)\n";
     119                cfe_printk(msg, err); /* Make sure the message gets out of the box. */
     120                panic(msg, err);
     121        }
     122        mcore = &ssb.mipscore;
     123
     124        /* FIXME: the nvram init depends on the ssb being fully initializes,
     125         * can't use the fill_sprom callback yet! */
     126        bcm47xx_fill_sprom_nvram(&ssb.sprom);
     127       
     128        s = nvram_get("kernel_args");
     129        if (s && !strncmp(s, "console=ttyS1", 13) && (mcore->nr_serial_ports >= 2)) {
     130                struct ssb_serial_port port;
     131
     132                /* swap serial ports */
     133                memcpy(&port, &mcore->serial_ports[0], sizeof(port));
     134                memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], sizeof(port));
     135                memcpy(&mcore->serial_ports[1], &port, sizeof(port));
     136        }
     137
     138        for (i = 0; i < mcore->nr_serial_ports; i++) {
     139                struct ssb_serial_port *port = &(mcore->serial_ports[i]);
     140                struct uart_port s;
     141       
     142                memset(&s, 0, sizeof(s));
     143                s.line = i;
     144                s.membase = port->regs;
     145                s.irq = port->irq + 2;//FIXME?
     146                s.uartclk = port->baud_base;
     147                s.flags = ASYNC_BOOT_AUTOCONF;
     148                s.iotype = SERIAL_IO_MEM;
     149                s.regshift = port->reg_shift;
     150
     151                early_serial_setup(&s);
     152        }
     153        cfe_printk("Serial init done.\n");
     154
     155        _machine_restart = bcm47xx_machine_restart;
     156        _machine_halt = bcm47xx_machine_halt;
     157        pm_power_off = bcm47xx_machine_halt;
     158
     159        board_time_init = bcm47xx_time_init;//FIXME move into ssb
     160}
     161
  • arch/mips/bcm947xx/time.c

    diff -Nru linux-2.6.19.ori/arch/mips/bcm947xx/time.c linux-2.6.19/arch/mips/bcm947xx/time.c
    old new  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 *
     9 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     10 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     11 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     12 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     13 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     14 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     15 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     16 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     17 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     18 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     19 *
     20 *  You should have received a copy of the  GNU General Public License along
     21 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     22 *  675 Mass Ave, Cambridge, MA 02139, USA.
     23 */
     24
     25#include <linux/init.h>
     26#include <linux/kernel.h>
     27#include <linux/sched.h>
     28#include <linux/serial_reg.h>
     29#include <linux/interrupt.h>
     30#include <linux/ssb.h>
     31#include <asm/addrspace.h>
     32#include <asm/io.h>
     33#include <asm/time.h>
     34
     35extern struct ssb_bus ssb;
     36
     37void __init
     38bcm47xx_time_init(void)
     39{
     40        unsigned long hz;
     41
     42        /*
     43         * Use deterministic values for initial counter interrupt
     44         * so that calibrate delay avoids encountering a counter wrap.
     45         */
     46        write_c0_count(0);
     47        write_c0_compare(0xffff);
     48
     49        hz = ssb_clockspeed(&ssb);
     50        if (!hz)
     51                hz = 100000000;
     52
     53        /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
     54        mips_hpt_frequency = hz;
     55}
     56
     57void __init
     58plat_timer_setup(struct irqaction *irq)
     59{
     60        /* Enable the timer interrupt */
     61        setup_irq(7, irq);
     62}
  • arch/mips/cfe/Makefile

    diff -Nru linux-2.6.19.ori/arch/mips/cfe/Makefile linux-2.6.19/arch/mips/cfe/Makefile
    old new  
     1#
     2# Makefile for the Broadcom Common Firmware Environment support
     3#
     4
     5obj-y += cfe.o
  • arch/mips/cfe/cfe.c

    diff -Nru linux-2.6.19.ori/arch/mips/cfe/cfe.c linux-2.6.19/arch/mips/cfe/cfe.c
    old new  
     1/*
     2 * Broadcom Common Firmware Environment (CFE) support
     3 *
     4 * Copyright 2000, 2001, 2002
     5 * Broadcom Corporation. All rights reserved.
     6 *
     7 * Copyright (C) 2006 Michael Buesch
     8 *
     9 * Original Authors:  Mitch Lichtenberg, Chris Demetriou
     10 *
     11 * This software is furnished under license and may be used and copied only
     12 * in accordance with the following terms and conditions.  Subject to these
     13 * conditions, you may download, copy, install, use, modify and distribute
     14 * modified or unmodified copies of this software in source and/or binary
     15 * form. No title or ownership is transferred hereby.
     16 *
     17 * 1) Any source code used, modified or distributed must reproduce and
     18 *    retain this copyright notice and list of conditions as they appear in
     19 *    the source file.
     20 *
     21 * 2) No right is granted to use any trade name, trademark, or logo of
     22 *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
     23 *    used to endorse or promote products derived from this software
     24 *    without the prior written permission of Broadcom Corporation.
     25 *
     26 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
     27 *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
     28 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
     29 *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
     30 *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
     31 *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     34 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     35 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     36 *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37 */
     38
     39#include <linux/init.h>
     40#include <linux/string.h>
     41#include <linux/errno.h>
     42#include <linux/spinlock.h>
     43#include <asm/cfe.h>
     44
     45#include "cfe_private.h"
     46
     47
     48static cfe_uint_t cfe_handle;
     49static int (*cfe_trampoline)(long handle, long iocb);
     50
     51
     52#include <linux/kernel.h>
     53
     54void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
     55                      unsigned long fwarg2, unsigned long fwarg3)
     56{
     57        if (fwarg3 == 0x80300000) {
     58                /* WRT54G workaround */
     59                fwarg3 = CFE_EPTSEAL;
     60                fwarg2 = 0xBFC00500;
     61        }
     62        if (fwarg3 != CFE_EPTSEAL) {
     63                /* We are not booted from CFE */
     64                return;
     65        }
     66        if (fwarg1 == 0) {
     67                /* We are on the boot CPU */
     68                cfe_handle = (cfe_uint_t)fwarg0;
     69                cfe_trampoline = CFE_TO_PTR(fwarg2);
     70        }
     71}
     72
     73int cfe_vprintk(const char *fmt, va_list args)
     74{
     75        static char buffer[1024];
     76        static DEFINE_SPINLOCK(lock);
     77        static const char pfx[] = "CFE-console: ";
     78        static const size_t pfx_len = sizeof(pfx) - 1;
     79        unsigned long flags;
     80        int len, cnt, pos;
     81        int handle;
     82        int res;
     83
     84        if (!cfe_present())
     85                return -ENODEV;
     86
     87        spin_lock_irqsave(&lock, flags);
     88        handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
     89        if (CFE_ISERR(handle)) {
     90                len = -EIO;
     91                goto out;
     92        }
     93        strcpy(buffer, pfx);
     94        len = vscnprintf(buffer + pfx_len,
     95                         sizeof(buffer) - pfx_len - 2,
     96                         fmt, args);
     97        len += pfx_len;
     98        /* The CFE console requires CR-LF line-ends.
     99         * Add a CR, if we only terminate lines with a LF.
     100         * This does only fix CR-LF at the end of the string.
     101         * So for multiple lines, use multiple cfe_vprintk calls.
     102         */
     103        if (len > 1 &&
     104            buffer[len - 1] == '\n' && buffer[len - 2] != '\r') {
     105                buffer[len - 1] = '\r';
     106                buffer[len] = '\n';
     107                len += 1;
     108        }
     109        cnt = len;
     110        pos = 0;
     111        while (cnt > 0) {
     112                res = cfe_write(handle, buffer + pos, len - pos);
     113                if (CFE_ISERR(res)) {
     114                        len = -EIO;
     115                        goto out;
     116                }
     117                cnt -= res;
     118                pos += res;
     119        }
     120out:
     121        spin_unlock_irqrestore(&lock, flags);
     122
     123        return len;
     124}
     125
     126int cfe_printk(const char *fmt, ...)
     127{
     128        va_list args;
     129        int res;
     130
     131        va_start(args, fmt);
     132        res = cfe_vprintk(fmt, args);
     133        va_end(args);
     134
     135        return res;
     136}
     137
     138static int cfe_iocb_dispatch(struct cfe_iocb *iocb)
     139{
     140        if (!cfe_present())
     141                return CFE_ERR_UNSUPPORTED;
     142        return cfe_trampoline((long)cfe_handle, (long)iocb);
     143}
     144
     145int cfe_present(void)
     146{
     147        return (cfe_trampoline != NULL);
     148}
     149
     150int cfe_close(int handle)
     151{
     152        struct cfe_iocb iocb;
     153        int err;
     154
     155        memset(&iocb, 0, sizeof(iocb));
     156        iocb.fcode = CFE_CMD_DEV_CLOSE;
     157        iocb.handle = handle;
     158
     159        err = cfe_iocb_dispatch(&iocb);
     160
     161        return (CFE_ISERR(err)) ? err : iocb.status;
     162}
     163
     164int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1)
     165{
     166        struct cfe_iocb iocb;
     167        int err;
     168
     169        memset(&iocb, 0, sizeof(iocb));
     170        iocb.fcode = CFE_CMD_FW_CPUCTL;
     171        iocb.psize = sizeof(struct cfe_iocb_cpuctl);
     172        iocb.cpuctl.number = cpu;
     173        iocb.cpuctl.command = CFE_CPU_CMD_START;
     174        iocb.cpuctl.gp = gp;
     175        iocb.cpuctl.sp = sp;
     176        iocb.cpuctl.a1 = a1;
     177        iocb.cpuctl.start_addr = (long)fn;
     178
     179        err = cfe_iocb_dispatch(&iocb);
     180
     181        return (CFE_ISERR(err)) ? err : iocb.status;
     182}
     183
     184int cfe_cpu_stop(int cpu)
     185{
     186        struct cfe_iocb iocb;
     187        int err;
     188
     189        memset(&iocb, 0, sizeof(iocb));
     190        iocb.fcode = CFE_CMD_FW_CPUCTL;
     191        iocb.psize = sizeof(struct cfe_iocb_cpuctl);
     192        iocb.cpuctl.number = cpu;
     193        iocb.cpuctl.command = CFE_CPU_CMD_STOP;
     194
     195        err = cfe_iocb_dispatch(&iocb);
     196
     197        return (CFE_ISERR(err)) ? err : iocb.status;
     198}
     199
     200int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
     201{
     202        struct cfe_iocb iocb;
     203        int err;
     204
     205        memset(&iocb, 0, sizeof(iocb));
     206        iocb.fcode = CFE_CMD_ENV_ENUM;
     207        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     208        iocb.envbuf.index = idx;
     209        iocb.envbuf.name = PTR_TO_CFE(name);
     210        iocb.envbuf.name_len = namelen;
     211        iocb.envbuf.val = PTR_TO_CFE(val);
     212        iocb.envbuf.val_len = vallen;
     213
     214        err = cfe_iocb_dispatch(&iocb);
     215
     216        return (CFE_ISERR(err)) ? err : iocb.status;
     217}
     218
     219int cfe_enumdev(int idx, char *name, int namelen)
     220{
     221        struct cfe_iocb iocb;
     222        int err;
     223
     224        memset(&iocb, 0, sizeof(iocb));
     225
     226        iocb.fcode = CFE_CMD_DEV_ENUM;
     227        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     228        iocb.envbuf.index = idx;
     229        iocb.envbuf.name = PTR_TO_CFE(name);
     230        iocb.envbuf.name_len = namelen;
     231
     232        err = cfe_iocb_dispatch(&iocb);
     233
     234        return (CFE_ISERR(err)) ? err : iocb.status;
     235}
     236
     237int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
     238                u64 *type)
     239{
     240        struct cfe_iocb iocb;
     241        int err;
     242
     243        memset(&iocb, 0, sizeof(iocb));
     244
     245        iocb.fcode = CFE_CMD_FW_MEMENUM;
     246        iocb.flags = flags;
     247        iocb.psize = sizeof(struct cfe_iocb_meminfo);
     248        iocb.meminfo.index = idx;
     249
     250        err = cfe_iocb_dispatch(&iocb);
     251        if (CFE_ISERR(err))
     252                return err;
     253        if (!CFE_ISERR(iocb.status)) {
     254                *start = iocb.meminfo.addr;
     255                *length = iocb.meminfo.size;
     256                *type = iocb.meminfo.type;
     257        }
     258
     259        return iocb.status;
     260}
     261
     262int cfe_exit(int warm, int status)
     263{
     264        struct cfe_iocb iocb;
     265        int err;
     266
     267printk("CFE REBOOT\n");
     268        memset(&iocb, 0, sizeof(iocb));
     269        iocb.fcode = CFE_CMD_FW_RESTART;
     270        if (warm)
     271                iocb.flags = CFE_FLG_WARMSTART;
     272        iocb.psize = sizeof(struct cfe_iocb_exitstat);
     273        iocb.exitstat.status = status;
     274
     275printk("CALL\n");
     276        err = cfe_iocb_dispatch(&iocb);
     277printk("DONE\n");
     278
     279        return (CFE_ISERR(err)) ? err : iocb.status;
     280}
     281
     282int cfe_flushcache(int flags)
     283{
     284        struct cfe_iocb iocb;
     285        int err;
     286
     287        memset(&iocb, 0, sizeof(iocb));
     288        iocb.fcode = CFE_CMD_FW_FLUSHCACHE;
     289        iocb.flags = flags;
     290
     291        err = cfe_iocb_dispatch(&iocb);
     292
     293        return (CFE_ISERR(err)) ? err : iocb.status;
     294}
     295
     296int cfe_getdevinfo(char *name)
     297{
     298        struct cfe_iocb iocb;
     299        int err;
     300
     301        memset(&iocb, 0, sizeof(iocb));
     302        iocb.fcode = CFE_CMD_DEV_GETINFO;
     303        iocb.psize = sizeof(struct cfe_iocb_buf);
     304        iocb.buffer.ptr = PTR_TO_CFE(name);
     305        iocb.buffer.length = strlen(name);
     306
     307        err = cfe_iocb_dispatch(&iocb);
     308        if (CFE_ISERR(err))
     309                return err;
     310        if (CFE_ISERR(iocb.status))
     311                return iocb.status;
     312
     313        return iocb.buffer.devflags;
     314}
     315
     316int cfe_getenv(char *name, char *dest, int destlen)
     317{
     318        struct cfe_iocb iocb;
     319        int err;
     320
     321        dest[0] = '\0';
     322        memset(&iocb, 0, sizeof(iocb));
     323        iocb.fcode = CFE_CMD_ENV_GET;
     324        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     325        iocb.envbuf.name = PTR_TO_CFE(name);
     326        iocb.envbuf.name_len = strlen(name);
     327        iocb.envbuf.val = PTR_TO_CFE(dest);
     328        iocb.envbuf.val_len = destlen;
     329
     330        err = cfe_iocb_dispatch(&iocb);
     331
     332        return (CFE_ISERR(err)) ? err : iocb.status;
     333}
     334
     335int cfe_getfwinfo(struct cfe_fwinfo *info)
     336{
     337        struct cfe_iocb iocb;
     338        int err;
     339
     340        memset(&iocb, 0, sizeof(iocb));
     341        iocb.fcode = CFE_CMD_FW_GETINFO;
     342        iocb.psize = sizeof(struct cfe_iocb_fwinfo);
     343
     344        err = cfe_iocb_dispatch(&iocb);
     345        if (CFE_ISERR(err))
     346                return err;
     347        if (CFE_ISERR(iocb.status))
     348                return err;
     349
     350        info->version = iocb.fwinfo.version;
     351        info->totalmem = iocb.fwinfo.totalmem;
     352        info->flags = iocb.fwinfo.flags;
     353        info->boardid = iocb.fwinfo.boardid;
     354        info->bootarea_va = iocb.fwinfo.bootarea_va;
     355        info->bootarea_pa = iocb.fwinfo.bootarea_pa;
     356        info->bootarea_size = iocb.fwinfo.bootarea_size;
     357
     358        return iocb.status;
     359}
     360
     361int cfe_getstdhandle(int handletype)
     362{
     363        struct cfe_iocb iocb;
     364        int err;
     365
     366        memset(&iocb, 0, sizeof(iocb));
     367        iocb.fcode = CFE_CMD_DEV_GETHANDLE;
     368        iocb.flags = handletype;
     369
     370        err = cfe_iocb_dispatch(&iocb);
     371        if (CFE_ISERR(err))
     372                return err;
     373        if (CFE_ISERR(iocb.status))
     374                return iocb.status;
     375
     376        return iocb.handle;
     377}
     378
     379int cfe_getticks(s64 *ticks)
     380{
     381        struct cfe_iocb iocb;
     382        int err;
     383
     384        memset(&iocb, 0, sizeof(iocb));
     385        iocb.fcode = CFE_CMD_FW_GETTIME;
     386        iocb.psize = sizeof(struct cfe_iocb_time);
     387
     388        err = cfe_iocb_dispatch(&iocb);
     389        if (CFE_ISERR(err))
     390                return err;
     391        if (!CFE_ISERR(iocb.status))
     392                *ticks = iocb.time.ticks;
     393
     394        return iocb.status;
     395}
     396
     397int cfe_inpstat(int handle)
     398{
     399        struct cfe_iocb iocb;
     400        int err;
     401
     402        memset(&iocb, 0, sizeof(iocb));
     403        iocb.fcode = CFE_CMD_DEV_INPSTAT;
     404        iocb.handle = handle;
     405        iocb.psize = sizeof(struct cfe_iocb_inpstat);
     406
     407        err = cfe_iocb_dispatch(&iocb);
     408        if (CFE_ISERR(err))
     409                return err;
     410        if (CFE_ISERR(iocb.status))
     411                return iocb.status;
     412
     413        return iocb.inpstat.status;
     414}
     415
     416int cfe_ioctl(int handle, unsigned int ioctlnum,
     417              unsigned char *buffer, int length,
     418              int *retlen, u64 offset)
     419{
     420        struct cfe_iocb iocb;
     421        int err;
     422
     423        memset(&iocb, 0, sizeof(iocb));
     424        iocb.fcode = CFE_CMD_DEV_IOCTL;
     425        iocb.handle = handle;
     426        iocb.psize = sizeof(struct cfe_iocb_buf);
     427        iocb.buffer.offset = offset;
     428        iocb.buffer.ioctlcmd = ioctlnum;
     429        iocb.buffer.ptr = PTR_TO_CFE(buffer);
     430        iocb.buffer.length = length;
     431
     432        err = cfe_iocb_dispatch(&iocb);
     433        if (CFE_ISERR(err))
     434                return err;
     435        if (CFE_ISERR(iocb.status))
     436                return iocb.status;
     437        if (retlen)
     438                *retlen = iocb.buffer.retlen;
     439
     440        return iocb.status;
     441}
     442
     443int cfe_open(char *name)
     444{
     445        struct cfe_iocb iocb;
     446        int err;
     447
     448        memset(&iocb, 0, sizeof(iocb));
     449        iocb.fcode = CFE_CMD_DEV_OPEN;
     450        iocb.psize = sizeof(struct cfe_iocb_buf);
     451        iocb.buffer.ptr = PTR_TO_CFE(name);
     452        iocb.buffer.length = strlen(name);
     453
     454        err = cfe_iocb_dispatch(&iocb);
     455        if (CFE_ISERR(err))
     456                return err;
     457        if (CFE_ISERR(iocb.status))
     458                return iocb.status;
     459
     460        return iocb.handle;
     461}
     462
     463int cfe_read(int handle, unsigned char *buffer, int length)
     464{
     465        return cfe_readblk(handle, 0, buffer, length);
     466}
     467
     468int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
     469{
     470        struct cfe_iocb iocb;
     471        int err;
     472
     473        memset(&iocb, 0, sizeof(iocb));
     474        iocb.fcode = CFE_CMD_DEV_READ;
     475        iocb.handle = handle;
     476        iocb.psize = sizeof(struct cfe_iocb_buf);
     477        iocb.buffer.offset = offset;
     478        iocb.buffer.ptr = PTR_TO_CFE(buffer);
     479        iocb.buffer.length = length;
     480
     481        err = cfe_iocb_dispatch(&iocb);
     482        if (CFE_ISERR(err))
     483                return err;
     484        if (CFE_ISERR(iocb.status))
     485                return iocb.status;
     486
     487        return iocb.buffer.retlen;
     488}
     489
     490int cfe_setenv(char *name, char *val)
     491{
     492        struct cfe_iocb iocb;
     493        int err;
     494
     495        memset(&iocb, 0, sizeof(iocb));
     496        iocb.fcode = CFE_CMD_ENV_SET;
     497        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     498        iocb.envbuf.name = PTR_TO_CFE(name);
     499        iocb.envbuf.name_len = strlen(name);
     500        iocb.envbuf.val = PTR_TO_CFE(val);
     501        iocb.envbuf.val_len = strlen(val);
     502
     503        err = cfe_iocb_dispatch(&iocb);
     504
     505        return (CFE_ISERR(err)) ? err : iocb.status;
     506}
     507
     508int cfe_write(int handle, unsigned char *buffer, int length)
     509{
     510        return cfe_writeblk(handle, 0, buffer, length);
     511}
     512
     513int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
     514{
     515        struct cfe_iocb iocb;
     516        int err;
     517
     518        memset(&iocb, 0, sizeof(iocb));
     519        iocb.fcode = CFE_CMD_DEV_WRITE;
     520        iocb.handle = handle;
     521        iocb.psize = sizeof(struct cfe_iocb_buf);
     522        iocb.buffer.offset = offset;
     523        iocb.buffer.ptr = PTR_TO_CFE(buffer);
     524        iocb.buffer.length = length;
     525
     526        err = cfe_iocb_dispatch(&iocb);
     527        if (CFE_ISERR(err))
     528                return err;
     529        if (CFE_ISERR(iocb.status))
     530                return iocb.status;
     531
     532        return iocb.buffer.retlen;
     533}
  • arch/mips/cfe/cfe_private.h

    diff -Nru linux-2.6.19.ori/arch/mips/cfe/cfe_private.h linux-2.6.19/arch/mips/cfe/cfe_private.h
    old new  
     1/*
     2 * Broadcom Common Firmware Environment (CFE) support
     3 *
     4 * Copyright 2000, 2001, 2002
     5 * Broadcom Corporation. All rights reserved.
     6 *
     7 * Copyright (C) 2006 Michael Buesch
     8 *
     9 * Original Authors:  Mitch Lichtenberg, Chris Demetriou
     10 *
     11 * This software is furnished under license and may be used and copied only
     12 * in accordance with the following terms and conditions.  Subject to these
     13 * conditions, you may download, copy, install, use, modify and distribute
     14 * modified or unmodified copies of this software in source and/or binary
     15 * form. No title or ownership is transferred hereby.
     16 *
     17 * 1) Any source code used, modified or distributed must reproduce and
     18 *    retain this copyright notice and list of conditions as they appear in
     19 *    the source file.
     20 *
     21 * 2) No right is granted to use any trade name, trademark, or logo of
     22 *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
     23 *    used to endorse or promote products derived from this software
     24 *    without the prior written permission of Broadcom Corporation.
     25 *
     26 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
     27 *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
     28 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
     29 *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
     30 *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
     31 *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     34 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     35 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     36 *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37 */
     38
     39#ifndef LINUX_CFE_PRIVATE_H_
     40#define LINUX_CFE_PRIVATE_H_
     41
     42#ifndef __ASSEMBLY__
     43
     44/* Seal indicating CFE's presence, passed to the kernel. */
     45#define CFE_EPTSEAL             0x43464531
     46
     47#define CFE_CMD_FW_GETINFO      0
     48#define CFE_CMD_FW_RESTART      1
     49#define CFE_CMD_FW_BOOT         2
     50#define CFE_CMD_FW_CPUCTL       3
     51#define CFE_CMD_FW_GETTIME      4
     52#define CFE_CMD_FW_MEMENUM      5
     53#define CFE_CMD_FW_FLUSHCACHE   6
     54
     55#define CFE_CMD_DEV_GETHANDLE   9
     56#define CFE_CMD_DEV_ENUM        10
     57#define CFE_CMD_DEV_OPEN        11
     58#define CFE_CMD_DEV_INPSTAT     12
     59#define CFE_CMD_DEV_READ        13
     60#define CFE_CMD_DEV_WRITE       14
     61#define CFE_CMD_DEV_IOCTL       15
     62#define CFE_CMD_DEV_CLOSE       16
     63#define CFE_CMD_DEV_GETINFO     17
     64
     65#define CFE_CMD_ENV_ENUM        20
     66#define CFE_CMD_ENV_GET         22
     67#define CFE_CMD_ENV_SET         23
     68#define CFE_CMD_ENV_DEL         24
     69
     70#define CFE_CMD_MAX             32
     71
     72#define CFE_CMD_VENDOR_USE      0x8000  /* codes above this are for customer use */
     73
     74typedef u64 cfe_uint_t;
     75typedef s64 cfe_int_t;
     76typedef s64 cfe_ptr_t;
     77
     78/* Cast a pointer from native to CFE-API pointer and back */
     79#define CFE_TO_PTR(p)           ((void *)(unsigned long)(p))
     80#define PTR_TO_CFE(p)           ((cfe_ptr_t)(unsigned long)(p))
     81
     82struct cfe_iocb_buf {
     83        cfe_uint_t      offset;         /* offset on device (bytes) */
     84        cfe_ptr_t       ptr;            /* pointer to a buffer */
     85        cfe_uint_t      length;         /* length of this buffer */
     86        cfe_uint_t      retlen;         /* returned length (for read ops) */
     87        union {
     88                cfe_uint_t      ioctlcmd;       /* IOCTL command (used only for IOCTLs) */
     89                cfe_uint_t      devflags;       /* Returned device info flags */
     90        };
     91};
     92
     93struct cfe_iocb_inpstat {
     94        cfe_uint_t      status;         /* 1 means input available */
     95};
     96
     97struct cfe_iocb_envbuf {
     98        cfe_int_t       index;          /* 0-based enumeration index */
     99        cfe_ptr_t       name;           /* name string buffer */
     100        cfe_int_t       name_len;       /* size of name buffer */
     101        cfe_ptr_t       val;            /* value string buffer */
     102        cfe_int_t       val_len;        /* size of value string buffer */
     103};
     104
     105struct cfe_iocb_cpuctl {
     106        cfe_uint_t      number;         /* cpu number to control */
     107        cfe_uint_t      command;        /* command to issue to CPU */
     108        cfe_uint_t      start_addr;     /* CPU start address */
     109        cfe_uint_t      gp;             /* starting GP value */
     110        cfe_uint_t      sp;             /* starting SP value */
     111        cfe_uint_t      a1;             /* starting A1 value */
     112};
     113
     114struct cfe_iocb_time {
     115        cfe_int_t       ticks;          /* current time in ticks */
     116};
     117
     118struct cfe_iocb_exitstat {
     119        cfe_int_t       status;
     120};
     121
     122struct cfe_iocb_meminfo {
     123        cfe_int_t       index;          /* 0-based enumeration index */
     124        cfe_int_t       type;           /* type of memory block */
     125        cfe_uint_t      addr;           /* physical start address */
     126        cfe_uint_t      size;           /* block size */
     127};
     128
     129struct cfe_iocb_fwinfo {
     130        cfe_int_t       version;        /* major, minor, eco version */
     131        cfe_int_t       totalmem;       /* total installed mem */
     132        cfe_int_t       flags;          /* various flags */
     133        cfe_int_t       boardid;        /* board ID */
     134        cfe_int_t       bootarea_va;    /* VA of boot area */
     135        cfe_int_t       bootarea_pa;    /* PA of boot area */
     136        cfe_int_t       bootarea_size;  /* size of boot area */
     137        cfe_int_t       reserved1;
     138        cfe_int_t       reserved2;
     139        cfe_int_t       reserved3;
     140};
     141
     142/* CFE I/O Control Block */
     143struct cfe_iocb {
     144        cfe_uint_t      fcode;          /* IOCB function code */
     145        cfe_int_t       status;         /* return status */
     146        cfe_int_t       handle;         /* file/device handle */
     147        cfe_uint_t      flags;          /* flags for this IOCB */
     148        cfe_uint_t      psize;          /* size of parameter list */
     149        union {
     150                struct cfe_iocb_buf             buffer;         /* buffer parameters */
     151                struct cfe_iocb_inpstat         inpstat;        /* input status parameters */
     152                struct cfe_iocb_envbuf          envbuf;         /* environment function parameters */
     153                struct cfe_iocb_cpuctl          cpuctl;         /* CPU control parameters */
     154                struct cfe_iocb_time            time;           /* timer parameters */
     155                struct cfe_iocb_meminfo         meminfo;        /* memory arena info parameters */
     156                struct cfe_iocb_fwinfo          fwinfo;         /* firmware information */
     157                struct cfe_iocb_exitstat        exitstat;       /* Exit Status */
     158        };
     159};
     160
     161
     162#include <linux/init.h>
     163
     164void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
     165                      unsigned long fwarg2, unsigned long fwarg3);
     166
     167#else /* __ASSEMBLY__ */
     168
     169        .macro  cfe_early_init
     170#ifdef CONFIG_CFE
     171                jal     cfe_setup
     172#endif
     173        .endm
     174
     175#endif /* __ASSEMBLY__ */
     176#endif /* LINUX_CFE_PRIVATE_H_ */
  • arch/mips/kernel/cpu-probe.c

    diff -Nru linux-2.6.19.ori/arch/mips/kernel/cpu-probe.c linux-2.6.19/arch/mips/kernel/cpu-probe.c
    old new  
    723723}
    724724
    725725
     726static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
     727{
     728        decode_config1(c);
     729        switch (c->processor_id & 0xff00) {
     730                case PRID_IMP_BCM3302:
     731                        c->cputype = CPU_BCM3302;
     732                        c->isa_level = MIPS_CPU_ISA_M32R1;
     733                        c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
     734                                        MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
     735                break;
     736                case PRID_IMP_BCM4710:
     737                        c->cputype = CPU_BCM4710;
     738                        c->isa_level = MIPS_CPU_ISA_M32R1;
     739                        c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
     740                                        MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
     741                break;
     742        default:
     743                c->cputype = CPU_UNKNOWN;
     744                break;
     745        }
     746}
     747
    726748__init void cpu_probe(void)
    727749{
    728750        struct cpuinfo_mips *c = &current_cpu_data;
     
    745767        case PRID_COMP_SIBYTE:
    746768                cpu_probe_sibyte(c);
    747769                break;
     770        case PRID_COMP_BROADCOM:
     771                cpu_probe_broadcom(c);
     772                break;
    748773        case PRID_COMP_SANDCRAFT:
    749774                cpu_probe_sandcraft(c);
    750775                break;
  • arch/mips/kernel/head.S

    diff -Nru linux-2.6.19.ori/arch/mips/kernel/head.S linux-2.6.19/arch/mips/kernel/head.S
    old new  
    129129#endif
    130130        .endm
    131131
     132        j kernel_entry
     133        nop
     134
    132135        /*
    133136         * Reserved space for exception handlers.
    134137         * Necessary for machines which link their kernels at KSEG0.
  • arch/mips/kernel/proc.c

    diff -Nru linux-2.6.19.ori/arch/mips/kernel/proc.c linux-2.6.19/arch/mips/kernel/proc.c
    old new  
    8383        [CPU_VR4181]    = "NEC VR4181",
    8484        [CPU_VR4181A]   = "NEC VR4181A",
    8585        [CPU_SR71000]   = "Sandcraft SR71000",
     86        [CPU_BCM3302]   = "Broadcom BCM3302",
     87        [CPU_BCM4710]   = "Broadcom BCM4710",
    8688        [CPU_PR4450]    = "Philips PR4450",
    8789};
    8890
  • arch/mips/mm/tlbex.c

    diff -Nru linux-2.6.19.ori/arch/mips/mm/tlbex.c linux-2.6.19/arch/mips/mm/tlbex.c
    old new  
    880880        case CPU_4KSC:
    881881        case CPU_20KC:
    882882        case CPU_25KF:
     883        case CPU_BCM3302:
     884        case CPU_BCM4710:
    883885                tlbw(p);
    884886                break;
    885887
  • drivers/Kconfig

    diff -Nru linux-2.6.19.ori/drivers/Kconfig linux-2.6.19/drivers/Kconfig
    old new  
    5656
    5757source "drivers/hwmon/Kconfig"
    5858
     59source "drivers/ssb/Kconfig"
     60
    5961source "drivers/mfd/Kconfig"
    6062
    6163source "drivers/media/Kconfig"
  • drivers/Makefile

    diff -Nru linux-2.6.19.ori/drivers/Makefile linux-2.6.19/drivers/Makefile
    old new  
    7777obj-$(CONFIG_SUPERH)            += sh/
    7878obj-$(CONFIG_GENERIC_TIME)      += clocksource/
    7979obj-$(CONFIG_DMA_ENGINE)        += dma/
     80obj-$(CONFIG_SSB)               += ssb/
  • drivers/mtd/chips/cfi_cmdset_0002.c

    diff -Nru linux-2.6.19.ori/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.6.19/drivers/mtd/chips/cfi_cmdset_0002.c
    old new  
    296296                        printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
    297297                               "version %c.%c.\n",  extp->MajorVersion,
    298298                               extp->MinorVersion);
    299                         kfree(extp);
    300                         kfree(mtd);
    301                         return NULL;
    302299                }
    303300
    304301                /* Install our own private info structure */
  • drivers/mtd/maps/Kconfig

    diff -Nru linux-2.6.19.ori/drivers/mtd/maps/Kconfig linux-2.6.19/drivers/mtd/maps/Kconfig
    old new  
    299299          Mapping for the Flaga digital module. If you don't have one, ignore
    300300          this setting.
    301301
     302config MTD_BCM47XX
     303        tristate "BCM47xx flash device"
     304        depends on MIPS && MTD_CFI && BCM947XX
     305        help
     306          Support for the flash chips on the BCM947xx board.
     307         
    302308config MTD_BEECH
    303309        tristate "CFI Flash device mapped on IBM 405LP Beech"
    304310        depends on MTD_CFI && BEECH
  • drivers/mtd/maps/Makefile

    diff -Nru linux-2.6.19.ori/drivers/mtd/maps/Makefile linux-2.6.19/drivers/mtd/maps/Makefile
    old new  
    2929obj-$(CONFIG_MTD_PCMCIA)        += pcmciamtd.o
    3030obj-$(CONFIG_MTD_RPXLITE)       += rpxlite.o
    3131obj-$(CONFIG_MTD_TQM8XXL)       += tqm8xxl.o
     32obj-$(CONFIG_MTD_BCM47XX)       += bcm47xx-flash.o
    3233obj-$(CONFIG_MTD_SA1100)        += sa1100-flash.o
    3334obj-$(CONFIG_MTD_IPAQ)          += ipaq-flash.o
    3435obj-$(CONFIG_MTD_SBC_GXX)       += sbc_gxx.o
  • drivers/mtd/maps/bcm47xx-flash.c

    diff -Nru linux-2.6.19.ori/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.19/drivers/mtd/maps/bcm47xx-flash.c
    old new  
     1/*
     2 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
     3 *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
     4 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     5 *
     6 *  original functions for finding root filesystem from Mike Baker
     7 *
     8 *  This program is free software; you can redistribute  it and/or modify it
     9 *  under  the terms of  the GNU General  Public License as published by the
     10 *  Free Software Foundation;  either version 2 of the  License, or (at your
     11 *  option) any later version.
     12 *
     13 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     14 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     15 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     16 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     17 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     18 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     19 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     21 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     22 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23 *
     24 *  You should have received a copy of the  GNU General Public License along
     25 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     26 *  675 Mass Ave, Cambridge, MA 02139, USA.
     27 *
     28 *  Copyright 2001-2003, Broadcom Corporation
     29 *  All Rights Reserved.
     30 *
     31 *  THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
     32 *  KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
     33 *  SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
     34 *  FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
     35 *
     36 *  Flash mapping for BCM947XX boards
     37 */
     38
     39#include <linux/init.h>
     40#include <linux/module.h>
     41#include <linux/types.h>
     42#include <linux/kernel.h>
     43#include <linux/wait.h>
     44#include <linux/mtd/mtd.h>
     45#include <linux/mtd/map.h>
     46#ifdef CONFIG_MTD_PARTITIONS
     47#include <linux/mtd/partitions.h>
     48#endif
     49#include <linux/squashfs_fs.h>
     50#include <linux/jffs2.h>
     51#include <linux/crc32.h>
     52#include <linux/ssb.h>
     53#include <asm/io.h>
     54
     55
     56#define TRX_MAGIC       0x30524448      /* "HDR0" */
     57#define TRX_VERSION     1
     58#define TRX_MAX_LEN     0x3A0000
     59#define TRX_NO_HEADER   1               /* Do not write TRX header */   
     60#define TRX_GZ_FILES    0x2     /* Contains up to TRX_MAX_OFFSET individual gzip files */
     61#define TRX_MAX_OFFSET  3
     62
     63struct trx_header {
     64        u32 magic;              /* "HDR0" */
     65        u32 len;                /* Length of file including header */
     66        u32 crc32;              /* 32-bit CRC from flag_version to end of file */
     67        u32 flag_version;       /* 0:15 flags, 16:31 version */
     68        u32 offsets[TRX_MAX_OFFSET];    /* Offsets of partitions from start of header */
     69};
     70
     71#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
     72#define NVRAM_SPACE 0x8000
     73#define WINDOW_ADDR 0x1fc00000
     74#define WINDOW_SIZE 0x400000
     75#define BUSWIDTH 2
     76
     77extern struct ssb_bus ssb;
     78static struct mtd_info *bcm947xx_mtd;
     79
     80static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
     81{
     82#define MIPS_MEMCPY_ALIGN 4
     83        map_word ret;
     84        ssize_t transfer;
     85        ssize_t done = 0;
     86        if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) {
     87                done = len & ~(MIPS_MEMCPY_ALIGN - 1);
     88                memcpy_fromio(to, map->virt + from, done);
     89        }
     90        while (done < len) {
     91                ret = map->read(map, from + done);
     92                transfer = len - done;
     93                if (transfer > map->bankwidth)
     94                        transfer = map->bankwidth;
     95                memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer);
     96                done += transfer;
     97        }
     98}
     99
     100static struct map_info bcm947xx_map = {
     101        name: "Physically mapped flash",
     102        size: WINDOW_SIZE,
     103        bankwidth: BUSWIDTH,
     104        phys: WINDOW_ADDR,
     105};
     106
     107#ifdef CONFIG_MTD_PARTITIONS
     108
     109static struct mtd_partition bcm947xx_parts[] = {
     110        { name: "cfe",  offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
     111        { name: "linux", offset: 0, size: 0, },
     112        { name: "rootfs", offset: 0, size: 0, },
     113        { name: "nvram", offset: 0, size: 0, },
     114        { name: "OpenWrt", offset: 0, size: 0, },
     115        { name: NULL, },
     116};
     117
     118static int __init
     119find_cfe_size(struct mtd_info *mtd, size_t size)
     120{
     121        struct trx_header *trx;
     122        unsigned char buf[512];
     123        int off;
     124        size_t len;
     125        int blocksize;
     126
     127        trx = (struct trx_header *) buf;
     128
     129        blocksize = mtd->erasesize;
     130        if (blocksize < 0x10000)
     131                blocksize = 0x10000;
     132
     133        for (off = (128*1024); off < size; off += blocksize) {
     134                memset(buf, 0xe5, sizeof(buf));
     135
     136                /*
     137                 * Read into buffer
     138                 */
     139                if (mtd->read(mtd, off, sizeof(buf), &len, buf) ||
     140                    len != sizeof(buf))
     141                        continue;
     142
     143                /* found a TRX header */
     144                if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
     145                        goto found;
     146                }
     147        }
     148
     149        printk(KERN_NOTICE
     150               "%s: Couldn't find bootloader size\n",
     151               mtd->name);
     152        return -1;
     153
     154 found:
     155        printk(KERN_NOTICE "bootloader size: %d\n", off);
     156        return off;
     157
     158}
     159
     160/*
     161 * Copied from mtdblock.c
     162 *
     163 * Cache stuff...
     164 *
     165 * Since typical flash erasable sectors are much larger than what Linux's
     166 * buffer cache can handle, we must implement read-modify-write on flash
     167 * sectors for each block write requests.  To avoid over-erasing flash sectors
     168 * and to speed things up, we locally cache a whole flash sector while it is
     169 * being written to until a different sector is required.
     170 */
     171
     172static void erase_callback(struct erase_info *done)
     173{
     174        wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
     175        wake_up(wait_q);
     176}
     177
     178static int erase_write (struct mtd_info *mtd, unsigned long pos,
     179                        int len, const char *buf)
     180{
     181        struct erase_info erase;
     182        DECLARE_WAITQUEUE(wait, current);
     183        wait_queue_head_t wait_q;
     184        size_t retlen;
     185        int ret;
     186
     187        /*
     188         * First, let's erase the flash block.
     189         */
     190
     191        init_waitqueue_head(&wait_q);
     192        erase.mtd = mtd;
     193        erase.callback = erase_callback;
     194        erase.addr = pos;
     195        erase.len = len;
     196        erase.priv = (u_long)&wait_q;
     197
     198        set_current_state(TASK_INTERRUPTIBLE);
     199        add_wait_queue(&wait_q, &wait);
     200
     201        ret = mtd->erase(mtd, &erase);
     202        if (ret) {
     203                set_current_state(TASK_RUNNING);
     204                remove_wait_queue(&wait_q, &wait);
     205                printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
     206                                     "on \"%s\" failed\n",
     207                        pos, len, mtd->name);
     208                return ret;
     209        }
     210
     211        schedule();  /* Wait for erase to finish. */
     212        remove_wait_queue(&wait_q, &wait);
     213
     214        /*
     215         * Next, writhe data to flash.
     216         */
     217
     218        ret = mtd->write (mtd, pos, len, &retlen, buf);
     219        if (ret)
     220                return ret;
     221        if (retlen != len)
     222                return -EIO;
     223        return 0;
     224}
     225
     226
     227
     228
     229static int __init
     230find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
     231{
     232        struct trx_header trx, *trx2;
     233        unsigned char buf[512], *block;
     234        int off, blocksize;
     235        u32 i, crc = ~0;
     236        size_t len;
     237        struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
     238
     239        blocksize = mtd->erasesize;
     240        if (blocksize < 0x10000)
     241                blocksize = 0x10000;
     242
     243        for (off = (128*1024); off < size; off += blocksize) {
     244                memset(&trx, 0xe5, sizeof(trx));
     245
     246                /*
     247                 * Read into buffer
     248                 */
     249                if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
     250                    len != sizeof(trx))
     251                        continue;
     252
     253                /* found a TRX header */
     254                if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
     255                        part->offset = le32_to_cpu(trx.offsets[2]) ? :
     256                                le32_to_cpu(trx.offsets[1]);
     257                        part->size = le32_to_cpu(trx.len);
     258
     259                        part->size -= part->offset;
     260                        part->offset += off;
     261
     262                        goto found;
     263                }
     264        }
     265
     266        printk(KERN_NOTICE
     267               "%s: Couldn't find root filesystem\n",
     268               mtd->name);
     269        return -1;
     270
     271 found:
     272        if (part->size == 0)
     273                return 0;
     274       
     275        if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
     276                return 0;
     277
     278        if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
     279                printk(KERN_INFO "%s: Filesystem type: squashfs, size=0x%x\n", mtd->name, (u32) sb->bytes_used);
     280
     281                /* Update the squashfs partition size based on the superblock info */
     282                part->size = sb->bytes_used;
     283                len = part->offset + part->size;
     284                len +=  (mtd->erasesize - 1);
     285                len &= ~(mtd->erasesize - 1);
     286                part->size = len - part->offset;
     287        } else if (*((__u16 *) buf) == JFFS2_MAGIC_BITMASK) {
     288                printk(KERN_INFO "%s: Filesystem type: jffs2\n", mtd->name);
     289
     290                /* Move the squashfs outside of the trx */
     291                part->size = 0;
     292        } else {
     293                printk(KERN_INFO "%s: Filesystem type: unknown\n", mtd->name);
     294                return 0;
     295        }
     296
     297        if (trx.len != part->offset + part->size - off) {
     298                /* Update the trx offsets and length */
     299                trx.len = part->offset + part->size - off;
     300       
     301                /* Update the trx crc32 */
     302                for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
     303                        if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
     304                                return 0;
     305                        crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
     306                }
     307                trx.crc32 = crc;
     308
     309                /* read first eraseblock from the trx */
     310                block = kmalloc(mtd->erasesize, GFP_KERNEL);
     311                trx2 = (struct trx_header *) block;
     312                if (mtd->read(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
     313                        printk("Error accessing the first trx eraseblock\n");
     314                        return 0;
     315                }
     316               
     317                printk("Updating TRX offsets and length:\n");
     318                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);
     319                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);
     320
     321                /* Write updated trx header to the flash */
     322                memcpy(block, &trx, sizeof(trx));
     323                if (mtd->unlock)
     324                        mtd->unlock(mtd, off, mtd->erasesize);
     325                erase_write(mtd, off, mtd->erasesize, block);
     326                if (mtd->sync)
     327                        mtd->sync(mtd);
     328                kfree(block);
     329                printk("Done\n");
     330        }
     331       
     332        return part->size;
     333}
     334
     335struct mtd_partition * __init
     336init_mtd_partitions(struct mtd_info *mtd, size_t size)
     337{
     338        int cfe_size;
     339
     340        if ((cfe_size = find_cfe_size(mtd,size)) < 0)
     341                return NULL;
     342
     343        /* boot loader */
     344        bcm947xx_parts[0].offset = 0;
     345        bcm947xx_parts[0].size   = cfe_size;
     346
     347        /* nvram */
     348        if (cfe_size != 384 * 1024) {
     349                bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
     350                bcm947xx_parts[3].size   = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
     351        } else {
     352                /* nvram (old 128kb config partition on netgear wgt634u) */
     353                bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
     354                bcm947xx_parts[3].size   = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
     355        }
     356
     357        /* linux (kernel and rootfs) */
     358        if (cfe_size != 384 * 1024) {
     359                bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
     360                bcm947xx_parts[1].size   = bcm947xx_parts[3].offset -
     361                        bcm947xx_parts[1].offset;
     362        } else {
     363                /* do not count the elf loader, which is on one block */
     364                bcm947xx_parts[1].offset = bcm947xx_parts[0].size +
     365                        bcm947xx_parts[3].size + mtd->erasesize;
     366                bcm947xx_parts[1].size   = size -
     367                        bcm947xx_parts[0].size -
     368                        (2*bcm947xx_parts[3].size) -
     369                        mtd->erasesize;
     370        }
     371
     372        /* find and size rootfs */
     373        if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
     374                /* entirely jffs2 */
     375                bcm947xx_parts[4].name = NULL;
     376                bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset -
     377                                bcm947xx_parts[3].size;
     378        } else {
     379                /* legacy setup */
     380                /* calculate leftover flash, and assign it to the jffs2 partition */
     381                if (cfe_size != 384 * 1024) {
     382                        bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
     383                                bcm947xx_parts[2].size;
     384                        if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
     385                                bcm947xx_parts[4].offset += mtd->erasesize -
     386                                        (bcm947xx_parts[4].offset % mtd->erasesize);
     387                        }
     388                        bcm947xx_parts[4].size = bcm947xx_parts[3].offset -
     389                                bcm947xx_parts[4].offset;
     390                } else {
     391                        bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
     392                                bcm947xx_parts[2].size;
     393                        if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
     394                                bcm947xx_parts[4].offset += mtd->erasesize -
     395                                        (bcm947xx_parts[4].offset % mtd->erasesize);
     396                        }
     397                        bcm947xx_parts[4].size = size - bcm947xx_parts[3].size -
     398                                bcm947xx_parts[4].offset;
     399                }
     400        }
     401
     402        return bcm947xx_parts;
     403}
     404#endif
     405
     406int __init init_bcm947xx_map(void)
     407{
     408        struct ssb_mipscore *mcore = &ssb.mipscore;
     409        size_t size;
     410        int ret = 0;
     411#ifdef CONFIG_MTD_PARTITIONS
     412        struct mtd_partition *parts;
     413        int i;
     414#endif
     415        u32 window = mcore->flash_window;
     416        u32 window_size = mcore->flash_window_size;
     417
     418        printk("flash init: 0x%08x 0x%08x\n", window, window_size);
     419        bcm947xx_map.virt = ioremap(window, window_size);
     420
     421        if (!bcm947xx_map.virt) {
     422                printk("Failed to ioremap\n");
     423                return -EIO;
     424        }
     425        simple_map_init(&bcm947xx_map);
     426       
     427        bcm947xx_map.copy_from = bcm947xx_map_copy_from;
     428       
     429        if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
     430                printk("Failed to do_map_probe\n");
     431                iounmap((void *)bcm947xx_map.virt);
     432                return -ENXIO;
     433        }
     434
     435        bcm947xx_mtd->owner = THIS_MODULE;
     436
     437        size = bcm947xx_mtd->size;
     438
     439        printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR);
     440
     441#ifdef CONFIG_MTD_PARTITIONS
     442        parts = init_mtd_partitions(bcm947xx_mtd, size);
     443        for (i = 0; parts[i].name; i++);
     444        ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
     445        if (ret) {
     446                printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
     447                goto fail;
     448        }
     449#endif
     450        return 0;
     451
     452 fail:
     453        if (bcm947xx_mtd)
     454                map_destroy(bcm947xx_mtd);
     455        if (bcm947xx_map.virt)
     456                iounmap((void *)bcm947xx_map.virt);
     457        bcm947xx_map.virt = 0;
     458        return ret;
     459}
     460
     461void __exit cleanup_bcm947xx_map(void)
     462{
     463#ifdef CONFIG_MTD_PARTITIONS
     464        del_mtd_partitions(bcm947xx_mtd);
     465#endif
     466        map_destroy(bcm947xx_mtd);
     467        iounmap((void *)bcm947xx_map.virt);
     468}
     469
     470module_init(init_bcm947xx_map);
     471module_exit(cleanup_bcm947xx_map);
  • drivers/net/Kconfig

    diff -Nru linux-2.6.19.ori/drivers/net/Kconfig linux-2.6.19/drivers/net/Kconfig
    old new  
    13941394
    13951395config B44
    13961396        tristate "Broadcom 4400 ethernet support"
    1397         depends on NET_PCI && PCI
     1397        depends on SSB && EXPERIMENTAL
    13981398        select MII
    13991399        help
    14001400          If you have a network (Ethernet) controller of this type, say Y and
  • drivers/net/b44.c

    diff -Nru linux-2.6.19.ori/drivers/net/b44.c linux-2.6.19/drivers/net/b44.c
    old new  
    1 /* b44.c: Broadcom 4400 device driver.
     1/* b44.c: Broadcom 4400/47xx device driver.
    22 *
    33 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
    4  * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
     4 * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
     5 * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     6 * Copyright (C) 2006 Felix Fietkau (nbd@openwrt.org)
    57 * Copyright (C) 2006 Broadcom Corporation.
    68 *
    79 * Distribute under GPL.
     
    2022#include <linux/delay.h>
    2123#include <linux/init.h>
    2224#include <linux/dma-mapping.h>
     25#include <linux/ssb.h>
    2326
    2427#include <asm/uaccess.h>
    2528#include <asm/io.h>
    2629#include <asm/irq.h>
    2730
     31
    2832#include "b44.h"
    2933
    3034#define DRV_MODULE_NAME         "b44"
     
    8791static char version[] __devinitdata =
    8892        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
    8993
    90 MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
    91 MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
     94MODULE_AUTHOR("Felix Fietkau, Florian Schirmer, Pekka Pietikainen, David S. Miller");
     95MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
    9296MODULE_LICENSE("GPL");
    9397MODULE_VERSION(DRV_MODULE_VERSION);
    9498
     
    96100module_param(b44_debug, int, 0);
    97101MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
    98102
    99 static struct pci_device_id b44_pci_tbl[] = {
    100         { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
    101           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
    102         { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0,
    103           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
    104         { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
    105           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
    106         { }     /* terminate list with empty entry */
     103static struct ssb_device_id b44_ssb_tbl[] = {
     104        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET, SSB_ANY_REV),
     105        SSB_DEVTABLE_END
    107106};
    108107
    109 MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
    110 
    111108static void b44_halt(struct b44 *);
    112109static void b44_init_rings(struct b44 *);
    113110static void b44_init_hw(struct b44 *, int);
    114111
    115112static int dma_desc_align_mask;
    116113static int dma_desc_sync_size;
     114static int instance;
    117115
    118116static const char b44_gstrings[][ETH_GSTRING_LEN] = {
    119117#define _B44(x...)      # x,
     
    121119#undef _B44
    122120};
    123121
    124 static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
    125                                                 dma_addr_t dma_base,
    126                                                 unsigned long offset,
    127                                                 enum dma_data_direction dir)
    128 {
    129         dma_sync_single_range_for_device(&pdev->dev, dma_base,
    130                                          offset & dma_desc_align_mask,
    131                                          dma_desc_sync_size, dir);
    132 }
    133 
    134 static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
    135                                              dma_addr_t dma_base,
    136                                              unsigned long offset,
    137                                              enum dma_data_direction dir)
    138 {
    139         dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
    140                                       offset & dma_desc_align_mask,
    141                                       dma_desc_sync_size, dir);
    142 }
    143 
    144 static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
    145 {
    146         return readl(bp->regs + reg);
    147 }
    148 
    149 static inline void bw32(const struct b44 *bp,
    150                         unsigned long reg, unsigned long val)
    151 {
    152         writel(val, bp->regs + reg);
     122static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
     123                                               dma_addr_t dma_base,
     124                                               unsigned long offset,
     125                                               enum dma_data_direction dir)
     126{
     127        dma_sync_single_range_for_device(&sdev->dev, dma_base,
     128                                        offset & dma_desc_align_mask,
     129                                        dma_desc_sync_size, dir);
     130}
     131
     132static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
     133                                            dma_addr_t dma_base,
     134                                            unsigned long offset,
     135                                            enum dma_data_direction dir)
     136{
     137        dma_sync_single_range_for_cpu(&sdev->dev, dma_base,
     138                                     offset & dma_desc_align_mask,
     139                                     dma_desc_sync_size, dir);
    153140}
    154141
    155142static int b44_wait_bit(struct b44 *bp, unsigned long reg,
     
    177164        return 0;
    178165}
    179166
    180 /* Sonics SiliconBackplane support routines.  ROFL, you should see all the
    181  * buzz words used on this company's website :-)
    182  *
    183  * All of these routines must be invoked with bp->lock held and
    184  * interrupts disabled.
    185  */
    186 
    187 #define SB_PCI_DMA             0x40000000      /* Client Mode PCI memory access space (1 GB) */
    188 #define BCM4400_PCI_CORE_ADDR  0x18002000      /* Address of PCI core on BCM4400 cards */
    189 
    190 static u32 ssb_get_core_rev(struct b44 *bp)
    191 {
    192         return (br32(bp, B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
    193 }
    194 
    195 static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
    196 {
    197         u32 bar_orig, pci_rev, val;
    198 
    199         pci_read_config_dword(bp->pdev, SSB_BAR0_WIN, &bar_orig);
    200         pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
    201         pci_rev = ssb_get_core_rev(bp);
    202 
    203         val = br32(bp, B44_SBINTVEC);
    204         val |= cores;
    205         bw32(bp, B44_SBINTVEC, val);
    206 
    207         val = br32(bp, SSB_PCI_TRANS_2);
    208         val |= SSB_PCI_PREF | SSB_PCI_BURST;
    209         bw32(bp, SSB_PCI_TRANS_2, val);
    210 
    211         pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, bar_orig);
    212 
    213         return pci_rev;
    214 }
    215 
    216 static void ssb_core_disable(struct b44 *bp)
    217 {
    218         if (br32(bp, B44_SBTMSLOW) & SBTMSLOW_RESET)
    219                 return;
    220 
    221         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
    222         b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0);
    223         b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1);
    224         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
    225                             SBTMSLOW_REJECT | SBTMSLOW_RESET));
    226         br32(bp, B44_SBTMSLOW);
    227         udelay(1);
    228         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
    229         br32(bp, B44_SBTMSLOW);
    230         udelay(1);
    231 }
    232 
    233 static void ssb_core_reset(struct b44 *bp)
     167static inline void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
    234168{
    235169        u32 val;
    236170
    237         ssb_core_disable(bp);
    238         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
    239         br32(bp, B44_SBTMSLOW);
    240         udelay(1);
    241 
    242         /* Clear SERR if set, this is a hw bug workaround.  */
    243         if (br32(bp, B44_SBTMSHIGH) & SBTMSHIGH_SERR)
    244                 bw32(bp, B44_SBTMSHIGH, 0);
    245 
    246         val = br32(bp, B44_SBIMSTATE);
    247         if (val & (SBIMSTATE_IBE | SBIMSTATE_TO))
    248                 bw32(bp, B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
    249 
    250         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
    251         br32(bp, B44_SBTMSLOW);
    252         udelay(1);
    253 
    254         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK));
    255         br32(bp, B44_SBTMSLOW);
    256         udelay(1);
    257 }
     171        bw32(bp, B44_CAM_CTRL, (CAM_CTRL_READ |
     172                            (index << CAM_CTRL_INDEX_SHIFT)));
    258173
    259 static int ssb_core_unit(struct b44 *bp)
    260 {
    261 #if 0
    262         u32 val = br32(bp, B44_SBADMATCH0);
    263         u32 base;
     174        b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
    264175
    265         type = val & SBADMATCH0_TYPE_MASK;
    266         switch (type) {
    267         case 0:
    268                 base = val & SBADMATCH0_BS0_MASK;
    269                 break;
     176        val = br32(bp, B44_CAM_DATA_LO);
    270177
    271         case 1:
    272                 base = val & SBADMATCH0_BS1_MASK;
    273                 break;
     178        data[2] = (val >> 24) & 0xFF;
     179        data[3] = (val >> 16) & 0xFF;
     180        data[4] = (val >> 8) & 0xFF;
     181        data[5] = (val >> 0) & 0xFF;
    274182
    275         case 2:
    276         default:
    277                 base = val & SBADMATCH0_BS2_MASK;
    278                 break;
    279         };
    280 #endif
    281         return 0;
    282 }
     183        val = br32(bp, B44_CAM_DATA_HI);
    283184
    284 static int ssb_is_core_up(struct b44 *bp)
    285 {
    286         return ((br32(bp, B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
    287                 == SBTMSLOW_CLOCK);
     185        data[0] = (val >> 8) & 0xFF;
     186        data[1] = (val >> 0) & 0xFF;
    288187}
    289188
    290 static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
     189static inline void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
    291190{
    292191        u32 val;
    293192
     
    323222        bw32(bp, B44_IMASK, bp->imask);
    324223}
    325224
    326 static int b44_readphy(struct b44 *bp, int reg, u32 *val)
     225static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
    327226{
    328227        int err;
    329228
    330229        bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
    331230        bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
    332231                             (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
    333                              (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
     232                             (phy_addr << MDIO_DATA_PMD_SHIFT) |
    334233                             (reg << MDIO_DATA_RA_SHIFT) |
    335234                             (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
    336235        err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
     
    339238        return err;
    340239}
    341240
    342 static int b44_writephy(struct b44 *bp, int reg, u32 val)
     241static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
    343242{
    344243        bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
    345244        bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
    346245                             (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
    347                              (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
     246                             (phy_addr << MDIO_DATA_PMD_SHIFT) |
    348247                             (reg << MDIO_DATA_RA_SHIFT) |
    349248                             (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
    350249                             (val & MDIO_DATA_DATA)));
    351250        return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
    352251}
    353252
     253static inline int b44_readphy(struct b44 *bp, int reg, u32 *val)
     254{
     255        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     256                return 0;
     257
     258        return __b44_readphy(bp, bp->phy_addr, reg, val);
     259}
     260
     261static inline int b44_writephy(struct b44 *bp, int reg, u32 val)
     262{
     263        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     264                return 0;
     265               
     266        return __b44_writephy(bp, bp->phy_addr, reg, val);
     267}
     268
    354269/* miilib interface */
    355270/* FIXME FIXME: phy_id is ignored, bp->phy_addr use is unconditional
    356271 * due to code existing before miilib use was added to this driver.
     
    379294        u32 val;
    380295        int err;
    381296
     297        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     298                return 0;
    382299        err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
    383300        if (err)
    384301                return err;
     
    437354        __b44_set_flow_ctrl(bp, pause_enab);
    438355}
    439356
     357
     358extern char *nvram_get(char *name); //FIXME: move elsewhere
    440359static int b44_setup_phy(struct b44 *bp)
    441360{
    442361        u32 val;
    443362        int err;
    444363
     364        /*
     365         * workaround for bad hardware design in Linksys WAP54G v1.0
     366         * see https://dev.openwrt.org/ticket/146
     367         * check and reset bit "isolate"
     368         */
     369        if ((atoi(nvram_get("boardnum")) == 2) &&
     370                        (__b44_readphy(bp, 0, MII_BMCR, &val) == 0) &&
     371                        (val & BMCR_ISOLATE) &&
     372                        (__b44_writephy(bp, 0, MII_BMCR, val & ~BMCR_ISOLATE) != 0)) {
     373                printk(KERN_WARNING PFX "PHY: cannot reset MII transceiver isolate bit.\n");
     374        }
     375
     376        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     377                return 0;
    445378        if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
    446379                goto out;
    447380        if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
     
    537470{
    538471        u32 bmsr, aux;
    539472
     473        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
     474                bp->flags |= B44_FLAG_100_BASE_T;
     475                bp->flags |= B44_FLAG_FULL_DUPLEX;
     476                if (!netif_carrier_ok(bp->dev)) {
     477                        u32 val = br32(bp, B44_TX_CTRL);
     478                        val |= TX_CTRL_DUPLEX;
     479                        bw32(bp, B44_TX_CTRL, val);
     480                        netif_carrier_on(bp->dev);
     481                        b44_link_report(bp);
     482                }
     483                return;
     484        }
     485
    540486        if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
    541487            !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
    542488            (bmsr != 0xffff)) {
     
    613559
    614560                BUG_ON(skb == NULL);
    615561
    616                 pci_unmap_single(bp->pdev,
     562                dma_unmap_single(&bp->sdev->dev,
    617563                                 pci_unmap_addr(rp, mapping),
    618564                                 skb->len,
    619                                  PCI_DMA_TODEVICE);
     565                                 DMA_TO_DEVICE);
    620566                rp->skb = NULL;
    621567                dev_kfree_skb_irq(skb);
    622568        }
     
    652598        skb = dev_alloc_skb(RX_PKT_BUF_SZ);
    653599        if (skb == NULL)
    654600                return -ENOMEM;
    655 
    656         mapping = pci_map_single(bp->pdev, skb->data,
     601       
     602        mapping = dma_map_single(&bp->sdev->dev, skb->data,
    657603                                 RX_PKT_BUF_SZ,
    658                                  PCI_DMA_FROMDEVICE);
     604                                 DMA_FROM_DEVICE);
    659605
    660606        /* Hardware bug work-around, the chip is unable to do PCI DMA
    661607           to/from anything above 1GB :-( */
     
    663609                mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
    664610                /* Sigh... */
    665611                if (!dma_mapping_error(mapping))
    666                         pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
     612                        dma_unmap_single(&bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
    667613                dev_kfree_skb_any(skb);
    668614                skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
    669615                if (skb == NULL)
    670616                        return -ENOMEM;
    671                 mapping = pci_map_single(bp->pdev, skb->data,
     617                mapping = dma_map_single(&bp->sdev->dev, skb->data,
    672618                                         RX_PKT_BUF_SZ,
    673                                          PCI_DMA_FROMDEVICE);
     619                                         DMA_FROM_DEVICE);
    674620                if (dma_mapping_error(mapping) ||
    675621                        mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
    676622                        if (!dma_mapping_error(mapping))
    677                                 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
     623                                dma_unmap_single(&bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
    678624                        dev_kfree_skb_any(skb);
    679625                        return -ENOMEM;
    680626                }
     
    703649        dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
    704650
    705651        if (bp->flags & B44_FLAG_RX_RING_HACK)
    706                 b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
    707                                              dest_idx * sizeof(dp),
    708                                              DMA_BIDIRECTIONAL);
     652                b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
     653                                            dest_idx * sizeof(dp),
     654                                            DMA_BIDIRECTIONAL);
    709655
    710656        return RX_PKT_BUF_SZ;
    711657}
     
    732678                           pci_unmap_addr(src_map, mapping));
    733679
    734680        if (bp->flags & B44_FLAG_RX_RING_HACK)
    735                 b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
    736                                           src_idx * sizeof(src_desc),
    737                                           DMA_BIDIRECTIONAL);
     681                b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
     682                                         src_idx * sizeof(src_desc),
     683                                         DMA_BIDIRECTIONAL);
    738684
    739685        ctrl = src_desc->ctrl;
    740686        if (dest_idx == (B44_RX_RING_SIZE - 1))
     
    748694        src_map->skb = NULL;
    749695
    750696        if (bp->flags & B44_FLAG_RX_RING_HACK)
    751                 b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
    752                                              dest_idx * sizeof(dest_desc),
    753                                              DMA_BIDIRECTIONAL);
     697                b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
     698                                            dest_idx * sizeof(dest_desc),
     699                                            DMA_BIDIRECTIONAL);
    754700
    755         pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
     701        dma_sync_single_for_device(&bp->sdev->dev, src_desc->addr,
    756702                                       RX_PKT_BUF_SZ,
    757                                        PCI_DMA_FROMDEVICE);
     703                                       DMA_FROM_DEVICE);
    758704}
    759705
    760706static int b44_rx(struct b44 *bp, int budget)
     
    774720                struct rx_header *rh;
    775721                u16 len;
    776722
    777                 pci_dma_sync_single_for_cpu(bp->pdev, map,
     723                dma_sync_single_for_cpu(&bp->sdev->dev, map,
    778724                                            RX_PKT_BUF_SZ,
    779                                             PCI_DMA_FROMDEVICE);
     725                                            DMA_FROM_DEVICE);
    780726                rh = (struct rx_header *) skb->data;
    781727                len = cpu_to_le16(rh->len);
    782728                if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
     
    808754                        skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
    809755                        if (skb_size < 0)
    810756                                goto drop_it;
    811                         pci_unmap_single(bp->pdev, map,
    812                                          skb_size, PCI_DMA_FROMDEVICE);
     757                        dma_unmap_single(&bp->sdev->dev, map,
     758                                         skb_size, DMA_FROM_DEVICE);
    813759                        /* Leave out rx_header */
    814                         skb_put(skb, len+bp->rx_offset);
    815                         skb_pull(skb,bp->rx_offset);
     760                skb_put(skb, len+bp->rx_offset);
     761                        skb_pull(skb,bp->rx_offset);
    816762                } else {
    817763                        struct sk_buff *copy_skb;
    818764
     
    980926                goto err_out;
    981927        }
    982928
    983         mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
     929        mapping = dma_map_single(&bp->sdev->dev, skb->data, len, DMA_TO_DEVICE);
    984930        if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
    985931                /* Chip can't handle DMA to/from >1GB, use bounce buffer */
    986932                if (!dma_mapping_error(mapping))
    987                         pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
     933                        dma_unmap_single(&bp->sdev->dev, mapping, len, DMA_TO_DEVICE);
    988934
    989935                bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
    990936                                             GFP_ATOMIC|GFP_DMA);
    991937                if (!bounce_skb)
    992938                        goto err_out;
    993939
    994                 mapping = pci_map_single(bp->pdev, bounce_skb->data,
    995                                          len, PCI_DMA_TODEVICE);
     940                mapping = dma_map_single(&bp->sdev->dev, bounce_skb->data,
     941                                         len, DMA_TO_DEVICE);
    996942                if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
    997943                        if (!dma_mapping_error(mapping))
    998                                 pci_unmap_single(bp->pdev, mapping,
    999                                          len, PCI_DMA_TODEVICE);
     944                                dma_unmap_single(&bp->sdev->dev, mapping,
     945                                         len, DMA_TO_DEVICE);
    1000946                        dev_kfree_skb_any(bounce_skb);
    1001947                        goto err_out;
    1002948                }
     
    1019965        bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
    1020966
    1021967        if (bp->flags & B44_FLAG_TX_RING_HACK)
    1022                 b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
    1023                                              entry * sizeof(bp->tx_ring[0]),
    1024                                              DMA_TO_DEVICE);
     968                b44_sync_dma_desc_for_device(bp->sdev, bp->tx_ring_dma,
     969                                            entry * sizeof(bp->tx_ring[0]),
     970                                            DMA_TO_DEVICE);
    1025971
    1026972        entry = NEXT_TX(entry);
    1027973
     
    10941040
    10951041                if (rp->skb == NULL)
    10961042                        continue;
    1097                 pci_unmap_single(bp->pdev,
     1043                dma_unmap_single(&bp->sdev->dev,
    10981044                                 pci_unmap_addr(rp, mapping),
    10991045                                 RX_PKT_BUF_SZ,
    1100                                  PCI_DMA_FROMDEVICE);
     1046                                 DMA_FROM_DEVICE);
    11011047                dev_kfree_skb_any(rp->skb);
    11021048                rp->skb = NULL;
    11031049        }
     
    11081054
    11091055                if (rp->skb == NULL)
    11101056                        continue;
    1111                 pci_unmap_single(bp->pdev,
     1057                dma_unmap_single(&bp->sdev->dev,
    11121058                                 pci_unmap_addr(rp, mapping),
    11131059                                 rp->skb->len,
    1114                                  PCI_DMA_TODEVICE);
     1060                                 DMA_TO_DEVICE);
    11151061                dev_kfree_skb_any(rp->skb);
    11161062                rp->skb = NULL;
    11171063        }
     
    11331079        memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
    11341080
    11351081        if (bp->flags & B44_FLAG_RX_RING_HACK)
    1136                 dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
    1137                                            DMA_TABLE_BYTES,
    1138                                            PCI_DMA_BIDIRECTIONAL);
     1082                dma_sync_single_for_device(&bp->sdev->dev, bp->rx_ring_dma,
     1083                                          DMA_TABLE_BYTES,
     1084                                          DMA_BIDIRECTIONAL);
    11391085
    11401086        if (bp->flags & B44_FLAG_TX_RING_HACK)
    1141                 dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
    1142                                            DMA_TABLE_BYTES,
    1143                                            PCI_DMA_TODEVICE);
     1087                dma_sync_single_for_device(&bp->sdev->dev, bp->tx_ring_dma,
     1088                                          DMA_TABLE_BYTES,
     1089                                          DMA_TO_DEVICE);
    11441090
    11451091        for (i = 0; i < bp->rx_pending; i++) {
    11461092                if (b44_alloc_rx_skb(bp, -1, i) < 0)
     
    11601106        bp->tx_buffers = NULL;
    11611107        if (bp->rx_ring) {
    11621108                if (bp->flags & B44_FLAG_RX_RING_HACK) {
    1163                         dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
    1164                                          DMA_TABLE_BYTES,
    1165                                          DMA_BIDIRECTIONAL);
     1109                        dma_unmap_single(&bp->sdev->dev, bp->rx_ring_dma,
     1110                                        DMA_TABLE_BYTES,
     1111                                        DMA_BIDIRECTIONAL);
    11661112                        kfree(bp->rx_ring);
    11671113                } else
    1168                         pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
     1114                        dma_free_coherent(&bp->sdev->dev, DMA_TABLE_BYTES,
    11691115                                            bp->rx_ring, bp->rx_ring_dma);
    11701116                bp->rx_ring = NULL;
    11711117                bp->flags &= ~B44_FLAG_RX_RING_HACK;
    11721118        }
    11731119        if (bp->tx_ring) {
    11741120                if (bp->flags & B44_FLAG_TX_RING_HACK) {
    1175                         dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
    1176                                          DMA_TABLE_BYTES,
    1177                                          DMA_TO_DEVICE);
     1121                        dma_unmap_single(&bp->sdev->dev, bp->tx_ring_dma,
     1122                                        DMA_TABLE_BYTES,
     1123                                        DMA_TO_DEVICE);
    11781124                        kfree(bp->tx_ring);
    11791125                } else
    1180                         pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
     1126                        dma_free_coherent(&bp->sdev->dev, DMA_TABLE_BYTES,
    11811127                                            bp->tx_ring, bp->tx_ring_dma);
    11821128                bp->tx_ring = NULL;
    11831129                bp->flags &= ~B44_FLAG_TX_RING_HACK;
     
    12031149                goto out_err;
    12041150
    12051151        size = DMA_TABLE_BYTES;
    1206         bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
     1152        bp->rx_ring = dma_alloc_coherent(&bp->sdev->dev, size, &bp->rx_ring_dma, GFP_ATOMIC);
    12071153        if (!bp->rx_ring) {
    12081154                /* Allocation may have failed due to pci_alloc_consistent
    12091155                   insisting on use of GFP_DMA, which is more restrictive
     
    12151161                if (!rx_ring)
    12161162                        goto out_err;
    12171163
    1218                 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
    1219                                              DMA_TABLE_BYTES,
    1220                                              DMA_BIDIRECTIONAL);
     1164                rx_ring_dma = dma_map_single(&bp->sdev->dev, rx_ring,
     1165                                            DMA_TABLE_BYTES,
     1166                                            DMA_BIDIRECTIONAL);
    12211167
    12221168                if (dma_mapping_error(rx_ring_dma) ||
    12231169                        rx_ring_dma + size > B44_DMA_MASK) {
     
    12301176                bp->flags |= B44_FLAG_RX_RING_HACK;
    12311177        }
    12321178
    1233         bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
     1179        bp->tx_ring = dma_alloc_coherent(&bp->sdev->dev, size, &bp->tx_ring_dma, GFP_ATOMIC);
    12341180        if (!bp->tx_ring) {
    1235                 /* Allocation may have failed due to pci_alloc_consistent
     1181                /* Allocation may have failed due to dma_alloc_coherent
    12361182                   insisting on use of GFP_DMA, which is more restrictive
    12371183                   than necessary...  */
    12381184                struct dma_desc *tx_ring;
     
    12421188                if (!tx_ring)
    12431189                        goto out_err;
    12441190
    1245                 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
    1246                                              DMA_TABLE_BYTES,
    1247                                              DMA_TO_DEVICE);
     1191                tx_ring_dma = dma_map_single(&bp->sdev->dev, tx_ring,
     1192                                            DMA_TABLE_BYTES,
     1193                                            DMA_TO_DEVICE);
    12481194
    12491195                if (dma_mapping_error(tx_ring_dma) ||
    12501196                        tx_ring_dma + size > B44_DMA_MASK) {
     
    12791225/* bp->lock is held. */
    12801226static void b44_chip_reset(struct b44 *bp)
    12811227{
    1282         if (ssb_is_core_up(bp)) {
     1228        struct ssb_device *sdev = bp->sdev;
     1229
     1230        if (ssb_core_is_enabled(bp->sdev)) {
    12831231                bw32(bp, B44_RCV_LAZY, 0);
    12841232                bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
    12851233                b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
     
    12911239                }
    12921240                bw32(bp, B44_DMARX_CTRL, 0);
    12931241                bp->rx_prod = bp->rx_cons = 0;
    1294         } else {
    1295                 ssb_pci_setup(bp, (bp->core_unit == 0 ?
    1296                                    SBINTVEC_ENET0 :
    1297                                    SBINTVEC_ENET1));
    12981242        }
    12991243
    1300         ssb_core_reset(bp);
    1301 
     1244        ssb_core_enable(bp->sdev, 0);
    13021245        b44_clear_stats(bp);
    13031246
    1304         /* Make PHY accessible. */
    1305         bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
     1247        switch (sdev->bus->bustype) {
     1248        case SSB_BUSTYPE_SSB:
     1249                        bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
     1250                             (((ssb_clockspeed(sdev->bus) + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
     1251                             & MDIO_CTRL_MAXF_MASK)));
     1252                break;
     1253        case SSB_BUSTYPE_PCI:
     1254                bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
    13061255                             (0x0d & MDIO_CTRL_MAXF_MASK)));
     1256                break;
     1257        }
     1258
    13071259        br32(bp, B44_MDIO_CTRL);
    13081260
    13091261        if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) {
     
    13461298{
    13471299        struct b44 *bp = netdev_priv(dev);
    13481300        struct sockaddr *addr = p;
     1301        u32 val;
    13491302
    13501303        if (netif_running(dev))
    13511304                return -EBUSY;
     
    13561309        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
    13571310
    13581311        spin_lock_irq(&bp->lock);
    1359         __b44_set_mac_addr(bp);
     1312   
     1313        val = br32(bp, B44_RXCONFIG);
     1314        if (!(val & RXCONFIG_CAM_ABSENT))
     1315                __b44_set_mac_addr(bp);
     1316   
    13601317        spin_unlock_irq(&bp->lock);
    13611318
    13621319        return 0;
     
    14421399        return err;
    14431400}
    14441401
    1445 #if 0
    1446 /*static*/ void b44_dump_state(struct b44 *bp)
    1447 {
    1448         u32 val32, val32_2, val32_3, val32_4, val32_5;
    1449         u16 val16;
    1450 
    1451         pci_read_config_word(bp->pdev, PCI_STATUS, &val16);
    1452         printk("DEBUG: PCI status [%04x] \n", val16);
    1453 
    1454 }
    1455 #endif
    1456 
    14571402#ifdef CONFIG_NET_POLL_CONTROLLER
    14581403/*
    14591404 * Polling receive - used by netconsole and other diagnostic tools
     
    15681513static void b44_setup_wol(struct b44 *bp)
    15691514{
    15701515        u32 val;
    1571         u16 pmval;
    15721516
    15731517        bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI);
    15741518
     
    15921536        } else {
    15931537                b44_setup_pseudo_magicp(bp);
    15941538        }
    1595 
    1596         val = br32(bp, B44_SBTMSLOW);
    1597         bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
    1598 
    1599         pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval);
    1600         pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE);
    1601 
    16021539}
    16031540
    16041541static int b44_close(struct net_device *dev)
     
    16981635
    16991636        val = br32(bp, B44_RXCONFIG);
    17001637        val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
    1701         if (dev->flags & IFF_PROMISC) {
     1638        if ((dev->flags & IFF_PROMISC) || (val & RXCONFIG_CAM_ABSENT)) {
    17021639                val |= RXCONFIG_PROMISC;
    17031640                bw32(bp, B44_RXCONFIG, val);
    17041641        } else {
     
    17451682
    17461683static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
    17471684{
    1748         struct b44 *bp = netdev_priv(dev);
    1749         struct pci_dev *pci_dev = bp->pdev;
    1750 
    17511685        strcpy (info->driver, DRV_MODULE_NAME);
    17521686        strcpy (info->version, DRV_MODULE_VERSION);
    1753         strcpy (info->bus_info, pci_name(pci_dev));
    17541687}
    17551688
    17561689static int b44_nway_reset(struct net_device *dev)
     
    20341967        .get_perm_addr          = ethtool_op_get_perm_addr,
    20351968};
    20361969
     1970static int b44_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
     1971{
     1972        struct b44 *bp = dev->priv;
     1973        u32 ethcmd;
     1974
     1975        if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
     1976                return -EFAULT;
     1977
     1978        switch (ethcmd) {
     1979        case ETHTOOL_GDRVINFO: {
     1980                struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
     1981                strcpy (info.driver, DRV_MODULE_NAME);
     1982                strcpy (info.version, DRV_MODULE_VERSION);
     1983                memset(&info.fw_version, 0, sizeof(info.fw_version));
     1984                info.eedump_len = 0;
     1985                info.regdump_len = 0;
     1986                if (copy_to_user (useraddr, &info, sizeof (info)))
     1987                        return -EFAULT;
     1988                return 0;
     1989        }
     1990
     1991        case ETHTOOL_GSET: {
     1992                struct ethtool_cmd cmd = { ETHTOOL_GSET };
     1993
     1994                if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
     1995                        return -EAGAIN;
     1996                cmd.supported = (SUPPORTED_Autoneg);
     1997                cmd.supported |= (SUPPORTED_100baseT_Half |
     1998                                  SUPPORTED_100baseT_Full |
     1999                                  SUPPORTED_10baseT_Half |
     2000                                  SUPPORTED_10baseT_Full |
     2001                                  SUPPORTED_MII);
     2002
     2003                cmd.advertising = 0;
     2004                if (bp->flags & B44_FLAG_ADV_10HALF)
     2005                        cmd.advertising |= ADVERTISE_10HALF;
     2006                if (bp->flags & B44_FLAG_ADV_10FULL)
     2007                        cmd.advertising |= ADVERTISE_10FULL;
     2008                if (bp->flags & B44_FLAG_ADV_100HALF)
     2009                        cmd.advertising |= ADVERTISE_100HALF;
     2010                if (bp->flags & B44_FLAG_ADV_100FULL)
     2011                        cmd.advertising |= ADVERTISE_100FULL;
     2012                cmd.advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
     2013                cmd.speed = (bp->flags & B44_FLAG_100_BASE_T) ?
     2014                        SPEED_100 : SPEED_10;
     2015                cmd.duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
     2016                        DUPLEX_FULL : DUPLEX_HALF;
     2017                cmd.port = 0;
     2018                cmd.phy_address = bp->phy_addr;
     2019                cmd.transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
     2020                        XCVR_INTERNAL : XCVR_EXTERNAL;
     2021                cmd.autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
     2022                        AUTONEG_DISABLE : AUTONEG_ENABLE;
     2023                cmd.maxtxpkt = 0;
     2024                cmd.maxrxpkt = 0;
     2025                if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
     2026                        return -EFAULT;
     2027                return 0;
     2028        }
     2029        case ETHTOOL_SSET: {
     2030                struct ethtool_cmd cmd;
     2031
     2032                if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
     2033                        return -EAGAIN;
     2034
     2035                if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
     2036                        return -EFAULT;
     2037
     2038                /* We do not support gigabit. */
     2039                if (cmd.autoneg == AUTONEG_ENABLE) {
     2040                        if (cmd.advertising &
     2041                            (ADVERTISED_1000baseT_Half |
     2042                             ADVERTISED_1000baseT_Full))
     2043                                return -EINVAL;
     2044                } else if ((cmd.speed != SPEED_100 &&
     2045                            cmd.speed != SPEED_10) ||
     2046                           (cmd.duplex != DUPLEX_HALF &&
     2047                            cmd.duplex != DUPLEX_FULL)) {
     2048                                return -EINVAL;
     2049                }
     2050
     2051                spin_lock_irq(&bp->lock);
     2052
     2053                if (cmd.autoneg == AUTONEG_ENABLE) {
     2054                        bp->flags &= ~B44_FLAG_FORCE_LINK;
     2055                        bp->flags &= ~(B44_FLAG_ADV_10HALF |
     2056                                       B44_FLAG_ADV_10FULL |
     2057                                       B44_FLAG_ADV_100HALF |
     2058                                       B44_FLAG_ADV_100FULL);
     2059                        if (cmd.advertising & ADVERTISE_10HALF)
     2060                                bp->flags |= B44_FLAG_ADV_10HALF;
     2061                        if (cmd.advertising & ADVERTISE_10FULL)
     2062                                bp->flags |= B44_FLAG_ADV_10FULL;
     2063                        if (cmd.advertising & ADVERTISE_100HALF)
     2064                                bp->flags |= B44_FLAG_ADV_100HALF;
     2065                        if (cmd.advertising & ADVERTISE_100FULL)
     2066                                bp->flags |= B44_FLAG_ADV_100FULL;
     2067                } else {
     2068                        bp->flags |= B44_FLAG_FORCE_LINK;
     2069                        if (cmd.speed == SPEED_100)
     2070                                bp->flags |= B44_FLAG_100_BASE_T;
     2071                        if (cmd.duplex == DUPLEX_FULL)
     2072                                bp->flags |= B44_FLAG_FULL_DUPLEX;
     2073                }
     2074
     2075                b44_setup_phy(bp);
     2076
     2077                spin_unlock_irq(&bp->lock);
     2078
     2079                return 0;
     2080        }
     2081
     2082        case ETHTOOL_GMSGLVL: {
     2083                struct ethtool_value edata = { ETHTOOL_GMSGLVL };
     2084                edata.data = bp->msg_enable;
     2085                if (copy_to_user(useraddr, &edata, sizeof(edata)))
     2086                        return -EFAULT;
     2087                return 0;
     2088        }
     2089        case ETHTOOL_SMSGLVL: {
     2090                struct ethtool_value edata;
     2091                if (copy_from_user(&edata, useraddr, sizeof(edata)))
     2092                        return -EFAULT;
     2093                bp->msg_enable = edata.data;
     2094                return 0;
     2095        }
     2096        case ETHTOOL_NWAY_RST: {
     2097                u32 bmcr;
     2098                int r;
     2099
     2100                spin_lock_irq(&bp->lock);
     2101                b44_readphy(bp, MII_BMCR, &bmcr);
     2102                b44_readphy(bp, MII_BMCR, &bmcr);
     2103                r = -EINVAL;
     2104                if (bmcr & BMCR_ANENABLE) {
     2105                        b44_writephy(bp, MII_BMCR,
     2106                                     bmcr | BMCR_ANRESTART);
     2107                        r = 0;
     2108                }
     2109                spin_unlock_irq(&bp->lock);
     2110
     2111                return r;
     2112        }
     2113        case ETHTOOL_GLINK: {
     2114                struct ethtool_value edata = { ETHTOOL_GLINK };
     2115                edata.data = netif_carrier_ok(bp->dev) ? 1 : 0;
     2116                if (copy_to_user(useraddr, &edata, sizeof(edata)))
     2117                        return -EFAULT;
     2118                return 0;
     2119        }
     2120        case ETHTOOL_GRINGPARAM: {
     2121                struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
     2122
     2123                ering.rx_max_pending = B44_RX_RING_SIZE - 1;
     2124                ering.rx_pending = bp->rx_pending;
     2125
     2126                /* XXX ethtool lacks a tx_max_pending, oops... */
     2127
     2128                if (copy_to_user(useraddr, &ering, sizeof(ering)))
     2129                        return -EFAULT;
     2130                return 0;
     2131        }
     2132        case ETHTOOL_SRINGPARAM: {
     2133                struct ethtool_ringparam ering;
     2134
     2135                if (copy_from_user(&ering, useraddr, sizeof(ering)))
     2136                        return -EFAULT;
     2137
     2138                if ((ering.rx_pending > B44_RX_RING_SIZE - 1) ||
     2139                    (ering.rx_mini_pending != 0) ||
     2140                    (ering.rx_jumbo_pending != 0) ||
     2141                    (ering.tx_pending > B44_TX_RING_SIZE - 1))
     2142                        return -EINVAL;
     2143
     2144                spin_lock_irq(&bp->lock);
     2145
     2146                bp->rx_pending = ering.rx_pending;
     2147                bp->tx_pending = ering.tx_pending;
     2148
     2149                b44_halt(bp);
     2150                b44_init_rings(bp);
     2151                b44_init_hw(bp, 1);
     2152                netif_wake_queue(bp->dev);
     2153                spin_unlock_irq(&bp->lock);
     2154
     2155                b44_enable_ints(bp);
     2156               
     2157                return 0;
     2158        }
     2159        case ETHTOOL_GPAUSEPARAM: {
     2160                struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
     2161
     2162                epause.autoneg =
     2163                        (bp->flags & B44_FLAG_PAUSE_AUTO) != 0;
     2164                epause.rx_pause =
     2165                        (bp->flags & B44_FLAG_RX_PAUSE) != 0;
     2166                epause.tx_pause =
     2167                        (bp->flags & B44_FLAG_TX_PAUSE) != 0;
     2168                if (copy_to_user(useraddr, &epause, sizeof(epause)))
     2169                        return -EFAULT;
     2170                return 0;
     2171        }
     2172        case ETHTOOL_SPAUSEPARAM: {
     2173                struct ethtool_pauseparam epause;
     2174
     2175                if (copy_from_user(&epause, useraddr, sizeof(epause)))
     2176                        return -EFAULT;
     2177
     2178                spin_lock_irq(&bp->lock);
     2179                if (epause.autoneg)
     2180                        bp->flags |= B44_FLAG_PAUSE_AUTO;
     2181                else
     2182                        bp->flags &= ~B44_FLAG_PAUSE_AUTO;
     2183                if (epause.rx_pause)
     2184                        bp->flags |= B44_FLAG_RX_PAUSE;
     2185                else
     2186                        bp->flags &= ~B44_FLAG_RX_PAUSE;
     2187                if (epause.tx_pause)
     2188                        bp->flags |= B44_FLAG_TX_PAUSE;
     2189                else
     2190                        bp->flags &= ~B44_FLAG_TX_PAUSE;
     2191                if (bp->flags & B44_FLAG_PAUSE_AUTO) {
     2192                        b44_halt(bp);
     2193                        b44_init_rings(bp);
     2194                        b44_init_hw(bp, 1);
     2195                } else {
     2196                        __b44_set_flow_ctrl(bp, bp->flags);
     2197                }
     2198                spin_unlock_irq(&bp->lock);
     2199
     2200                b44_enable_ints(bp);
     2201               
     2202                return 0;
     2203        }
     2204        };
     2205
     2206        return -EOPNOTSUPP;
     2207}
     2208
    20372209static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
    20382210{
    20392211        struct mii_ioctl_data *data = if_mii(ifr);
     
    20432215        if (!netif_running(dev))
    20442216                goto out;
    20452217
    2046         spin_lock_irq(&bp->lock);
    2047         err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
    2048         spin_unlock_irq(&bp->lock);
    2049 out:
    2050         return err;
    2051 }
     2218        switch (cmd) {
     2219        case SIOCETHTOOL:
     2220               return b44_ethtool_ioctl(dev, (void __user*) ifr->ifr_data);
    20522221
    2053 /* Read 128-bytes of EEPROM. */
    2054 static int b44_read_eeprom(struct b44 *bp, u8 *data)
    2055 {
    2056         long i;
    2057         u16 *ptr = (u16 *) data;
     2222        case SIOCGMIIPHY:
     2223               data->phy_id = bp->phy_addr;
    20582224
    2059         for (i = 0; i < 128; i += 2)
    2060                 ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
     2225               /* fallthru */
     2226        case SIOCGMIIREG: {
     2227               u32 mii_regval;
     2228               spin_lock_irq(&bp->lock);
     2229               err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
     2230               spin_unlock_irq(&bp->lock);
    20612231
    2062         return 0;
     2232               data->val_out = mii_regval;
     2233
     2234               return err;
     2235        }
     2236
     2237        case SIOCSMIIREG:
     2238               if (!capable(CAP_NET_ADMIN))
     2239                      return -EPERM;
     2240
     2241               spin_lock_irq(&bp->lock);
     2242               err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
     2243               spin_unlock_irq(&bp->lock);
     2244
     2245               return err;
     2246
     2247        default:
     2248               break;
     2249        };
     2250        return -EOPNOTSUPP;
     2251
     2252out:
     2253        return err;
    20632254}
    20642255
    20652256static int __devinit b44_get_invariants(struct b44 *bp)
    20662257{
    2067         u8 eeprom[128];
    2068         int err;
     2258        struct ssb_device *sdev = bp->sdev;
     2259        int err = 0;
     2260        u8 *addr;
    20692261
    2070         err = b44_read_eeprom(bp, &eeprom[0]);
    2071         if (err)
    2072                 goto out;
     2262        bp->dma_offset = ssb_dma_offset(sdev);
    20732263
    2074         bp->dev->dev_addr[0] = eeprom[79];
    2075         bp->dev->dev_addr[1] = eeprom[78];
    2076         bp->dev->dev_addr[2] = eeprom[81];
    2077         bp->dev->dev_addr[3] = eeprom[80];
    2078         bp->dev->dev_addr[4] = eeprom[83];
    2079         bp->dev->dev_addr[5] = eeprom[82];
     2264        switch (instance) {
     2265        case 1:
     2266               addr = sdev->bus->sprom.r1.et0mac;
     2267               bp->phy_addr = sdev->bus->sprom.r1.et0phyaddr;
     2268               break;
     2269        default:
     2270               addr = sdev->bus->sprom.r1.et1mac;
     2271               bp->phy_addr = sdev->bus->sprom.r1.et1phyaddr;
     2272               break;
     2273        }
     2274
     2275        memcpy(bp->dev->dev_addr, addr, 6);
    20802276
    20812277        if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
    20822278                printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
     
    20852281
    20862282        memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
    20872283
    2088         bp->phy_addr = eeprom[90] & 0x1f;
    2089 
    20902284        /* With this, plus the rx_header prepended to the data by the
    20912285         * hardware, we'll land the ethernet header on a 2-byte boundary.
    20922286         */
    20932287        bp->rx_offset = 30;
    2094 
    20952288        bp->imask = IMASK_DEF;
    2096 
    2097         bp->core_unit = ssb_core_unit(bp);
    2098         bp->dma_offset = SB_PCI_DMA;
    2099 
    21002289        /* XXX - really required?
    21012290           bp->flags |= B44_FLAG_BUGGY_TXPTR;
    2102          */
     2291        */
    21032292
    2104         if (ssb_get_core_rev(bp) >= 7)
    2105                 bp->flags |= B44_FLAG_B0_ANDLATER;
    2106 
    2107 out:
    21082293        return err;
    21092294}
    21102295
    2111 static int __devinit b44_init_one(struct pci_dev *pdev,
    2112                                   const struct pci_device_id *ent)
     2296static int __devinit b44_init_one(struct ssb_device *sdev,
     2297                                  const struct ssb_device_id *ent)
    21132298{
    21142299        static int b44_version_printed = 0;
    2115         unsigned long b44reg_base, b44reg_len;
    21162300        struct net_device *dev;
    21172301        struct b44 *bp;
    21182302        int err, i;
    21192303
     2304        instance++;
     2305
    21202306        if (b44_version_printed++ == 0)
    21212307                printk(KERN_INFO "%s", version);
    21222308
    2123         err = pci_enable_device(pdev);
    2124         if (err) {
    2125                 dev_err(&pdev->dev, "Cannot enable PCI device, "
    2126                        "aborting.\n");
    2127                 return err;
    2128         }
    2129 
    2130         if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
    2131                 dev_err(&pdev->dev,
    2132                         "Cannot find proper PCI device "
    2133                        "base address, aborting.\n");
    2134                 err = -ENODEV;
    2135                 goto err_out_disable_pdev;
    2136         }
    2137 
    2138         err = pci_request_regions(pdev, DRV_MODULE_NAME);
    2139         if (err) {
    2140                 dev_err(&pdev->dev,
    2141                         "Cannot obtain PCI resources, aborting.\n");
    2142                 goto err_out_disable_pdev;
    2143         }
    2144 
    2145         pci_set_master(pdev);
    2146 
    2147         err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK);
    2148         if (err) {
    2149                 dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
    2150                 goto err_out_free_res;
    2151         }
    2152 
    2153         err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
    2154         if (err) {
    2155                 dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
    2156                 goto err_out_free_res;
    2157         }
    2158 
    2159         b44reg_base = pci_resource_start(pdev, 0);
    2160         b44reg_len = pci_resource_len(pdev, 0);
    2161 
    21622309        dev = alloc_etherdev(sizeof(*bp));
    21632310        if (!dev) {
    2164                 dev_err(&pdev->dev, "Etherdev alloc failed, aborting.\n");
     2311                dev_err(&sdev->dev, "Etherdev alloc failed, aborting.\n");
    21652312                err = -ENOMEM;
    2166                 goto err_out_free_res;
     2313                goto out;
    21672314        }
    21682315
    21692316        SET_MODULE_OWNER(dev);
    2170         SET_NETDEV_DEV(dev,&pdev->dev);
     2317        SET_NETDEV_DEV(dev,&sdev->dev);
    21712318
    21722319        /* No interesting netdevice features in this card... */
    21732320        dev->features |= 0;
    21742321
    21752322        bp = netdev_priv(dev);
    2176         bp->pdev = pdev;
     2323        bp->sdev = sdev;
    21772324        bp->dev = dev;
    21782325
    21792326        bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
    21802327
    21812328        spin_lock_init(&bp->lock);
    21822329
    2183         bp->regs = ioremap(b44reg_base, b44reg_len);
    2184         if (bp->regs == 0UL) {
    2185                 dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
    2186                 err = -ENOMEM;
    2187                 goto err_out_free_dev;
    2188         }
    2189 
    21902330        bp->rx_pending = B44_DEF_RX_RING_PENDING;
    21912331        bp->tx_pending = B44_DEF_TX_RING_PENDING;
    21922332
     
    22052345        dev->poll_controller = b44_poll_controller;
    22062346#endif
    22072347        dev->change_mtu = b44_change_mtu;
    2208         dev->irq = pdev->irq;
     2348        dev->irq = sdev->irq;
    22092349        SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
    22102350
    22112351        netif_carrier_off(dev);
    22122352
    22132353        err = b44_get_invariants(bp);
    22142354        if (err) {
    2215                 dev_err(&pdev->dev,
     2355                dev_err(&sdev->dev,
    22162356                        "Problem fetching invariants of chip, aborting.\n");
    2217                 goto err_out_iounmap;
     2357                goto err_out_free_dev;
    22182358        }
    22192359
    22202360        bp->mii_if.dev = dev;
     
    22332373
    22342374        err = register_netdev(dev);
    22352375        if (err) {
    2236                 dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
    2237                 goto err_out_iounmap;
     2376                dev_err(&sdev->dev, "Cannot register net device, aborting.\n");
     2377                goto out;
    22382378        }
    22392379
    2240         pci_set_drvdata(pdev, dev);
    2241 
    2242         pci_save_state(bp->pdev);
     2380        ssb_set_drvdata(sdev, dev);
    22432381
    22442382        /* Chip reset provides power to the b44 MAC & PCI cores, which
    22452383         * is necessary for MAC register access.
    22462384         */
    22472385        b44_chip_reset(bp);
    22482386
    2249         printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
     2387        printk(KERN_INFO "%s: Broadcom 10/100BaseT Ethernet ", dev->name);
    22502388        for (i = 0; i < 6; i++)
    22512389                printk("%2.2x%c", dev->dev_addr[i],
    22522390                       i == 5 ? '\n' : ':');
    22532391
    2254         return 0;
     2392        /* Initialize phy */
     2393        spin_lock_irq(&bp->lock);
     2394        b44_chip_reset(bp);
     2395        spin_unlock_irq(&bp->lock);
    22552396
    2256 err_out_iounmap:
    2257         iounmap(bp->regs);
     2397        return 0;
    22582398
    22592399err_out_free_dev:
    22602400        free_netdev(dev);
    22612401
    2262 err_out_free_res:
    2263         pci_release_regions(pdev);
    2264 
    2265 err_out_disable_pdev:
    2266         pci_disable_device(pdev);
    2267         pci_set_drvdata(pdev, NULL);
     2402out:
    22682403        return err;
    22692404}
    22702405
    2271 static void __devexit b44_remove_one(struct pci_dev *pdev)
     2406static void __devexit b44_remove_one(struct ssb_device *pdev)
    22722407{
    2273         struct net_device *dev = pci_get_drvdata(pdev);
    2274         struct b44 *bp = netdev_priv(dev);
     2408        struct net_device *dev = ssb_get_drvdata(pdev);
    22752409
    22762410        unregister_netdev(dev);
    2277         iounmap(bp->regs);
    22782411        free_netdev(dev);
    2279         pci_release_regions(pdev);
    2280         pci_disable_device(pdev);
    2281         pci_set_drvdata(pdev, NULL);
     2412        ssb_set_drvdata(pdev, NULL);
    22822413}
    22832414
    2284 static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
     2415static int b44_suspend(struct ssb_device *pdev, pm_message_t state)
    22852416{
    2286         struct net_device *dev = pci_get_drvdata(pdev);
     2417        struct net_device *dev = ssb_get_drvdata(pdev);
    22872418        struct b44 *bp = netdev_priv(dev);
    22882419
    22892420        if (!netif_running(dev))
    2290                  return 0;
     2421                return 0;
    22912422
    22922423        del_timer_sync(&bp->timer);
    22932424
     
    23052436                b44_init_hw(bp, 0);
    23062437                b44_setup_wol(bp);
    23072438        }
    2308         pci_disable_device(pdev);
     2439
    23092440        return 0;
    23102441}
    23112442
    2312 static int b44_resume(struct pci_dev *pdev)
     2443static int b44_resume(struct ssb_device *pdev)
    23132444{
    2314         struct net_device *dev = pci_get_drvdata(pdev);
     2445        struct net_device *dev = ssb_get_drvdata(pdev);
    23152446        struct b44 *bp = netdev_priv(dev);
    23162447
    2317         pci_restore_state(pdev);
    2318         pci_enable_device(pdev);
    2319         pci_set_master(pdev);
    2320 
    23212448        if (!netif_running(dev))
    23222449                return 0;
    23232450
     
    23392466        return 0;
    23402467}
    23412468
    2342 static struct pci_driver b44_driver = {
     2469static struct ssb_driver b44_driver = {
    23432470        .name           = DRV_MODULE_NAME,
    2344         .id_table       = b44_pci_tbl,
     2471        .id_table       = b44_ssb_tbl,
    23452472        .probe          = b44_init_one,
    23462473        .remove         = __devexit_p(b44_remove_one),
    2347         .suspend        = b44_suspend,
    2348         .resume         = b44_resume,
     2474        .suspend        = b44_suspend,
     2475        .resume         = b44_resume,
    23492476};
    23502477
    23512478static int __init b44_init(void)
    23522479{
    23532480        unsigned int dma_desc_align_size = dma_get_cache_alignment();
    23542481
     2482        instance = 0;
     2483
    23552484        /* Setup paramaters for syncing RX/TX DMA descriptors */
    23562485        dma_desc_align_mask = ~(dma_desc_align_size - 1);
    23572486        dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc));
    23582487
    2359         return pci_register_driver(&b44_driver);
     2488        return ssb_driver_register(&b44_driver);
    23602489}
    23612490
    23622491static void __exit b44_cleanup(void)
    23632492{
    2364         pci_unregister_driver(&b44_driver);
     2493        ssb_driver_unregister(&b44_driver);
    23652494}
    23662495
    23672496module_init(b44_init);
  • drivers/net/b44.h

    diff -Nru linux-2.6.19.ori/drivers/net/b44.h linux-2.6.19/drivers/net/b44.h
    old new  
    129129#define  RXCONFIG_FLOW          0x00000020 /* Flow Control Enable */
    130130#define  RXCONFIG_FLOW_ACCEPT   0x00000040 /* Accept Unicast Flow Control Frame */
    131131#define  RXCONFIG_RFILT         0x00000080 /* Reject Filter */
     132#define  RXCONFIG_CAM_ABSENT    0x00000100 /* CAM Absent */
    132133#define B44_RXMAXLEN    0x0404UL /* EMAC RX Max Packet Length */
    133134#define B44_TXMAXLEN    0x0408UL /* EMAC TX Max Packet Length */
    134135#define B44_MDIO_CTRL   0x0410UL /* EMAC MDIO Control */
     
    227228#define B44_RX_PAUSE    0x05D4UL /* MIB RX Pause Packets */
    228229#define B44_RX_NPAUSE   0x05D8UL /* MIB RX Non-Pause Packets */
    229230
    230 /* Silicon backplane register definitions */
    231 #define B44_SBIMSTATE   0x0F90UL /* SB Initiator Agent State */
    232 #define  SBIMSTATE_PC           0x0000000f /* Pipe Count */
    233 #define  SBIMSTATE_AP_MASK      0x00000030 /* Arbitration Priority */
    234 #define  SBIMSTATE_AP_BOTH      0x00000000 /* Use both timeslices and token */
    235 #define  SBIMSTATE_AP_TS        0x00000010 /* Use timeslices only */
    236 #define  SBIMSTATE_AP_TK        0x00000020 /* Use token only */
    237 #define  SBIMSTATE_AP_RSV       0x00000030 /* Reserved */
    238 #define  SBIMSTATE_IBE          0x00020000 /* In Band Error */
    239 #define  SBIMSTATE_TO           0x00040000 /* Timeout */
    240 #define B44_SBINTVEC    0x0F94UL /* SB Interrupt Mask */
    241 #define  SBINTVEC_PCI           0x00000001 /* Enable interrupts for PCI */
    242 #define  SBINTVEC_ENET0         0x00000002 /* Enable interrupts for enet 0 */
    243 #define  SBINTVEC_ILINE20       0x00000004 /* Enable interrupts for iline20 */
    244 #define  SBINTVEC_CODEC         0x00000008 /* Enable interrupts for v90 codec */
    245 #define  SBINTVEC_USB           0x00000010 /* Enable interrupts for usb */
    246 #define  SBINTVEC_EXTIF         0x00000020 /* Enable interrupts for external i/f */
    247 #define  SBINTVEC_ENET1         0x00000040 /* Enable interrupts for enet 1 */
    248 #define B44_SBTMSLOW    0x0F98UL /* SB Target State Low */
    249 #define  SBTMSLOW_RESET         0x00000001 /* Reset */
    250 #define  SBTMSLOW_REJECT        0x00000002 /* Reject */
    251 #define  SBTMSLOW_CLOCK         0x00010000 /* Clock Enable */
    252 #define  SBTMSLOW_FGC           0x00020000 /* Force Gated Clocks On */
    253 #define  SBTMSLOW_PE            0x40000000 /* Power Management Enable */
    254 #define  SBTMSLOW_BE            0x80000000 /* BIST Enable */
    255 #define B44_SBTMSHIGH   0x0F9CUL /* SB Target State High */
    256 #define  SBTMSHIGH_SERR         0x00000001 /* S-error */
    257 #define  SBTMSHIGH_INT          0x00000002 /* Interrupt */
    258 #define  SBTMSHIGH_BUSY         0x00000004 /* Busy */
    259 #define  SBTMSHIGH_GCR          0x20000000 /* Gated Clock Request */
    260 #define  SBTMSHIGH_BISTF        0x40000000 /* BIST Failed */
    261 #define  SBTMSHIGH_BISTD        0x80000000 /* BIST Done */
    262 #define B44_SBIDHIGH    0x0FFCUL /* SB Identification High */
    263 #define  SBIDHIGH_RC_MASK       0x0000000f /* Revision Code */
    264 #define  SBIDHIGH_CC_MASK       0x0000fff0 /* Core Code */
    265 #define  SBIDHIGH_CC_SHIFT      4
    266 #define  SBIDHIGH_VC_MASK       0xffff0000 /* Vendor Code */
    267 #define  SBIDHIGH_VC_SHIFT      16
    268 
    269 /* SSB PCI config space registers.  */
    270 #define SSB_PMCSR               0x44
    271 #define  SSB_PE                 0x100
    272 #define SSB_BAR0_WIN            0x80
    273 #define SSB_BAR1_WIN            0x84
    274 #define SSB_SPROM_CONTROL       0x88
    275 #define SSB_BAR1_CONTROL        0x8c
    276 
    277 /* SSB core and host control registers.  */
    278 #define SSB_CONTROL             0x0000UL
    279 #define SSB_ARBCONTROL          0x0010UL
    280 #define SSB_ISTAT               0x0020UL
    281 #define SSB_IMASK               0x0024UL
    282 #define SSB_MBOX                0x0028UL
    283 #define SSB_BCAST_ADDR          0x0050UL
    284 #define SSB_BCAST_DATA          0x0054UL
    285 #define SSB_PCI_TRANS_0         0x0100UL
    286 #define SSB_PCI_TRANS_1         0x0104UL
    287 #define SSB_PCI_TRANS_2         0x0108UL
    288 #define SSB_SPROM               0x0800UL
    289 
    290 #define SSB_PCI_MEM             0x00000000
    291 #define SSB_PCI_IO              0x00000001
    292 #define SSB_PCI_CFG0            0x00000002
    293 #define SSB_PCI_CFG1            0x00000003
    294 #define SSB_PCI_PREF            0x00000004
    295 #define SSB_PCI_BURST           0x00000008
    296 #define SSB_PCI_MASK0           0xfc000000
    297 #define SSB_PCI_MASK1           0xfc000000
    298 #define SSB_PCI_MASK2           0xc0000000
     231#define br32(bp, REG)   ssb_read32((bp)->sdev, (REG))
     232#define bw32(bp, REG, VAL)      ssb_write32((bp)->sdev, (REG), (VAL))
     233#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
    299234
    300235/* 4400 PHY registers */
    301236#define B44_MII_AUXCTRL         24      /* Auxiliary Control */
     
    346281
    347282struct ring_info {
    348283        struct sk_buff          *skb;
    349         DECLARE_PCI_UNMAP_ADDR(mapping);
     284        dma_addr_t      mapping;
    350285};
    351286
    352287#define B44_MCAST_TABLE_SIZE    32
     288#define B44_PHY_ADDR_NO_PHY     30
     289#define B44_MDC_RATIO           5000000
    353290
    354291#define B44_STAT_REG_DECLARE            \
    355292        _B44(tx_good_octets)            \
     
    425362
    426363        u32                     dma_offset;
    427364        u32                     flags;
    428 #define B44_FLAG_B0_ANDLATER    0x00000001
     365#define B44_FLAG_INIT_COMPLETE  0x00000001
    429366#define B44_FLAG_BUGGY_TXPTR    0x00000002
    430367#define B44_FLAG_REORDER_BUG    0x00000004
     368#define B44_FLAG_B0_ANDLATER    0x00000008
    431369#define B44_FLAG_PAUSE_AUTO     0x00008000
    432370#define B44_FLAG_FULL_DUPLEX    0x00010000
    433371#define B44_FLAG_100_BASE_T     0x00020000
     
    452390        struct net_device_stats stats;
    453391        struct b44_hw_stats     hw_stats;
    454392
    455         void __iomem            *regs;
    456         struct pci_dev          *pdev;
     393        struct ssb_device       *sdev;
    457394        struct net_device       *dev;
    458395
    459396        dma_addr_t              rx_ring_dma, tx_ring_dma;
  • drivers/ssb/Kconfig

    diff -Nru linux-2.6.19.ori/drivers/ssb/Kconfig linux-2.6.19/drivers/ssb/Kconfig
    old new  
     1menu "Sonics Silicon Backplane"
     2
     3config SSB
     4        tristate "Sonics Silicon Backplane support"
     5        depends on PCI
     6        help
     7          Support for the Sonics Silicon Backplane bus
     8
     9          The module will be called ssb
     10
     11          If unsure, say m
     12
     13config SSB_SILENT
     14        bool "No SSB kernel messages"
     15        depends on SSB
     16        help
     17          This option turns off all Sonics Silicon Backplane printks.
     18          Note that you won't be able to identify problems, once
     19          messages are turned off.
     20          This might only be desired for production kernels on
     21          embedded devices.
     22
     23          Say n
     24
     25config SSB_DEBUG
     26        bool "SSB debugging"
     27        depends on SSB && !SSB_SILENT
     28        # TODO: Default y for now, but change to n later
     29        default y
     30        help
     31          This turns on additional runtime checks and debugging
     32          messages. Turn this on for SSB troubleshooting.
     33
     34          If unsure, say n
     35
     36config SSB_SERIAL
     37        bool
     38        depends on SSB
     39        # ChipCommon and ExtIf serial support routines.
     40
     41config SSB_DRIVER_EXTIF
     42        bool "SSB Broadcom EXTIF core driver"
     43        help
     44          Driver for the Sonics Silicon Backplane attached
     45          Broadcom EXTIF core
     46
     47          If unsure, say n
     48
     49config SSB_DRIVER_MIPS
     50        bool "SSB Broadcom MIPS core driver"
     51        depends on SSB
     52        select SSB_SERIAL
     53        help
     54          Driver for the Sonics Silicon Backplane attached
     55          Broadcom MIPS core
     56
     57          If unsure, say n
     58
     59endmenu
  • drivers/ssb/Makefile

    diff -Nru linux-2.6.19.ori/drivers/ssb/Makefile linux-2.6.19/drivers/ssb/Makefile
    old new  
     1ssb-drivers-y                           += driver_chipcommon/
     2ssb-drivers-$(CONFIG_SSB_DRIVER_MIPS)   += driver_mips/
     3
     4obj-y += ssb.o $(ssb-drivers-y)
     5
     6ssb-objs := core.o pci.o scan.o
  • drivers/ssb/core.c

    diff -Nru linux-2.6.19.ori/drivers/ssb/core.c linux-2.6.19/drivers/ssb/core.c
    old new  
     1#include "ssb_private.h"
     2
     3#include <linux/delay.h>
     4#include <linux/pci.h>
     5#include <linux/ssb.h>
     6#include <linux/ssb_regs.h>
     7
     8
     9static LIST_HEAD(attach_queue);
     10static LIST_HEAD(buses);
     11static int nr_buses;
     12static DEFINE_SPINLOCK(buses_lock);
     13
     14
     15static struct ssb_device * ssb_device_get(struct ssb_device *dev)
     16{
     17        if (dev)
     18                get_device(&dev->dev);
     19        return dev;
     20}
     21
     22static void ssb_device_put(struct ssb_device *dev)
     23{
     24        if (dev)
     25                put_device(&dev->dev);
     26}
     27
     28static int ssb_device_resume(struct device *dev)
     29{//TODO
     30        return 0;
     31}
     32
     33static int ssb_device_suspend(struct device *dev, pm_message_t state)
     34{//TODO
     35        return 0;
     36}
     37
     38static void ssb_device_shutdown(struct device *dev)
     39{//TODO
     40}
     41
     42static int ssb_device_remove(struct device *dev)
     43{
     44        struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
     45        struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
     46
     47        if (ssb_drv && ssb_drv->remove)
     48                ssb_drv->remove(ssb_dev);
     49        ssb_device_put(ssb_dev);
     50
     51        return 0;
     52}
     53
     54static int ssb_device_probe(struct device *dev)
     55{
     56        struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
     57        struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
     58        int err = 0;
     59
     60        ssb_device_get(ssb_dev);
     61        if (ssb_drv && ssb_drv->probe)
     62                err = ssb_drv->probe(ssb_dev, &ssb_dev->id);
     63        if (!err)
     64                ssb_device_put(ssb_dev);
     65
     66        return err;
     67}
     68
     69static int ssb_match_devid(const struct ssb_device_id *tabid,
     70                           const struct ssb_device_id *devid)
     71{
     72        if ((tabid->vendor != devid->vendor) &&
     73            tabid->vendor != SSB_ANY_VENDOR)
     74                return 0;
     75        if ((tabid->coreid != devid->coreid) &&
     76            tabid->coreid != SSB_ANY_ID)
     77                return 0;
     78        if ((tabid->revision != devid->revision) &&
     79            tabid->revision != SSB_ANY_REV)
     80                return 0;
     81        return 1;
     82}
     83
     84static int ssb_bus_match(struct device *dev, struct device_driver *drv)
     85{
     86        struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
     87        struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv);
     88        const struct ssb_device_id *id;
     89
     90        for (id = ssb_drv->id_table;
     91             id->vendor || id->coreid || id->revision;
     92             id++) {
     93                if (ssb_match_devid(id, &ssb_dev->id))
     94                        return 1; /* found */
     95        }
     96
     97        return 0;
     98}
     99
     100struct bus_type ssb_bustype = {
     101        .name           = NULL, /* Intentionally NULL to indicate early boot */
     102        .match          = ssb_bus_match,
     103        .probe          = ssb_device_probe,
     104        .remove         = ssb_device_remove,
     105        .shutdown       = ssb_device_shutdown,
     106        .suspend        = ssb_device_suspend,
     107        .resume         = ssb_device_resume,
     108};
     109
     110#define is_early_boot()         (ssb_bustype.name == NULL)
     111
     112void ssb_bus_unregister(struct ssb_bus *bus)
     113{//FIXME?
     114        spin_lock(&buses_lock);
     115        list_del(&bus->list);
     116        spin_unlock(&buses_lock);
     117
     118//TODO chipcommon exit
     119        /* Free MMIO */
     120        bus->mapped_device = NULL;
     121        if (bus->bustype == SSB_BUSTYPE_SSB)
     122                iounmap(bus->mmio);
     123        else
     124                pci_iounmap(bus->host_pci, bus->mmio);
     125        bus->mmio = NULL;
     126}
     127EXPORT_SYMBOL_GPL(ssb_bus_unregister);
     128
     129/* Needs buses_lock locked */
     130static int ssb_attach_queued_buses(void)
     131{
     132        struct ssb_bus *bus, *n;
     133        struct ssb_device *dev;
     134        int i, err;
     135
     136ssb_printk("BUSINIT\n");
     137        list_for_each_entry_safe(bus, n, &attach_queue, list) {
     138                for (i = 0; i < bus->nr_devices; i++) {
     139                        dev = &(bus->devices[i]);
     140
     141                        err = device_register(&dev->dev);
     142                        if (err) {
     143                                ssb_printk("Could not register %s\n",
     144                                           dev->dev.bus_id);
     145                        }
     146                }
     147                list_move_tail(&bus->list, &buses);
     148        }
     149ssb_printk("BUS init second stage completed\n");
     150//FIXME dynamic clock somewhere?
     151        return 0;
     152}
     153
     154static int ssb_bus_register(struct ssb_bus *bus,
     155                            unsigned long baseaddr)
     156{
     157        int err;
     158
     159        ssb_printk("Sonics Silicon Backplane bus found at:\n");
     160        if (bus->bustype == SSB_BUSTYPE_PCI)
     161                ssb_printk("PCI device %s\n", bus->host_pci->dev.bus_id);
     162        else
     163                ssb_printk("Address 0x%08lX\n", baseaddr);
     164
     165        spin_lock(&buses_lock);
     166
     167        spin_lock_init(&bus->bar_lock);
     168        INIT_LIST_HEAD(&bus->list);
     169        bus->busnumber = nr_buses;
     170
     171        /* Powerup the bus */
     172        err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
     173        if (err)
     174                goto out;
     175        /* Scan for devices (cores) */
     176        err = ssb_bus_scan(bus, baseaddr);
     177        if (err)
     178                goto err_disable_xtal;
     179
     180        /* Initialize basic system devices (if available) */
     181        ssb_chipcommon_init(&bus->chipco);
     182        ssb_mipscore_init(&bus->mipscore);
     183        //TODO also register drivers for the basic system stuff later?
     184        //     I think the only purpose would be to show them in sysfs.
     185
     186        /* Queue it for attach */
     187        list_add_tail(&bus->list, &attach_queue);
     188        if (!is_early_boot()) {
     189                /* This is not early boot, so we must attach the bus now */
     190                err = ssb_attach_queued_buses();
     191                if (err)
     192                        goto err_dequeue;
     193        }
     194
     195        nr_buses++;
     196out:
     197        spin_unlock(&buses_lock);
     198
     199ssb_printk("busregister %d\n", err);
     200        return err;
     201err_dequeue:
     202        list_del(&bus->list);
     203err_disable_xtal:
     204        ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
     205        goto out;
     206}
     207
     208int ssb_bus_pcibus_register(struct ssb_bus *bus,
     209                            struct pci_dev *host_pci)
     210{
     211        int err;
     212
     213        bus->bustype = SSB_BUSTYPE_PCI;
     214        bus->host_pci = host_pci;
     215
     216        err = ssb_pci_sprom_get(bus);
     217        if (!err)
     218                err = ssb_bus_register(bus, 0);
     219
     220        return err;
     221}
     222EXPORT_SYMBOL_GPL(ssb_bus_pcibus_register);
     223
     224int ssb_bus_ssbbus_register(struct ssb_bus *bus,
     225                            unsigned long baseaddr,
     226                            void (*fill_sprom)(struct ssb_sprom *sprom))
     227{
     228        int err;
     229
     230        bus->bustype = SSB_BUSTYPE_SSB;
     231        fill_sprom(&bus->sprom);
     232        err = ssb_bus_register(bus, baseaddr);
     233
     234        return err;
     235}
     236
     237static inline
     238int do_select_core(struct ssb_bus *bus,
     239                   struct ssb_device *dev,
     240                   u16 *offset)
     241{
     242        int err = 0;
     243
     244        switch (bus->bustype) {
     245        case SSB_BUSTYPE_PCI:
     246                if (unlikely(dev != bus->mapped_device))
     247                        err = ssb_pci_switch_core(bus, dev);
     248                break;
     249        case SSB_BUSTYPE_SSB:
     250                *offset += dev->core_index * SSB_CORE_SIZE;
     251                break;
     252        }
     253
     254        return err;
     255}
     256
     257u16 ssb_read16(struct ssb_device *dev, u16 offset)
     258{
     259        struct ssb_bus *bus = dev->bus;
     260
     261        if (unlikely(do_select_core(bus, dev, &offset)))
     262                return 0xFFFF;
     263        return ssb_raw_read16(bus, offset);
     264}
     265EXPORT_SYMBOL_GPL(ssb_read16);
     266
     267u32 ssb_read32(struct ssb_device *dev, u16 offset)
     268{
     269        struct ssb_bus *bus = dev->bus;
     270
     271        if (unlikely(do_select_core(bus, dev, &offset)))
     272                return 0xFFFFFFFF;
     273        return ssb_raw_read32(bus, offset);
     274}
     275EXPORT_SYMBOL_GPL(ssb_read32);
     276
     277void ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
     278{
     279        struct ssb_bus *bus = dev->bus;
     280
     281        if (unlikely(do_select_core(bus, dev, &offset)))
     282                return;
     283        ssb_raw_write16(bus, offset, value);
     284}
     285EXPORT_SYMBOL_GPL(ssb_write16);
     286
     287void ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
     288{
     289        struct ssb_bus *bus = dev->bus;
     290
     291        if (unlikely(do_select_core(bus, dev, &offset)))
     292                return;
     293        ssb_raw_write32(bus, offset, value);
     294}
     295EXPORT_SYMBOL_GPL(ssb_write32);
     296
     297int __ssb_driver_register(struct ssb_driver *drv, struct module *owner)
     298{
     299        drv->drv.name = drv->name;
     300        drv->drv.bus = &ssb_bustype;
     301        drv->drv.owner = owner;
     302
     303        return driver_register(&drv->drv);
     304}
     305EXPORT_SYMBOL_GPL(__ssb_driver_register);
     306
     307void ssb_driver_unregister(struct ssb_driver *drv)
     308{
     309        driver_unregister(&drv->drv);
     310}
     311EXPORT_SYMBOL_GPL(ssb_driver_unregister);
     312
     313static u32 clkfactor_f6_resolve(u32 v)
     314{
     315        /* map the magic values */
     316        switch (v) {
     317        case SSB_CHIPCO_CLK_F6_2:
     318                return 2;
     319        case SSB_CHIPCO_CLK_F6_3:
     320                return 3;
     321        case SSB_CHIPCO_CLK_F6_4:
     322                return 4;
     323        case SSB_CHIPCO_CLK_F6_5:
     324                return 5;
     325        case SSB_CHIPCO_CLK_F6_6:
     326                return 6;
     327        case SSB_CHIPCO_CLK_F6_7:
     328                return 7;
     329        }
     330        return 0;
     331}
     332
     333/* Calculate the speed the backplane would run at a given set of clockcontrol values */
     334u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m)
     335{
     336        u32 n1, n2, clock, m1, m2, m3, mc;
     337
     338        n1 = (n & SSB_CHIPCO_CLK_N1);
     339        n2 = ((n & SSB_CHIPCO_CLK_N2) >> SSB_CHIPCO_CLK_N2_SHIFT);
     340
     341        switch (plltype) {
     342        case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
     343                if (m & SSB_CHIPCO_CLK_T6_MMASK)
     344                        return SSB_CHIPCO_CLK_T6_M0;
     345                return SSB_CHIPCO_CLK_T6_M1;
     346        case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
     347        case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
     348        case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
     349        case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
     350                n1 = clkfactor_f6_resolve(n1);
     351                n2 += SSB_CHIPCO_CLK_F5_BIAS;
     352                break;
     353        case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */
     354                n1 += SSB_CHIPCO_CLK_T2_BIAS;
     355                n2 += SSB_CHIPCO_CLK_T2_BIAS;
     356                assert((n1 >= 2) && (n1 <= 7));
     357                assert((n2 >= 5) && (n2 <= 23));
     358                break;
     359        case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */
     360                return 100000000;
     361        default:
     362                assert(0);
     363        }
     364
     365        switch (plltype) {
     366        case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
     367        case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
     368                clock = SSB_CHIPCO_CLK_BASE2 * n1 * n2;
     369                break;
     370        default:
     371                clock = SSB_CHIPCO_CLK_BASE1 * n1 * n2;
     372        }
     373        if (!clock)
     374                return 0;
     375
     376        m1 = (m & SSB_CHIPCO_CLK_M1);
     377        m2 = ((m & SSB_CHIPCO_CLK_M2) >> SSB_CHIPCO_CLK_M2_SHIFT);
     378        m3 = ((m & SSB_CHIPCO_CLK_M3) >> SSB_CHIPCO_CLK_M3_SHIFT);
     379        mc = ((m & SSB_CHIPCO_CLK_MC) >> SSB_CHIPCO_CLK_MC_SHIFT);
     380
     381        switch (plltype) {
     382        case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
     383        case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
     384        case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
     385        case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
     386                m1 = clkfactor_f6_resolve(m1);
     387                if ((plltype == SSB_PLLTYPE_1) ||
     388                    (plltype == SSB_PLLTYPE_3))
     389                        m2 += SSB_CHIPCO_CLK_F5_BIAS;
     390                else
     391                        m2 = clkfactor_f6_resolve(m2);
     392                m3 = clkfactor_f6_resolve(m3);
     393
     394                switch (mc) {
     395                case SSB_CHIPCO_CLK_MC_BYPASS:
     396                        return clock;
     397                case SSB_CHIPCO_CLK_MC_M1:
     398                        return (clock / m1);
     399                case SSB_CHIPCO_CLK_MC_M1M2:
     400                        return (clock / (m1 * m2));
     401                case SSB_CHIPCO_CLK_MC_M1M2M3:
     402                        return (clock / (m1 * m2 * m3));
     403                case SSB_CHIPCO_CLK_MC_M1M3:
     404                        return (clock / (m1 * m3));
     405                }
     406                return 0;
     407        case SSB_PLLTYPE_2:
     408                m1 += SSB_CHIPCO_CLK_T2_BIAS;
     409                m2 += SSB_CHIPCO_CLK_T2M2_BIAS;
     410                m3 += SSB_CHIPCO_CLK_T2_BIAS;
     411                assert((m1 >= 2) && (m1 <= 7));
     412                assert((m2 >= 3) && (m2 <= 10));
     413                assert((m3 >= 2) && (m3 <= 7));
     414
     415                if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP))
     416                        clock /= m1;
     417                if (!(mc & SSB_CHIPCO_CLK_T2MC_M2BYP))
     418                        clock /= m2;
     419                if (!(mc & SSB_CHIPCO_CLK_T2MC_M3BYP))
     420                        clock /= m3;
     421                return clock;
     422        default:
     423                assert(0);
     424        }
     425        return 0;
     426}
     427
     428/* Get the current speed the backplane is running at */
     429u32 ssb_clockspeed(struct ssb_bus *bus)
     430{
     431        u32 rate;
     432        u32 plltype;
     433        u32 clkctl_n, clkctl_m;
     434
     435        //TODO if EXTIF: PLLTYPE == 1, read n from clockcontrol_n, m from clockcontrol_sb
     436
     437        if (bus->chipco.dev) {
     438                ssb_chipco_get_clockcontrol(&bus->chipco, &plltype,
     439                                            &clkctl_n, &clkctl_m);
     440        } else
     441                return 0;
     442
     443        if (bus->chip_id == 0x5365) {
     444                rate = 100000000;
     445        } else {
     446                rate = ssb_calc_clock_rate(plltype, clkctl_n, clkctl_m);
     447                if (plltype == SSB_PLLTYPE_3) /* 25Mhz, 2 dividers */
     448                        rate /= 2;
     449        }
     450
     451        return rate;
     452}
     453
     454int ssb_core_is_enabled(struct ssb_device *dev)
     455{
     456        u32 val;
     457
     458        val = ssb_read32(dev, SSB_TMSLOW);
     459        val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT;
     460
     461        return (val == SSB_TMSLOW_CLOCK);
     462}
     463EXPORT_SYMBOL(ssb_core_is_enabled);
     464
     465void ssb_core_enable(struct ssb_device *dev, u32 core_specific_flags)
     466{
     467        u32 val;
     468
     469        ssb_core_disable(dev, core_specific_flags);
     470        ssb_write32(dev, SSB_TMSLOW,
     471                    SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK |
     472                    SSB_TMSLOW_FGC | core_specific_flags);
     473        /* flush */
     474        ssb_read32(dev, SSB_TMSLOW);
     475        udelay(1);
     476
     477        /* Clear SERR if set. This is a hw bug workaround. */
     478        if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR)
     479                ssb_write32(dev, SSB_TMSHIGH, 0);
     480
     481        val = ssb_read32(dev, SSB_IMSTATE);
     482        if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
     483                val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
     484                ssb_write32(dev, SSB_IMSTATE, val);
     485        }
     486
     487        ssb_write32(dev, SSB_TMSLOW,
     488                    SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC |
     489                    core_specific_flags);
     490        /* flush */
     491        ssb_read32(dev, SSB_TMSLOW);
     492        udelay(1);
     493
     494        ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK |
     495                    core_specific_flags);
     496        /* flush */
     497        ssb_read32(dev, SSB_TMSLOW);
     498        udelay(1);
     499}
     500EXPORT_SYMBOL(ssb_core_enable);
     501
     502static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
     503                        int timeout, int set)
     504{
     505        int i;
     506        u32 val;
     507
     508        for (i = 0; i < timeout; i++) {
     509                val = ssb_read32(dev, reg);
     510                if (set) {
     511                        if (val & bitmask)
     512                                return 0;
     513                } else {
     514                        if (!(val & bitmask))
     515                                return 0;
     516                }
     517                udelay(10);
     518        }
     519        printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on "
     520                            "register %04X to %s.\n",
     521               bitmask, reg, (set ? "set" : "clear"));
     522
     523        return -ETIMEDOUT;
     524}
     525
     526void ssb_core_disable(struct ssb_device *dev, u32 core_specific_flags)
     527{
     528        if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
     529                return;
     530
     531        ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_REJECT | SSB_TMSLOW_CLOCK);
     532        ssb_wait_bit(dev, SSB_TMSLOW, SSB_TMSLOW_REJECT, 1000, 1);
     533        ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
     534        ssb_write32(dev, SSB_TMSLOW,
     535                    SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
     536                    SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET |
     537                    core_specific_flags);
     538        /* flush */
     539        ssb_read32(dev, SSB_TMSLOW);
     540        udelay(1);
     541
     542        ssb_write32(dev, SSB_TMSLOW,
     543                    SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET |
     544                    core_specific_flags);
     545        /* flush */
     546        ssb_read32(dev, SSB_TMSLOW);
     547        udelay(1);
     548}
     549EXPORT_SYMBOL(ssb_core_disable);
     550
     551int __ssb_printk(const char *fmt, ...)
     552{
     553        va_list args;
     554        int res;
     555
     556        va_start(args, fmt);
     557#ifdef CONFIG_CFE
     558        if (is_early_boot() && cfe_present()) {
     559                res = cfe_vprintk(fmt, args);
     560        } else
     561#endif
     562        {
     563                printk(KERN_INFO);
     564                res = vprintk(fmt, args);
     565        }
     566        va_end(args);
     567
     568        return res;
     569}
     570
     571
     572static int ssb_modinit(void)
     573{
     574        int err;
     575
     576        ssb_bustype.name = "ssb";
     577        err = bus_register(&ssb_bustype);
     578        if (err)
     579                return err;
     580
     581        /* Maybe we already registered some buses at early boot.
     582         * Check for this and attach them
     583         */
     584        spin_lock(&buses_lock);
     585        err = ssb_attach_queued_buses();
     586        spin_unlock(&buses_lock);
     587
     588        return err;
     589}
     590subsys_initcall(ssb_modinit);
     591
     592static void __exit ssb_modexit(void)
     593{
     594        bus_unregister(&ssb_bustype);
     595}
     596module_exit(ssb_modexit)
  • drivers/ssb/driver_chipcommon/Makefile

    diff -Nru linux-2.6.19.ori/drivers/ssb/driver_chipcommon/Makefile linux-2.6.19/drivers/ssb/driver_chipcommon/Makefile
    old new  
     1obj-y += chipcommon.o
  • drivers/ssb/driver_chipcommon/chipcommon.c

    diff -Nru linux-2.6.19.ori/drivers/ssb/driver_chipcommon/chipcommon.c linux-2.6.19/drivers/ssb/driver_chipcommon/chipcommon.c
    old new  
     1#include <linux/ssb.h>
     2#include <linux/ssb_regs.h>
     3
     4#include "../ssb_private.h"
     5
     6
     7static inline u32 chipco_read32(struct ssb_chipcommon *cc,
     8                                u16 offset)
     9{
     10        return ssb_read32(cc->dev, offset);
     11}
     12
     13static inline void chipco_write32(struct ssb_chipcommon *cc,
     14                                  u16 offset,
     15                                  u32 value)
     16{
     17        ssb_write32(cc->dev, offset, value);
     18}
     19
     20static void ssb_clock(struct ssb_chipcommon *cc, enum ssb_clkmode mode)
     21{
     22        struct ssb_device *ccdev = cc->dev;
     23        struct ssb_bus *bus;
     24        u32 tmp;
     25
     26        if (!ccdev)
     27                return;
     28        bus = ccdev->bus;
     29        /* chipcommon cores prior to rev6 don't support dynamic clock control */
     30        if (ccdev->id.revision < 6)
     31                return;
     32        /* chipcommon cores rev10 are a whole new ball game */
     33        if (ccdev->id.revision >= 10)
     34                return;
     35        if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
     36                return;
     37
     38        switch (mode) {
     39        case SSB_CLKMODE_SLOW:
     40                tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
     41                tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
     42                chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
     43                break;
     44        case SSB_CLKMODE_FAST:
     45                ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
     46                tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
     47                tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
     48                tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
     49                chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
     50                break;
     51        case SSB_CLKMODE_DYNAMIC:
     52                tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
     53                tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
     54                tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
     55                tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
     56                if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
     57                        tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
     58                chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
     59
     60                /* for dynamic control, we have to release our xtal_pu "force on" */
     61                if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
     62                        ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
     63                break;
     64        default:
     65                assert(0);
     66        }
     67}
     68
     69void ssb_chipcommon_init(struct ssb_chipcommon *cc)
     70{
     71        if (!cc->dev)
     72                return; /* We don't have a ChipCommon */
     73        ssb_dprintk("Initializing Chipcommon...\n");
     74        ssb_clock(cc, SSB_CLKMODE_FAST);
     75}
     76
     77void ssb_chipcommon_exit(struct ssb_chipcommon *cc)
     78{
     79        //TODO
     80}
     81
     82void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
     83                                 u32 *plltype, u32 *n, u32 *m)
     84{
     85        *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
     86        *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
     87        switch (*plltype) {
     88        case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
     89                *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
     90                break;
     91        case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
     92                if (cc->dev->bus->chip_id != 0x5365) {
     93                        *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
     94                        break;
     95                }
     96                /* Fallthough */
     97        default:
     98                *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
     99        }
     100}
     101
     102void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
     103                            unsigned long ns)
     104{
     105        struct ssb_device *dev = cc->dev;
     106        struct ssb_bus *bus = dev->bus;
     107        u32 tmp;
     108
     109        /* set register for external IO to control LED. */
     110        chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);
     111        tmp = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT;         /* Waitcount-3 = 10ns */
     112        tmp |= ceildiv(40, ns) << SSB_PROG_WCNT_1_SHIFT;        /* Waitcount-1 = 40ns */
     113        tmp |= ceildiv(240, ns);                                /* Waitcount-0 = 240ns */
     114        chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp);       /* 0x01020a0c for a 100Mhz clock */
     115
     116        /* Set timing for the flash */
     117        tmp = ceildiv(10, ns) << SSB_FLASH_WCNT_3_SHIFT;        /* Waitcount-3 = 10nS */
     118        tmp |= ceildiv(10, ns) << SSB_FLASH_WCNT_1_SHIFT;       /* Waitcount-1 = 10nS */
     119        tmp |= ceildiv(120, ns);                                /* Waitcount-0 = 120nS */
     120        if ((bus->chip_id == 0x5365) ||
     121            (dev->id.revision < 9))
     122                chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);
     123        if ((bus->chip_id == 0x5365) ||
     124            (dev->id.revision < 9) ||
     125            ((bus->chip_id == 0x5350) && (bus->chip_rev == 0)))
     126                chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp);
     127
     128        if (bus->chip_id == 0x5350) {
     129                /* Enable EXTIF */
     130                tmp = ceildiv(10, ns) << SSB_PROG_WCNT_3_SHIFT;   /* Waitcount-3 = 10ns */
     131                tmp |= ceildiv(20, ns) << SSB_PROG_WCNT_2_SHIFT;  /* Waitcount-2 = 20ns */
     132                tmp |= ceildiv(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */
     133                tmp |= ceildiv(120, ns);                          /* Waitcount-0 = 120ns */
     134                chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
     135        }
     136}
     137
     138
     139#ifdef CONFIG_SSB_SERIAL
     140int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
     141                           struct ssb_serial_port *ports)
     142{
     143        struct ssb_bus *bus = cc->dev->bus;
     144        int nr_ports = 0;
     145        u32 plltype;
     146        unsigned int irq;
     147        u32 baud_base, div;
     148        u32 i, n;
     149
     150        plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
     151        irq = ssb_mips_irq(cc->dev);
     152
     153        if (plltype == SSB_PLLTYPE_1) {
     154                /* PLL clock */
     155                baud_base = ssb_calc_clock_rate(plltype,
     156                                                chipco_read32(cc, SSB_CHIPCO_CLOCK_N),
     157                                                chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));
     158                div = 1;
     159        } else {
     160                if (cc->dev->id.revision >= 11) {
     161                        /* Fixed ALP clock */
     162                        baud_base = 20000000;
     163                        div = 1;
     164                        /* Set the override bit so we don't divide it */
     165                        chipco_write32(cc, SSB_CHIPCO_CORECTL,
     166                                       SSB_CHIPCO_CORECTL_UARTCLK0);
     167                } else if (cc->dev->id.revision >= 3) {
     168                        /* Internal backplane clock */
     169                        baud_base = ssb_clockspeed(bus);
     170                        div = 2; /* Minimum divisor */
     171                        chipco_write32(cc, SSB_CHIPCO_CLKDIV,
     172                                       (chipco_read32(cc, SSB_CHIPCO_CLKDIV)
     173                                        & ~SSB_CHIPCO_CLKDIV_UART) | div);
     174                } else {
     175                        /* Fixed internal backplane clock */
     176                        baud_base = 88000000;
     177                        div = 48;
     178                }
     179
     180                /* Clock source depends on strapping if UartClkOverride is unset */
     181                if ((cc->dev->id.revision > 0) &&
     182                    !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {
     183                        if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==
     184                            SSB_CHIPCO_CAP_UARTCLK_INT) {
     185                                /* Internal divided backplane clock */
     186                                baud_base /= div;
     187                        } else {
     188                                /* Assume external clock of 1.8432 MHz */
     189                                baud_base = 1843200;
     190                        }
     191                }
     192        }
     193
     194        /* Determine the registers of the UARTs */
     195        n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART);
     196        for (i = 0; i < n; i++) {
     197                void __iomem *cc_mmio;
     198                void __iomem *uart_regs;
     199               
     200                cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);
     201                uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;
     202                /* Offset changed at after rev 0 */
     203                if (cc->dev->id.revision == 0)
     204                        uart_regs += (i * 8);
     205                else
     206                        uart_regs += (i * 256);
     207
     208                nr_ports++;
     209                ports[i].regs = uart_regs;
     210                ports[i].irq = irq;
     211                ports[i].baud_base = baud_base;
     212                ports[i].reg_shift = 0;
     213        }
     214
     215        return nr_ports;
     216}
     217#endif /* CONFIG_SSB_SERIAL */
  • drivers/ssb/driver_mips/Makefile

    diff -Nru linux-2.6.19.ori/drivers/ssb/driver_mips/Makefile linux-2.6.19/drivers/ssb/driver_mips/Makefile
    old new  
     1obj-y += mips.o
  • drivers/ssb/driver_mips/mips.c

    diff -Nru linux-2.6.19.ori/drivers/ssb/driver_mips/mips.c linux-2.6.19/drivers/ssb/driver_mips/mips.c
    old new  
     1#include <linux/ssb.h>
     2
     3#include <linux/serial.h>
     4#include <linux/serial_core.h>
     5#include <linux/serial_reg.h>
     6#include <asm/time.h>
     7
     8#include "../ssb_private.h"
     9
     10
     11static inline u32 mips_read32(struct ssb_mipscore *mcore,
     12                              u16 offset)
     13{
     14        return ssb_read32(mcore->dev, offset);
     15}
     16
     17static inline void mips_write32(struct ssb_mipscore *mcore,
     18                                u16 offset,
     19                                u32 value)
     20{
     21        ssb_write32(mcore->dev, offset, value);
     22}
     23
     24static const u32 ipsflag_irq_mask[] = {
     25        0,
     26        SSB_IPSFLAG_IRQ1,
     27        SSB_IPSFLAG_IRQ2,
     28        SSB_IPSFLAG_IRQ3,
     29        SSB_IPSFLAG_IRQ4,
     30};
     31
     32static const u32 ipsflag_irq_shift[] = {
     33        0,
     34        SSB_IPSFLAG_IRQ1_SHIFT,
     35        SSB_IPSFLAG_IRQ2_SHIFT,
     36        SSB_IPSFLAG_IRQ3_SHIFT,
     37        SSB_IPSFLAG_IRQ4_SHIFT,
     38};
     39
     40static inline u32 ssb_irqflag(struct ssb_device *dev)
     41{
     42        return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
     43}
     44
     45/* Get the MIPS IRQ assignment for a specified device.
     46 * If unassigned, 0 is returned.
     47 */
     48unsigned int ssb_mips_irq(struct ssb_device *dev)
     49{
     50        struct ssb_bus *bus = dev->bus;
     51        u32 irqflag;
     52        u32 ipsflag;
     53        u32 tmp;
     54        unsigned int irq;
     55
     56        irqflag = ssb_irqflag(dev);
     57        ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG);
     58        for (irq = 1; irq <= 4; irq++) {
     59                tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]);
     60                if (tmp == irqflag)
     61                        break;
     62        }
     63        if (irq == 5)
     64                irq = 0;
     65
     66        return irq;
     67}
     68
     69static void clear_irq(struct ssb_bus *bus, unsigned int irq)
     70{
     71        struct ssb_device *dev = bus->mipscore.dev;
     72
     73        /* Clear the IRQ in the MIPScore backplane registers */
     74        if (irq == 0) {
     75                ssb_write32(dev, SSB_INTVEC, 0);
     76        } else {
     77                ssb_write32(dev, SSB_IPSFLAG,
     78                            ssb_read32(dev, SSB_IPSFLAG) |
     79                            ipsflag_irq_mask[irq]);
     80        }
     81}
     82
     83static void set_irq(struct ssb_device *dev, unsigned int irq)
     84{
     85        unsigned int oldirq = ssb_mips_irq(dev);
     86        struct ssb_bus *bus = dev->bus;
     87        struct ssb_device *mdev = bus->mipscore.dev;
     88        u32 irqflag = ssb_irqflag(dev);
     89
     90        dev->irq = irq + 2;
     91       
     92        ssb_dprintk("set_irq: core 0x%04x, irq %d => %d\n", dev->id.coreid, oldirq, irq);
     93        /* clear the old irq */
     94        if (oldirq == 0)
     95                ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
     96        else
     97                clear_irq(bus, oldirq);
     98
     99        /* assign the new one */
     100        if (irq == 0)
     101                ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
     102       
     103        irqflag <<= ipsflag_irq_shift[irq];
     104        irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]);
     105        ssb_write32(mdev, SSB_IPSFLAG, irqflag);
     106}
     107
     108
     109static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
     110{
     111        struct ssb_bus *bus = mcore->dev->bus;
     112
     113        //TODO if (EXTIF available
     114#if 0
     115                extifregs_t *eir = (extifregs_t *) regs;
     116                sbconfig_t *sb;
     117
     118                /* Determine external UART register base */
     119                sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
     120                base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1)));
     121
     122                /* Determine IRQ */
     123                irq = sb_irq(sbh);
     124
     125                /* Disable GPIO interrupt initially */
     126                W_REG(&eir->gpiointpolarity, 0);
     127                W_REG(&eir->gpiointmask, 0);
     128
     129                /* Search for external UARTs */
     130                n = 2;
     131                for (i = 0; i < 2; i++) {
     132                        regs = (void *) REG_MAP(base + (i * 8), 8);
     133                        if (BCMINIT(serial_exists)(regs)) {
     134                                /* Set GPIO 1 to be the external UART IRQ */
     135                                W_REG(&eir->gpiointmask, 2);
     136                                if (add)
     137                                        add(regs, irq, 13500000, 0);
     138                        }
     139                }
     140
     141                /* Add internal UART if enabled */
     142                if (R_REG(&eir->corecontrol) & CC_UE)
     143                        if (add)
     144                                add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
     145
     146#endif
     147        if (bus->chipco.dev)
     148                mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
     149        else
     150                mcore->nr_serial_ports = 0;
     151}
     152
     153static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
     154{
     155        struct ssb_bus *bus = mcore->dev->bus;
     156
     157        if (bus->chipco.dev) {
     158                mcore->flash_window = 0x1c000000;
     159                mcore->flash_window_size = 0x800000;
     160        } else {
     161                mcore->flash_window = 0x1fc00000;
     162                mcore->flash_window_size = 0x400000;
     163        }
     164}
     165
     166void ssb_mipscore_init(struct ssb_mipscore *mcore)
     167{
     168        struct ssb_bus *bus = mcore->dev->bus;
     169        struct ssb_device *dev;
     170        unsigned long hz, ns;
     171        unsigned int irq, i;
     172
     173        if (!mcore->dev)
     174                return; /* We don't have a MIPS core */
     175
     176        ssb_dprintk("Initializing MIPS core...\n");
     177
     178        hz = ssb_clockspeed(bus);
     179        if (!hz)
     180                hz = 100000000;
     181        ns = 1000000000 / hz;
     182
     183//TODO
     184#if 0
     185        if (have EXTIF) {
     186                /* Initialize extif so we can get to the LEDs and external UART */
     187                W_REG(&eir->prog_config, CF_EN);
     188
     189                /* Set timing for the flash */
     190                tmp = CEIL(10, ns) << FW_W3_SHIFT;      /* W3 = 10nS */
     191                tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
     192                tmp = tmp | CEIL(120, ns);              /* W0 = 120nS */
     193                W_REG(&eir->prog_waitcount, tmp);       /* 0x01020a0c for a 100Mhz clock */
     194
     195                /* Set programmable interface timing for external uart */
     196                tmp = CEIL(10, ns) << FW_W3_SHIFT;      /* W3 = 10nS */
     197                tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
     198                tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
     199                tmp = tmp | CEIL(120, ns);              /* W0 = 120nS */
     200                W_REG(&eir->prog_waitcount, tmp);
     201        }
     202        else... chipcommon
     203#endif
     204        if (bus->chipco.dev)
     205                ssb_chipco_timing_init(&bus->chipco, ns);
     206
     207        /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
     208        for (irq = 2, i = 0; i < bus->nr_devices; i++) {
     209                dev = &(bus->devices[i]);
     210                dev->irq = ssb_mips_irq(dev) + 2;
     211                switch(dev->id.coreid) {
     212                        case SSB_DEV_USB11_HOST:
     213                                /* shouldn't need a separate irq line for non-4710, most of them have a proper
     214                                 * external usb controller on the pci */
     215                                if ((bus->chip_id == 0x4710) && (irq <= 4)) {
     216                                        set_irq(dev, irq++);
     217                                        break;
     218                                }
     219                        case SSB_DEV_PCI:
     220                        case SSB_DEV_ETHERNET:
     221                        case SSB_DEV_80211:
     222                        case SSB_DEV_USB20_HOST:
     223                                /* These devices get their own IRQ line if available, the rest goes on IRQ0 */
     224                                if (irq <= 4) {
     225                                        set_irq(dev, irq++);
     226                                        break;
     227                                }
     228                }
     229        }
     230
     231        ssb_mips_serial_init(mcore);
     232        ssb_mips_flash_detect(mcore);
     233}
  • drivers/ssb/pci.c

    diff -Nru linux-2.6.19.ori/drivers/ssb/pci.c linux-2.6.19/drivers/ssb/pci.c
    old new  
     1/*
     2 * Sonics Silicon Backplane PCI-Hostbus related functions.
     3 *
     4 * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
     5 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
     6 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
     7 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
     8 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
     9 *
     10 * Derived from the Broadcom 4400 device driver.
     11 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
     12 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
     13 * Copyright (C) 2006 Broadcom Corporation.
     14 *
     15 * Licensed under the GNU/GPL. See COPYING for details.
     16 */
     17
     18#include <linux/ssb.h>
     19#include <linux/ssb_regs.h>
     20#include <linux/pci.h>
     21#include <linux/delay.h>
     22
     23#include "ssb_private.h"
     24
     25
     26int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
     27{
     28        int err;
     29        int attempts = 0;
     30        u32 cur_core;
     31
     32        while (1) {
     33                err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
     34                                             (coreidx * SSB_CORE_SIZE)
     35                                             + SSB_ENUM_BASE);
     36                if (err)
     37                        goto error;
     38                err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
     39                                            &cur_core);
     40                if (err)
     41                        goto error;
     42                cur_core = (cur_core - SSB_ENUM_BASE)
     43                           / SSB_CORE_SIZE;
     44                if (cur_core == coreidx)
     45                        break;
     46
     47                if (attempts++ > SSB_BAR0_MAX_RETRIES)
     48                        goto error;
     49                udelay(10);
     50        }
     51        return 0;
     52error:
     53        printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
     54        return -ENODEV;
     55}
     56
     57int ssb_pci_switch_core(struct ssb_bus *bus,
     58                        struct ssb_device *dev)
     59{
     60        int err;
     61        unsigned long flags;
     62
     63        ssb_dprintk("Switching to core %d\n",
     64                    dev->core_index);
     65
     66        spin_lock_irqsave(&bus->bar_lock, flags);
     67        err = ssb_pci_switch_coreidx(bus, dev->core_index);
     68        if (!err)
     69                bus->mapped_device = dev;
     70        spin_unlock_irqrestore(&bus->bar_lock, flags);
     71
     72        return err;
     73}
     74
     75int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
     76{
     77        int err;
     78        u32 in, out, outenable;
     79
     80        if (bus->bustype != SSB_BUSTYPE_PCI)
     81                return 0;
     82
     83        err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
     84        if (err)
     85                goto err_pci;
     86        err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
     87        if (err)
     88                goto err_pci;
     89        err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
     90        if (err)
     91                goto err_pci;
     92
     93        outenable |= what;
     94
     95        if (turn_on) {
     96                /* Avoid glitching the clock if GPRS is already using it.
     97                 * We can't actually read the state of the PLLPD so we infer it
     98                 * by the value of XTAL_PU which *is* readable via gpioin.
     99                 */
     100                if (in & SSB_GPIO_XTAL)
     101                        return 0;
     102
     103                if (what & SSB_GPIO_XTAL) {
     104                        /* Turn the crystal on */
     105                        out |= SSB_GPIO_XTAL;
     106                        if (what & SSB_GPIO_PLL)
     107                                out |= SSB_GPIO_PLL;
     108                        err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
     109                        if (err)
     110                                goto err_pci;
     111                        err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
     112                                                     outenable);
     113                        if (err)
     114                                goto err_pci;
     115                        msleep(1);
     116                }
     117                if (what & SSB_GPIO_PLL) {
     118                        /* Turn the PLL on */
     119                        out &= ~SSB_GPIO_PLL;
     120                        err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
     121                        if (err)
     122                                goto err_pci;
     123                        msleep(2);
     124                }
     125        } else {
     126                if (what & SSB_GPIO_XTAL) {
     127                        /* Turn the crystal off */
     128                        out &= ~SSB_GPIO_XTAL;
     129                }
     130                if (what & SSB_GPIO_PLL) {
     131                        /* Turn the PLL off */
     132                        out |= SSB_GPIO_PLL;
     133                }
     134                err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
     135                if (err)
     136                        goto err_pci;
     137                err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
     138                if (err)
     139                        goto err_pci;
     140        }
     141
     142out:
     143        return err;
     144
     145err_pci:
     146        printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n");
     147        err = -EBUSY;
     148        goto out;
     149}
     150
     151#define SPOFF(offset)   (((offset) - SSB_SPROM_BASE) / sizeof(u16))
     152#define SPEX(_outvar, _offset, _mask, _shift)   \
     153        out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
     154
     155static inline u8 ssb_crc8(u8 crc, u8 data)
     156{
     157        /* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
     158        static const u8 t[] = {
     159                0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
     160                0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
     161                0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
     162                0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
     163                0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
     164                0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
     165                0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
     166                0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
     167                0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
     168                0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
     169                0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
     170                0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
     171                0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
     172                0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
     173                0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
     174                0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
     175                0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
     176                0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
     177                0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
     178                0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
     179                0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
     180                0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
     181                0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
     182                0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
     183                0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
     184                0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
     185                0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
     186                0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
     187                0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
     188                0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
     189                0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
     190                0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
     191        };
     192        return t[crc ^ data];
     193}
     194
     195static u8 ssb_sprom_crc(const u16 *sprom)
     196{
     197        int word;
     198        u8 crc = 0xFF;
     199
     200        for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) {
     201                crc = ssb_crc8(crc, sprom[word] & 0x00FF);
     202                crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
     203        }
     204        crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF);
     205        crc ^= 0xFF;
     206
     207        return crc;
     208}
     209
     210static int sprom_check_crc(const u16 *sprom)
     211{
     212        u8 crc;
     213        u8 expected_crc;
     214        u16 tmp;
     215
     216        crc = ssb_sprom_crc(sprom);
     217        tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC;
     218        expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
     219        if (crc != expected_crc)
     220                return -EPROTO;
     221
     222        return 0;
     223}
     224
     225static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
     226{
     227        int i;
     228
     229        for (i = 0; i < SSB_SPROMSIZE_WORDS; i++)
     230                sprom[i] = ssb_raw_read16(bus, SSB_SPROM_BASE + (i * 2));
     231}
     232
     233static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
     234{
     235        int i;
     236        u16 v;
     237
     238        SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0);
     239        SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0);
     240        SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0);
     241        for (i = 0; i < 3; i++) {
     242                v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
     243                *(((u16 *)out->il0mac) + i) = cpu_to_be16(v);
     244        }
     245        for (i = 0; i < 3; i++) {
     246                v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
     247                *(((u16 *)out->et0mac) + i) = cpu_to_be16(v);
     248        }
     249        for (i = 0; i < 3; i++) {
     250                v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
     251                *(((u16 *)out->et1mac) + i) = cpu_to_be16(v);
     252        }
     253        SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
     254        SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
     255             SSB_SPROM1_ETHPHY_ET1A_SHIFT);
     256        SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
     257        SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
     258        SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
     259        SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
     260             SSB_SPROM1_BINF_CCODE_SHIFT);
     261        SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
     262             SSB_SPROM1_BINF_ANTA_SHIFT);
     263        SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
     264             SSB_SPROM1_BINF_ANTBG_SHIFT);
     265        SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
     266        SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
     267        SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
     268        SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
     269        SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
     270        SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
     271        SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
     272        SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
     273             SSB_SPROM1_GPIOA_P1_SHIFT);
     274        SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
     275        SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
     276             SSB_SPROM1_GPIOB_P3_SHIFT);
     277        SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A, 0);
     278        SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG,
     279             SSB_SPROM1_MAXPWR_BG_SHIFT);
     280        SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A, 0);
     281        SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG,
     282             SSB_SPROM1_ITSSI_BG_SHIFT);
     283        SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
     284        SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
     285        SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
     286             SSB_SPROM1_AGAIN_BG_SHIFT);
     287        for (i = 0; i < 4; i++) {
     288                v = in[SPOFF(SSB_SPROM1_OEM) + i];
     289                *(((u16 *)out->oem) + i) = cpu_to_le16(v);
     290        }
     291}
     292
     293static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in)
     294{
     295        int i;
     296        u16 v;
     297
     298        SPEX(boardflags_hi, SSB_SPROM2_BFLHI,  0xFFFF, 0);
     299        SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
     300        SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
     301             SSB_SPROM2_MAXP_A_LO_SHIFT);
     302        SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
     303        SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
     304        SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
     305        SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
     306        SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
     307        SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
     308        SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
     309        for (i = 0; i < 4; i++) {
     310                v = in[SPOFF(SSB_SPROM2_CCODE) + i];
     311                *(((u16 *)out->country_str) + i) = cpu_to_le16(v);
     312        }
     313}
     314
     315static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in)
     316{
     317        out->ofdmapo  = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8;
     318        out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8;
     319        out->ofdmapo <<= 16;
     320        out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8;
     321        out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8;
     322
     323        out->ofdmalpo  = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8;
     324        out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8;
     325        out->ofdmalpo <<= 16;
     326        out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8;
     327        out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8;
     328
     329        out->ofdmahpo  = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8;
     330        out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8;
     331        out->ofdmahpo <<= 16;
     332        out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8;
     333        out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8;
     334
     335        SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON,
     336             SSB_SPROM3_GPIOLDC_ON_SHIFT);
     337        SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF,
     338             SSB_SPROM3_GPIOLDC_OFF_SHIFT);
     339        SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0);
     340        SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M,
     341             SSB_SPROM3_CCKPO_2M_SHIFT);
     342        SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M,
     343             SSB_SPROM3_CCKPO_55M_SHIFT);
     344        SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M,
     345             SSB_SPROM3_CCKPO_11M_SHIFT);
     346
     347        out->ofdmgpo  = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8;
     348        out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8;
     349        out->ofdmgpo <<= 16;
     350        out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8;
     351        out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
     352}
     353
     354static int sprom_extract(struct ssb_sprom *out, const u16 *in)
     355{
     356        memset(out, 0, sizeof(*out));
     357
     358        SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0);
     359        SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
     360             SSB_SPROM_REVISION_CRC_SHIFT);
     361
     362        if (out->revision == 0)
     363                goto err_unsup;
     364        if (out->revision >= 1 && out->revision <= 3)
     365                sprom_extract_r1(&out->r1, in);
     366        if (out->revision >= 2 && out->revision <= 3)
     367                sprom_extract_r2(&out->r2, in);
     368        if (out->revision == 3)
     369                sprom_extract_r3(&out->r3, in);
     370        if (out->revision >= 4)
     371                goto err_unsup;
     372       
     373        return 0;
     374err_unsup:
     375        ssb_printk("ERROR: Unsupported SPROM revision %d\n",
     376                   out->revision);
     377        return -EOPNOTSUPP;
     378}
     379
     380int ssb_pci_sprom_get(struct ssb_bus *bus)
     381{
     382        int err = -ENOMEM;
     383        u16 *buf;
     384
     385        assert(bus->bustype == SSB_BUSTYPE_PCI);
     386
     387        buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
     388        if (!buf)
     389                goto out;
     390        sprom_do_read(bus, buf);
     391        err = sprom_check_crc(buf);
     392        if (err)
     393                ssb_printk("WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
     394        err = sprom_extract(&bus->sprom, buf);
     395
     396        kfree(buf);
     397out:
     398        return err;
     399}
  • drivers/ssb/scan.c

    diff -Nru linux-2.6.19.ori/drivers/ssb/scan.c linux-2.6.19/drivers/ssb/scan.c
    old new  
     1#include <linux/ssb.h>
     2#include <linux/ssb_regs.h>
     3#include <linux/pci.h>
     4#include <asm/io.h>
     5
     6#include "ssb_private.h"
     7
     8
     9static const char * ssb_core_name(u16 coreid)
     10{
     11        switch (coreid) {
     12        case SSB_DEV_CHIPCOMMON:
     13                return "ChipCommon";
     14        case SSB_DEV_ILINE20:
     15                return "ILine 20";
     16        case SSB_DEV_SDRAM:
     17                return "SDRAM";
     18        case SSB_DEV_PCI:
     19                return "PCI";
     20        case SSB_DEV_MIPS:
     21                return "MIPS";
     22        case SSB_DEV_ETHERNET:
     23                return "Fast Ethernet";
     24        case SSB_DEV_V90:
     25                return "V90";
     26        case SSB_DEV_USB11_HOSTDEV:
     27                return "USB 1.1 Hostdev";
     28        case SSB_DEV_ADSL:
     29                return "ADSL";
     30        case SSB_DEV_ILINE100:
     31                return "ILine 100";
     32        case SSB_DEV_IPSEC:
     33                return "IPSEC";
     34        case SSB_DEV_PCMCIA:
     35                return "PCMCIA";
     36        case SSB_DEV_INTERNAL_MEM:
     37                return "Internal Memory";
     38        case SSB_DEV_MEMC_SDRAM:
     39                return "MEMC SDRAM";
     40        case SSB_DEV_EXTIF:
     41                return "EXTIF";
     42        case SSB_DEV_80211:
     43                return "IEEE 802.11";
     44        case SSB_DEV_MIPS_3302:
     45                return "MIPS 3302";
     46        case SSB_DEV_USB11_HOST:
     47                return "USB 1.1 Host";
     48        case SSB_DEV_USB11_DEV:
     49                return "USB 1.1 Device";
     50        case SSB_DEV_USB20_HOST:
     51                return "USB 2.0 Host";
     52        case SSB_DEV_USB20_DEV:
     53                return "USB 2.0 Device";
     54        case SSB_DEV_SDIO_HOST:
     55                return "SDIO Host";
     56        case SSB_DEV_ROBOSWITCH:
     57                return "Roboswitch";
     58        case SSB_DEV_PARA_ATA:
     59                return "PATA";
     60        case SSB_DEV_SATA_XORDMA:
     61                return "SATA XOR-DMA";
     62        case SSB_DEV_ETHERNET_GBIT:
     63                return "GBit Ethernet";
     64        case SSB_DEV_PCIE:
     65                return "PCI-E";
     66        case SSB_DEV_MIMO_PHY:
     67                return "MIMO PHY";
     68        case SSB_DEV_SRAM_CTRLR:
     69                return "SRAM Controller";
     70        case SSB_DEV_MINI_MACPHY:
     71                return "Mini MACPHY";
     72        case SSB_DEV_ARM_1176:
     73                return "ARM 1176";
     74        case SSB_DEV_ARM_7TDMI:
     75                return "ARM 7TDMI";
     76        }
     77        return "Unknown CoreID";
     78}
     79
     80static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
     81{
     82        u16 chipid_fallback = 0;
     83
     84        switch (pci_dev->device) {
     85        case 0x4301:
     86                chipid_fallback = 0x4301;
     87                break;
     88        case 0x4305 ... 0x4307:
     89                chipid_fallback = 0x4307;
     90                break;
     91        case 0x4402 ... 0x4403:
     92                chipid_fallback = 0x4402;
     93                break;
     94        case 0x4610 ... 0x4615:
     95                chipid_fallback = 0x4610;
     96                break;
     97        case 0x4710 ... 0x4715:
     98                chipid_fallback = 0x4710;
     99                break;
     100        case 0x4320 ... 0x4325:
     101                chipid_fallback = 0x4309;
     102                break;
     103        default:
     104                ssb_printk("PCI-ID not in fallback list\n");
     105        }
     106
     107        return chipid_fallback;
     108}
     109
     110static u8 chipid_to_nrcores(u16 chipid)
     111{
     112        switch (chipid) {
     113        case 0x5365:
     114                return 7;
     115        case 0x4306:
     116                return 6;
     117        case 0x4310:
     118                return 8;
     119        case 0x4307:
     120        case 0x4301:
     121                return 5;
     122        case 0x4402:
     123                return 3;
     124        case 0x4710:
     125        case 0x4610:
     126        case 0x4704:
     127                return 9;
     128        default:
     129                ssb_printk("CHIPID not found in nrcores fallback list\n");
     130        }
     131        return 1;
     132}
     133
     134static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
     135                       u16 offset)
     136{
     137        if (bus->bustype == SSB_BUSTYPE_SSB)
     138                offset += current_coreidx * SSB_CORE_SIZE;
     139        return ssb_raw_read32(bus, offset);
     140}
     141
     142static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
     143{
     144        switch (bus->bustype) {
     145        case SSB_BUSTYPE_SSB:
     146                break;
     147        case SSB_BUSTYPE_PCI:
     148                return ssb_pci_switch_coreidx(bus, coreidx);
     149        default:
     150                assert(0);
     151        }
     152        return 0;
     153}
     154
     155int ssb_bus_scan(struct ssb_bus *bus,
     156                 unsigned long baseaddr)
     157{
     158        int err = -ENOMEM;
     159        void __iomem *mmio;
     160        u32 idhi, cc, rev, tmp;
     161        int i;
     162        struct ssb_device *dev;
     163
     164        if (bus->bustype == SSB_BUSTYPE_SSB) {
     165                /* Only map the first core for now. */
     166                mmio = ioremap(baseaddr, SSB_CORE_SIZE);
     167        } else {
     168                assert(bus->host_pci);
     169                mmio = pci_iomap(bus->host_pci, 0, ~0UL);
     170        }
     171        if (!mmio)
     172                goto out;
     173        bus->mmio = mmio;
     174
     175        err = scan_switchcore(bus, 0); /* Switch to first core */
     176        if (err)
     177                goto err_unmap;
     178
     179        idhi = scan_read32(bus, 0, SSB_IDHIGH);
     180        cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
     181        rev = (idhi & SSB_IDHIGH_RCLO);
     182        rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
     183
     184        bus->nr_devices = 0;
     185        if (cc == SSB_DEV_CHIPCOMMON) {
     186                tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
     187
     188                bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
     189                bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
     190                                SSB_CHIPCO_REVSHIFT;
     191                bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
     192                                    SSB_CHIPCO_PACKSHIFT;
     193                if (rev >= 4) {
     194                        bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
     195                                          SSB_CHIPCO_NRCORESSHIFT;
     196                }
     197                tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
     198                bus->chipco.capabilities = tmp;
     199        } else {
     200                if (bus->bustype == SSB_BUSTYPE_SSB) {
     201                        bus->chip_id = 0x4710;
     202                        bus->chip_rev = 0;
     203                        bus->chip_package = 0;
     204                } else {
     205                        bus->chip_id = pcidev_to_chipid(bus->host_pci);
     206                        pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
     207                                             &bus->chip_rev);
     208                        bus->chip_package = 0;
     209                }
     210        }
     211        if (!bus->nr_devices)
     212                bus->nr_devices = chipid_to_nrcores(bus->chip_id);
     213        if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
     214                ssb_printk("ERR: More than %d ssb cores found (%d)\n",
     215                           SSB_MAX_NR_CORES, bus->nr_devices);
     216                goto err_unmap;
     217        }
     218        if (bus->bustype == SSB_BUSTYPE_SSB) {
     219                /* Now that we know the number of cores,
     220                 * remap the whole IO space for all cores.
     221                 */
     222                err = -ENOMEM;
     223                iounmap(mmio);
     224                mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
     225                if (!mmio)
     226                        goto out;
     227                bus->mmio = mmio;
     228        }
     229
     230        /* Fetch basic information about each core/device */
     231        for (i = 0; i < bus->nr_devices; i++) {
     232                err = scan_switchcore(bus, i);
     233                if (err)
     234                        goto err_unmap;
     235                dev = &(bus->devices[i]);
     236
     237                idhi = scan_read32(bus, i, SSB_IDHIGH);
     238                dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
     239                dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
     240                dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
     241                dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
     242                dev->core_index = i;
     243                dev->bus = bus;
     244                if ((dev->bus->bustype == SSB_BUSTYPE_PCI) && (bus->host_pci))
     245                        dev->irq = bus->host_pci->irq;
     246
     247                ssb_printk("Core %d found: %s "
     248                           "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
     249                           i, ssb_core_name(dev->id.coreid),
     250                           dev->id.coreid, dev->id.revision, dev->id.vendor);
     251
     252                dev->dev.bus = &ssb_bustype;
     253                snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
     254                         "ssb%02x:%02x", bus->busnumber, i);
     255
     256                switch (dev->id.coreid) {
     257                case SSB_DEV_CHIPCOMMON:
     258                        if (bus->chipco.dev) {
     259                                ssb_printk("WARNING: Multiple Chipcommon found\n");
     260                                break;
     261                        }
     262                        bus->chipco.dev = dev;
     263                        break;
     264                case SSB_DEV_MIPS:
     265                case SSB_DEV_MIPS_3302:
     266                        if (bus->mipscore.dev) {
     267                                ssb_printk("WARNING: Multiple MIPS cores found\n");
     268                                break;
     269                        }
     270                        bus->mipscore.dev = dev;
     271                default:
     272                        break;
     273                }
     274        }
     275        err = 0;
     276out:
     277        return err;
     278err_unmap:
     279        if (bus->bustype == SSB_BUSTYPE_SSB)
     280                iounmap(mmio);
     281        else
     282                pci_iounmap(bus->host_pci, mmio);
     283        goto out;
     284}
  • drivers/ssb/sprom.c

    diff -Nru linux-2.6.19.ori/drivers/ssb/sprom.c linux-2.6.19/drivers/ssb/sprom.c
    old new  
     1 
  • drivers/ssb/ssb_private.h

    diff -Nru linux-2.6.19.ori/drivers/ssb/ssb_private.h linux-2.6.19/drivers/ssb/ssb_private.h
    old new  
     1#ifndef LINUX_SSB_PRIVATE_H_
     2#define LINUX_SSB_PRIVATE_H_
     3
     4#include <linux/ssb.h>
     5#include <linux/types.h>
     6#include <asm/io.h>
     7
     8#ifdef CONFIG_CFE
     9# include <asm/cfe.h>
     10#endif
     11
     12
     13#define PFX     "ssb: "
     14
     15#ifdef CONFIG_SSB_SILENT
     16# define ssb_printk(fmt, x...)  do { /* nothing */ } while (0)
     17#else
     18/* SSB specific printk. If CFE is available, this can be used in early boot.
     19 * But it does not harm otherwise. It just does not print anything.
     20 */
     21int __ssb_printk(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
     22# define ssb_printk(fmt, x...)  __ssb_printk(PFX fmt ,##x)
     23#endif /* CONFIG_SSB_SILENT */
     24
     25/* dprintk: Debugging printk; vanishes for non-debug compilation */
     26#ifdef CONFIG_SSB_DEBUG
     27# define ssb_dprintk(fmt, x...) ssb_printk(fmt ,##x)
     28#else
     29# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0)
     30#endif
     31
     32/* printkl: Rate limited printk */
     33#define ssb_printkl(fmt, x...)  do {            \
     34        if (printk_ratelimit())                 \
     35                ssb_printk(fmt ,##x);           \
     36                                } while (0)
     37
     38/* dprintkl: Rate limited debugging printk */
     39#ifdef CONFIG_SSB_DEBUG
     40# define ssb_dprintkl                   ssb_printkl
     41#else
     42# define ssb_dprintkl(fmt, x...)        do { /* nothing */ } while (0)
     43#endif
     44
     45#define assert(cond)    do {                                            \
     46        if (unlikely(!(cond))) {                                        \
     47                ssb_dprintk(KERN_ERR PFX "BUG: Assertion failed (%s) "  \
     48                            "at: %s:%d:%s()\n",                         \
     49                            #cond, __FILE__, __LINE__, __func__);       \
     50        }                                                               \
     51                       } while (0)
     52
     53
     54extern struct bus_type ssb_bustype;
     55
     56/* pci.c */
     57extern int ssb_pci_switch_core(struct ssb_bus *bus,
     58                               struct ssb_device *dev);
     59extern int ssb_pci_switch_coreidx(struct ssb_bus *bus,
     60                                  u8 coreidx);
     61extern int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
     62                        int turn_on);
     63extern int ssb_pci_sprom_get(struct ssb_bus *bus);
     64
     65
     66/* scan.c */
     67extern int ssb_bus_scan(struct ssb_bus *bus,
     68                        unsigned long baseaddr);
     69
     70
     71/* core.c */
     72extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
     73
     74static inline
     75u16 ssb_raw_read16(struct ssb_bus *bus, u16 offset)
     76{
     77        return readw(bus->mmio + offset);
     78}
     79
     80static inline
     81u32 ssb_raw_read32(struct ssb_bus *bus, u16 offset)
     82{
     83        return readl(bus->mmio + offset);
     84}
     85
     86static inline
     87void ssb_raw_write16(struct ssb_bus *bus, u16 offset, u16 value)
     88{
     89        writew(value, bus->mmio + offset);
     90}
     91
     92static inline
     93void ssb_raw_write32(struct ssb_bus *bus, u16 offset, u32 value)
     94{
     95        writel(value, bus->mmio + offset);
     96}
     97
     98
     99static inline
     100unsigned long ceildiv(unsigned long x, unsigned long y)
     101{
     102        return ((x + (y - 1)) / y);
     103}
     104
     105
     106#endif /* LINUX_SSB_PRIVATE_H_ */
  • include/asm-mips/asm-offsets.h

    diff -Nru linux-2.6.19.ori/include/asm-mips/asm-offsets.h linux-2.6.19/include/asm-mips/asm-offsets.h
    old new  
     1#ifndef __ASM_OFFSETS_H__
     2#define __ASM_OFFSETS_H__
     3/*
     4 * DO NOT MODIFY.
     5 *
     6 * This file was generated by Kbuild
     7 *
     8 */
     9
     10/* MIPS pt_regs offsets. */
     11#define PT_R0     24   
     12#define PT_R1     28   
     13#define PT_R2     32   
     14#define PT_R3     36   
     15#define PT_R4     40   
     16#define PT_R5     44   
     17#define PT_R6     48   
     18#define PT_R7     52   
     19#define PT_R8     56   
     20#define PT_R9     60   
     21#define PT_R10    64   
     22#define PT_R11    68   
     23#define PT_R12    72   
     24#define PT_R13    76   
     25#define PT_R14    80   
     26#define PT_R15    84   
     27#define PT_R16    88   
     28#define PT_R17    92   
     29#define PT_R18    96   
     30#define PT_R19    100   
     31#define PT_R20    104   
     32#define PT_R21    108   
     33#define PT_R22    112   
     34#define PT_R23    116   
     35#define PT_R24    120   
     36#define PT_R25    124   
     37#define PT_R26    128   
     38#define PT_R27    132   
     39#define PT_R28    136   
     40#define PT_R29    140   
     41#define PT_R30    144   
     42#define PT_R31    148   
     43#define PT_LO     160   
     44#define PT_HI     156   
     45#define PT_EPC    172   
     46#define PT_BVADDR 164   
     47#define PT_STATUS 152   
     48#define PT_CAUSE  168   
     49#define PT_SIZE   176   
     50
     51/* MIPS task_struct offsets. */
     52#define TASK_STATE         0   
     53#define TASK_THREAD_INFO   4   
     54#define TASK_FLAGS         12   
     55#define TASK_MM            132 
     56#define TASK_PID           168 
     57#define TASK_STRUCT_SIZE   1048
     58
     59/* MIPS thread_info offsets. */
     60#define TI_TASK            0   
     61#define TI_EXEC_DOMAIN     4   
     62#define TI_FLAGS           8   
     63#define TI_TP_VALUE        12   
     64#define TI_CPU             16   
     65#define TI_PRE_COUNT       20   
     66#define TI_ADDR_LIMIT      24   
     67#define TI_RESTART_BLOCK   28   
     68#define TI_REGS            48   
     69#define _THREAD_SIZE_ORDER 0x1 
     70#define _THREAD_SIZE       0x2000       
     71#define _THREAD_MASK       0x1fff       
     72
     73/* MIPS specific thread_struct offsets. */
     74#define THREAD_REG16   432     
     75#define THREAD_REG17   436     
     76#define THREAD_REG18   440     
     77#define THREAD_REG19   444     
     78#define THREAD_REG20   448     
     79#define THREAD_REG21   452     
     80#define THREAD_REG22   456     
     81#define THREAD_REG23   460     
     82#define THREAD_REG29   464     
     83#define THREAD_REG30   468     
     84#define THREAD_REG31   472     
     85#define THREAD_STATUS  476     
     86#define THREAD_FPU     480     
     87#define THREAD_BVADDR  772     
     88#define THREAD_BUADDR  776     
     89#define THREAD_ECODE   780     
     90#define THREAD_TRAPNO  784     
     91#define THREAD_MFLAGS  788     
     92#define THREAD_TRAMP   792     
     93#define THREAD_OLDCTX  796     
     94
     95#define THREAD_FPR0    480     
     96#define THREAD_FPR1    488     
     97#define THREAD_FPR2    496     
     98#define THREAD_FPR3    504     
     99#define THREAD_FPR4    512     
     100#define THREAD_FPR5    520     
     101#define THREAD_FPR6    528     
     102#define THREAD_FPR7    536     
     103#define THREAD_FPR8    544     
     104#define THREAD_FPR9    552     
     105#define THREAD_FPR10   560     
     106#define THREAD_FPR11   568     
     107#define THREAD_FPR12   576     
     108#define THREAD_FPR13   584     
     109#define THREAD_FPR14   592     
     110#define THREAD_FPR15   600     
     111#define THREAD_FPR16   608     
     112#define THREAD_FPR17   616     
     113#define THREAD_FPR18   624     
     114#define THREAD_FPR19   632     
     115#define THREAD_FPR20   640     
     116#define THREAD_FPR21   648     
     117#define THREAD_FPR22   656     
     118#define THREAD_FPR23   664     
     119#define THREAD_FPR24   672     
     120#define THREAD_FPR25   680     
     121#define THREAD_FPR26   688     
     122#define THREAD_FPR27   696     
     123#define THREAD_FPR28   704     
     124#define THREAD_FPR29   712     
     125#define THREAD_FPR30   720     
     126#define THREAD_FPR31   728     
     127#define THREAD_FCR31   736     
     128
     129/* Linux sigcontext offsets. */
     130#define SC_REGS       16       
     131#define SC_FPREGS     272       
     132#define SC_MDHI       552       
     133#define SC_MDLO       560       
     134#define SC_PC         8
     135#define SC_STATUS     4
     136#define SC_FPC_CSR    532       
     137#define SC_FPC_EIR    536       
     138#define SC_HI1        568       
     139#define SC_LO1        572       
     140#define SC_HI2        576       
     141#define SC_LO2        580       
     142#define SC_HI3        584       
     143#define SC_LO3        588       
     144
     145/* Linux signal numbers. */
     146#define _SIGHUP     0x1
     147#define _SIGINT     0x2
     148#define _SIGQUIT    0x3
     149#define _SIGILL     0x4
     150#define _SIGTRAP    0x5
     151#define _SIGIOT     0x6
     152#define _SIGABRT    0x6
     153#define _SIGEMT     0x7
     154#define _SIGFPE     0x8
     155#define _SIGKILL    0x9
     156#define _SIGBUS     0xa
     157#define _SIGSEGV    0xb
     158#define _SIGSYS     0xc
     159#define _SIGPIPE    0xd
     160#define _SIGALRM    0xe
     161#define _SIGTERM    0xf
     162#define _SIGUSR1    0x10       
     163#define _SIGUSR2    0x11       
     164#define _SIGCHLD    0x12       
     165#define _SIGPWR     0x13       
     166#define _SIGWINCH   0x14       
     167#define _SIGURG     0x15       
     168#define _SIGIO      0x16       
     169#define _SIGSTOP    0x17       
     170#define _SIGTSTP    0x18       
     171#define _SIGCONT    0x19       
     172#define _SIGTTIN    0x1a       
     173#define _SIGTTOU    0x1b       
     174#define _SIGVTALRM  0x1c       
     175#define _SIGPROF    0x1d       
     176#define _SIGXCPU    0x1e       
     177#define _SIGXFSZ    0x1f       
     178
     179/* Linux irq_cpustat_t offsets. */
     180#define IC_SOFTIRQ_PENDING 0   
     181#define IC_IRQ_CPUSTAT_T   32   
     182
     183/* Size of struct page  */
     184#define STRUCT_PAGE_SIZE   32   
     185
     186/* Linux mm_struct offsets. */
     187#define MM_USERS      40       
     188#define MM_PGD        36       
     189#define MM_CONTEXT    348       
     190
     191#define _PAGE_SIZE     0x1000   
     192#define _PAGE_SHIFT    0xc     
     193
     194#define _PGD_T_SIZE    0x4     
     195#define _PMD_T_SIZE    0x4     
     196#define _PTE_T_SIZE    0x4     
     197
     198#define _PGD_T_LOG2    $2       
     199#define _PMD_T_LOG2    $2       
     200#define _PTE_T_LOG2    $2       
     201
     202#define _PMD_SHIFT     0x16     
     203#define _PGDIR_SHIFT   0x16     
     204
     205#define _PGD_ORDER     0x0     
     206#define _PMD_ORDER     0x1     
     207#define _PTE_ORDER     0x0     
     208
     209#define _PTRS_PER_PGD  0x400   
     210#define _PTRS_PER_PMD  0x1     
     211#define _PTRS_PER_PTE  0x400   
     212
     213
     214#endif
  • include/asm-mips/bootinfo.h

    diff -Nru linux-2.6.19.ori/include/asm-mips/bootinfo.h linux-2.6.19/include/asm-mips/bootinfo.h
    old new  
    212212#define MACH_GROUP_NEC_EMMA2RH 25       /* NEC EMMA2RH (was 23)         */
    213213#define  MACH_NEC_MARKEINS      0       /* NEC EMMA2RH Mark-eins        */
    214214
     215/*
     216 * Valid machtype for group Broadcom
     217 */
     218#define MACH_GROUP_BRCM         23      /* Broadcom                     */
     219#define MACH_BCM47XX            1       /* Broadcom BCM47xx             */
     220
    215221#define CL_SIZE                 COMMAND_LINE_SIZE
    216222
    217223const char *get_system_type(void);
  • include/asm-mips/cfe.h

    diff -Nru linux-2.6.19.ori/include/asm-mips/cfe.h linux-2.6.19/include/asm-mips/cfe.h
    old new  
     1/*
     2 * Broadcom Common Firmware Environment (CFE) support
     3 *
     4 * Copyright 2000, 2001, 2002
     5 * Broadcom Corporation. All rights reserved.
     6 *
     7 * Copyright (C) 2006 Michael Buesch
     8 *
     9 * Original Authors:  Mitch Lichtenberg, Chris Demetriou
     10 *
     11 * This software is furnished under license and may be used and copied only
     12 * in accordance with the following terms and conditions.  Subject to these
     13 * conditions, you may download, copy, install, use, modify and distribute
     14 * modified or unmodified copies of this software in source and/or binary
     15 * form. No title or ownership is transferred hereby.
     16 *
     17 * 1) Any source code used, modified or distributed must reproduce and
     18 *    retain this copyright notice and list of conditions as they appear in
     19 *    the source file.
     20 *
     21 * 2) No right is granted to use any trade name, trademark, or logo of
     22 *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
     23 *    used to endorse or promote products derived from this software
     24 *    without the prior written permission of Broadcom Corporation.
     25 *
     26 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
     27 *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
     28 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
     29 *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
     30 *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
     31 *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     34 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     35 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     36 *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37 */
     38
     39#ifndef LINUX_CFE_API_H_
     40#define LINUX_CFE_API_H_
     41
     42#include <linux/types.h>
     43
     44
     45#define CFE_MI_RESERVED         0               /* memory is reserved, do not use */
     46#define CFE_MI_AVAILABLE        1               /* memory is available */
     47
     48#define CFE_FLG_WARMSTART       0x00000001
     49#define CFE_FLG_FULL_ARENA      0x00000001
     50#define CFE_FLG_ENV_PERMANENT   0x00000001
     51
     52#define CFE_CPU_CMD_START       1
     53#define CFE_CPU_CMD_STOP        0
     54
     55#define CFE_STDHANDLE_CONSOLE   0
     56
     57#define CFE_DEV_NETWORK         1
     58#define CFE_DEV_DISK            2
     59#define CFE_DEV_FLASH           3
     60#define CFE_DEV_SERIAL          4
     61#define CFE_DEV_CPU             5
     62#define CFE_DEV_NVRAM           6
     63#define CFE_DEV_CLOCK           7
     64#define CFE_DEV_OTHER           8
     65#define CFE_DEV_MASK            0x0F
     66
     67#define CFE_CACHE_FLUSH_D       1
     68#define CFE_CACHE_INVAL_I       2
     69#define CFE_CACHE_INVAL_D       4
     70#define CFE_CACHE_INVAL_L2      8
     71
     72#define CFE_FWI_64BIT           0x00000001
     73#define CFE_FWI_32BIT           0x00000002
     74#define CFE_FWI_RELOC           0x00000004
     75#define CFE_FWI_UNCACHED        0x00000008
     76#define CFE_FWI_MULTICPU        0x00000010
     77#define CFE_FWI_FUNCSIM         0x00000020
     78#define CFE_FWI_RTLSIM          0x00000040
     79
     80struct cfe_fwinfo {
     81        s64 version;            /* major, minor, eco version */
     82        s64 totalmem;           /* total installed mem */
     83        s64 flags;              /* various flags */
     84        s64 boardid;            /* board ID */
     85        s64 bootarea_va;        /* VA of boot area */
     86        s64 bootarea_pa;        /* PA of boot area */
     87        s64 bootarea_size;      /* size of boot area */
     88};
     89
     90
     91/* The public CFE API */
     92
     93int cfe_present(void);  /* Check if we booted from CFE. Returns bool */
     94
     95int cfe_getticks(s64 *ticks);
     96int cfe_close(int handle);
     97int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1);
     98int cfe_cpu_stop(int cpu);
     99int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen);
     100int cfe_enumdev(int idx, char *name, int namelen);
     101int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
     102                u64 *type);
     103int cfe_exit(int warm, int status);
     104int cfe_flushcache(int flags);
     105int cfe_getdevinfo(char *name);
     106int cfe_getenv(char *name, char *dest, int destlen);
     107int cfe_getfwinfo(struct cfe_fwinfo *info);
     108int cfe_getstdhandle(int handletype);
     109int cfe_inpstat(int handle);
     110int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
     111              int length, int *retlen, u64 offset);
     112int cfe_open(char *name);
     113int cfe_read(int handle, unsigned char *buffer, int length);
     114int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length);
     115int cfe_setenv(char *name, char *val);
     116int cfe_write(int handle, unsigned char *buffer, int length);
     117int cfe_writeblk(int handle, s64 offset, unsigned char *buffer,
     118                 int length);
     119
     120
     121/* High level API */
     122
     123/* Print some information to CFE's console (most likely serial line) */
     124int cfe_printk(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
     125int cfe_vprintk(const char *fmt, va_list args);
     126
     127
     128
     129/* Error codes returned by the low API functions */
     130
     131#define CFE_ISERR(errcode)      (errcode < 0)
     132
     133#define CFE_OK                   0
     134#define CFE_ERR                 -1      /* generic error */
     135#define CFE_ERR_INV_COMMAND     -2
     136#define CFE_ERR_EOF             -3
     137#define CFE_ERR_IOERR           -4
     138#define CFE_ERR_NOMEM           -5
     139#define CFE_ERR_DEVNOTFOUND     -6
     140#define CFE_ERR_DEVOPEN         -7
     141#define CFE_ERR_INV_PARAM       -8
     142#define CFE_ERR_ENVNOTFOUND     -9
     143#define CFE_ERR_ENVREADONLY     -10
     144
     145#define CFE_ERR_NOTELF          -11
     146#define CFE_ERR_NOT32BIT        -12
     147#define CFE_ERR_WRONGENDIAN     -13
     148#define CFE_ERR_BADELFVERS      -14
     149#define CFE_ERR_NOTMIPS         -15
     150#define CFE_ERR_BADELFFMT       -16
     151#define CFE_ERR_BADADDR         -17
     152
     153#define CFE_ERR_FILENOTFOUND    -18
     154#define CFE_ERR_UNSUPPORTED     -19
     155
     156#define CFE_ERR_HOSTUNKNOWN     -20
     157
     158#define CFE_ERR_TIMEOUT         -21
     159
     160#define CFE_ERR_PROTOCOLERR     -22
     161
     162#define CFE_ERR_NETDOWN         -23
     163#define CFE_ERR_NONAMESERVER    -24
     164
     165#define CFE_ERR_NOHANDLES       -25
     166#define CFE_ERR_ALREADYBOUND    -26
     167
     168#define CFE_ERR_CANNOTSET       -27
     169#define CFE_ERR_NOMORE          -28
     170#define CFE_ERR_BADFILESYS      -29
     171#define CFE_ERR_FSNOTAVAIL      -30
     172
     173#define CFE_ERR_INVBOOTBLOCK    -31
     174#define CFE_ERR_WRONGDEVTYPE    -32
     175#define CFE_ERR_BBCHECKSUM      -33
     176#define CFE_ERR_BOOTPROGCHKSUM  -34
     177
     178#define CFE_ERR_LDRNOTAVAIL     -35
     179
     180#define CFE_ERR_NOTREADY        -36
     181
     182#define CFE_ERR_GETMEM          -37
     183#define CFE_ERR_SETMEM          -38
     184
     185#define CFE_ERR_NOTCONN         -39
     186#define CFE_ERR_ADDRINUSE       -40
     187
     188
     189#endif /* LINUX_CFE_API_H_ */
  • include/asm-mips/cpu.h

    diff -Nru linux-2.6.19.ori/include/asm-mips/cpu.h linux-2.6.19/include/asm-mips/cpu.h
    old new  
    104104#define PRID_IMP_SR71000        0x0400
    105105
    106106/*
     107 * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
     108 */
     109
     110#define PRID_IMP_BCM4710        0x4000
     111#define PRID_IMP_BCM3302        0x9000
     112
     113/*
    107114 * Definitions for 7:0 on legacy processors
    108115 */
    109116
     
    200207#define CPU_SB1A                62
    201208#define CPU_74K                 63
    202209#define CPU_R14000              64
    203 #define CPU_LAST                64
     210#define CPU_BCM3302             65
     211#define CPU_BCM4710             66
     212#define CPU_LAST                66
    204213
    205214/*
    206215 * ISA Level encodings
  • include/asm-mips/mach-bcm947xx/kernel-entry-init.h

    diff -Nru linux-2.6.19.ori/include/asm-mips/mach-bcm947xx/kernel-entry-init.h linux-2.6.19/include/asm-mips/mach-bcm947xx/kernel-entry-init.h
    old new  
     1/*
     2 * This file is subject to the terms and conditions of the GNU General Public
     3 * License.  See the file "COPYING" in the main directory of this archive
     4 * for more details.
     5 *
     6 * Copyright (C) 2005 Embedded Alley Solutions, Inc
     7 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
     8 * Copyright (C) 2006 Michael Buesch
     9 */
     10#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
     11#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
     12
     13/* Intentionally empty macro, used in head.S. Override in
     14 * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
     15 */
     16        .macro  kernel_entry_setup
     17        .endm
     18
     19/*
     20 * Do SMP slave processor setup necessary before we can savely execute C code.
     21 */
     22        .macro  smp_slave_setup
     23        .endm
     24
     25
     26#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
  • include/linux/pci_ids.h

    diff -Nru linux-2.6.19.ori/include/linux/pci_ids.h linux-2.6.19/include/linux/pci_ids.h
    old new  
    19531953#define PCI_DEVICE_ID_TIGON3_5906M      0x1713
    19541954#define PCI_DEVICE_ID_BCM4401           0x4401
    19551955#define PCI_DEVICE_ID_BCM4401B0         0x4402
     1956#define PCI_DEVICE_ID_BCM4713           0x4713
    19561957
    19571958#define PCI_VENDOR_ID_TOPIC             0x151f
    19581959#define PCI_DEVICE_ID_TOPIC_TP560       0x0000
  • include/linux/ssb.h

    diff -Nru linux-2.6.19.ori/include/linux/ssb.h linux-2.6.19/include/linux/ssb.h
    old new  
     1#ifndef LINUX_SSB_H_
     2#define LINUX_SSB_H_
     3#ifdef __KERNEL__
     4
     5#include <linux/device.h>
     6#include <linux/list.h>
     7#include <linux/types.h>
     8#include <linux/spinlock.h>
     9
     10#include <linux/ssb_regs.h>
     11
     12
     13struct ssb_bus;
     14struct ssb_driver;
     15
     16
     17struct ssb_sprom_r1 {
     18        u16 pci_spid;           /* Subsystem Product ID for PCI */
     19        u16 pci_svid;           /* Subsystem Vendor ID for PCI */
     20        u16 pci_pid;            /* Product ID for PCI */
     21        u8 il0mac[6];           /* MAC address for 802.11b/g */
     22        u8 et0mac[6];           /* MAC address for Ethernet */
     23        u8 et1mac[6];           /* MAC address for 802.11a */
     24        u8 et0phyaddr:5;        /* MII address for enet0 */
     25        u8 et1phyaddr:5;        /* MII address for enet1 */
     26        u8 et0mdcport:1;        /* MDIO for enet0 */
     27        u8 et1mdcport:1;        /* MDIO for enet1 */
     28        u8 board_rev;           /* Board revision */
     29        u8 country_code:4;      /* Country Code */
     30        u8 antenna_a:2;         /* Antenna 0/1 available for A-PHY */
     31        u8 antenna_bg:2;        /* Antenna 0/1 available for B-PHY and G-PHY */
     32        u16 pa0b0;
     33        u16 pa0b1;
     34        u16 pa0b2;
     35        u16 pa1b0;
     36        u16 pa1b1;
     37        u16 pa1b2;
     38        u8 gpio0;               /* GPIO pin 0 */
     39        u8 gpio1;               /* GPIO pin 1 */
     40        u8 gpio2;               /* GPIO pin 2 */
     41        u8 gpio3;               /* GPIO pin 3 */
     42        u16 maxpwr_a;           /* A-PHY Power Amplifier Max Power (in dBm Q5.2) */
     43        u16 maxpwr_bg;          /* B/G-PHY Power Amplifier Max Power (in dBm Q5.2) */
     44        u8 itssi_a;             /* Idle TSSI Target for A-PHY */
     45        u8 itssi_bg;            /* Idle TSSI Target for B/G-PHY */
     46        u16 boardflags_lo;      /* Boardflags (low 16 bits) */
     47        u8 antenna_gain_a;      /* A-PHY Antenna gain (in dBm Q5.2) */
     48        u8 antenna_gain_bg;     /* B/G-PHY Antenna gain (in dBm Q5.2) */
     49        u8 oem[8];              /* OEM string (rev 1 only) */
     50};
     51
     52struct ssb_sprom_r2 {
     53        u16 boardflags_hi;      /* Boardflags (high 16 bits) */
     54        u8 maxpwr_a_lo;         /* A-PHY Max Power Low */
     55        u8 maxpwr_a_hi;         /* A-PHY Max Power High */
     56        u16 pa1lob0;            /* A-PHY PA Low Settings */
     57        u16 pa1lob1;            /* A-PHY PA Low Settings */
     58        u16 pa1lob2;            /* A-PHY PA Low Settings */
     59        u16 pa1hib0;            /* A-PHY PA High Settings */
     60        u16 pa1hib1;            /* A-PHY PA High Settings */
     61        u16 pa1hib2;            /* A-PHY PA High Settings */
     62        u8 ofdm_pwr_off;        /* OFDM Power Offset from CCK Level */
     63        u8 country_str[2];      /* Two char Country Code */
     64};
     65
     66struct ssb_sprom_r3 {
     67        u32 ofdmapo;            /* A-PHY OFDM Mid Power Offset */
     68        u32 ofdmalpo;           /* A-PHY OFDM Low Power Offset */
     69        u32 ofdmahpo;           /* A-PHY OFDM High Power Offset */
     70        u8 gpioldc_on_cnt;      /* GPIO LED Powersave Duty Cycle ON count */
     71        u8 gpioldc_off_cnt;     /* GPIO LED Powersave Duty Cycle OFF count */
     72        u8 cckpo_1M:4;          /* CCK Power Offset for Rate 1M */
     73        u8 cckpo_2M:4;          /* CCK Power Offset for Rate 2M */
     74        u8 cckpo_55M:4;         /* CCK Power Offset for Rate 5.5M */
     75        u8 cckpo_11M:4;         /* CCK Power Offset for Rate 11M */
     76        u32 ofdmgpo;            /* G-PHY OFDM Power Offset */
     77};
     78
     79struct ssb_sprom_r4 {
     80        /* TODO */
     81};
     82
     83struct ssb_sprom {
     84        u8 revision;
     85        u8 crc;
     86        /* The valid r# fields are selected by the "revision".
     87         * Revision 3 and lower inherit from lower revisions.
     88         */
     89        union {
     90                struct {
     91                        struct ssb_sprom_r1 r1;
     92                        struct ssb_sprom_r2 r2;
     93                        struct ssb_sprom_r3 r3;
     94                };
     95                struct ssb_sprom_r4 r4;
     96        };
     97};
     98
     99
     100/* Core-ID values. */
     101#define SSB_DEV_CHIPCOMMON      0x800
     102#define SSB_DEV_ILINE20         0x801
     103#define SSB_DEV_SDRAM           0x803
     104#define SSB_DEV_PCI             0x804
     105#define SSB_DEV_MIPS            0x805
     106#define SSB_DEV_ETHERNET        0x806
     107#define SSB_DEV_V90             0x807
     108#define SSB_DEV_USB11_HOSTDEV   0x808
     109#define SSB_DEV_ADSL            0x809
     110#define SSB_DEV_ILINE100        0x80A
     111#define SSB_DEV_IPSEC           0x80B
     112#define SSB_DEV_PCMCIA          0x80D
     113#define SSB_DEV_INTERNAL_MEM    0x80E
     114#define SSB_DEV_MEMC_SDRAM      0x80F
     115#define SSB_DEV_EXTIF           0x811
     116#define SSB_DEV_80211           0x812
     117#define SSB_DEV_MIPS_3302       0x816
     118#define SSB_DEV_USB11_HOST      0x817
     119#define SSB_DEV_USB11_DEV       0x818
     120#define SSB_DEV_USB20_HOST      0x819
     121#define SSB_DEV_USB20_DEV       0x81A
     122#define SSB_DEV_SDIO_HOST       0x81B
     123#define SSB_DEV_ROBOSWITCH      0x81C
     124#define SSB_DEV_PARA_ATA        0x81D
     125#define SSB_DEV_SATA_XORDMA     0x81E
     126#define SSB_DEV_ETHERNET_GBIT   0x81F
     127#define SSB_DEV_PCIE            0x820
     128#define SSB_DEV_MIMO_PHY        0x821
     129#define SSB_DEV_SRAM_CTRLR      0x822
     130#define SSB_DEV_MINI_MACPHY     0x823
     131#define SSB_DEV_ARM_1176        0x824
     132#define SSB_DEV_ARM_7TDMI       0x825
     133
     134/* Vendor-ID values */
     135#define SSB_VENDOR_BROADCOM     0x4243
     136
     137struct ssb_device_id {
     138        u16 vendor;
     139        u16 coreid;
     140        u8 revision;
     141};
     142#define SSB_DEVICE(_vendor, _coreid, _revision)  \
     143        { .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
     144#define SSB_DEVTABLE_END  \
     145        { 0, },
     146
     147#define SSB_ANY_VENDOR          0xFFFF
     148#define SSB_ANY_ID              0xFFFF
     149#define SSB_ANY_REV             0xFF
     150
     151
     152struct ssb_device {
     153        struct device dev;
     154        struct ssb_bus *bus;
     155        struct ssb_device_id id;
     156
     157        u8 core_index;
     158        u32 dma_routing;        //FIXME assign this! move to bus? Use helper function?
     159        unsigned int irq;
     160        void *drvdata;
     161};
     162#define dev_to_ssb_dev(_dev) container_of(_dev, struct ssb_device, dev)
     163
     164static inline
     165void ssb_set_drvdata(struct ssb_device *dev, void *data)
     166{
     167        dev->drvdata = data;
     168}
     169static inline
     170void * ssb_get_drvdata(struct ssb_device *dev)
     171{
     172        return dev->drvdata;
     173}
     174
     175u16 ssb_read16(struct ssb_device *dev, u16 offset);
     176u32 ssb_read32(struct ssb_device *dev, u16 offset);
     177void ssb_write16(struct ssb_device *dev, u16 offset, u16 value);
     178void ssb_write32(struct ssb_device *dev, u16 offset, u32 value);
     179
     180
     181struct ssb_driver {
     182        const char *name;
     183        const struct ssb_device_id *id_table;
     184
     185        int (*probe)(struct ssb_device *dev, const struct ssb_device_id *id);
     186        void (*remove)(struct ssb_device *dev);
     187        int (*suspend)(struct ssb_device *dev, pm_message_t state);
     188        int (*resume)(struct ssb_device *dev);
     189        void (*shutdown)(struct ssb_device *dev);
     190
     191        struct device_driver drv;
     192};
     193#define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
     194
     195extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
     196static inline int ssb_driver_register(struct ssb_driver *drv)
     197{
     198        return __ssb_driver_register(drv, THIS_MODULE);
     199}
     200extern void ssb_driver_unregister(struct ssb_driver *drv);
     201
     202
     203
     204
     205enum ssb_bustype {
     206        SSB_BUSTYPE_SSB,        /* This SSB bus is the system bus */
     207        SSB_BUSTYPE_PCI,        /* SSB is connected to PCI bus */
     208        //FIXME JTAG?
     209};
     210
     211#include <linux/ssb_driver_chipcommon.h>
     212#include <linux/ssb_driver_mips.h>
     213#include <linux/ssb_driver_extif.h>
     214
     215struct ssb_bus {
     216        enum ssb_bustype bustype;
     217        struct pci_dev *host_pci;
     218        void __iomem *mmio;
     219
     220        u16 chip_id;
     221        u16 chip_rev;
     222        u8 chip_package;
     223        struct ssb_sprom sprom;
     224
     225        spinlock_t bar_lock;
     226        struct ssb_device *mapped_device;
     227        int nr_devices;
     228        struct ssb_device devices[SSB_MAX_NR_CORES]; /* cores */
     229
     230        struct ssb_chipcommon chipco;
     231        struct ssb_mipscore mipscore;
     232
     233        int busnumber;
     234        struct list_head list;
     235};
     236
     237extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
     238                                   unsigned long baseaddr,
     239                                   void (*fill_sprom)(struct ssb_sprom *sprom));
     240extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
     241                                   struct pci_dev *host_pci);
     242extern void ssb_bus_unregister(struct ssb_bus *bus);
     243extern u32 ssb_clockspeed(struct ssb_bus *bus);
     244
     245int ssb_core_is_enabled(struct ssb_device *dev);
     246void ssb_core_enable(struct ssb_device *dev, u32 core_specific_flags);
     247void ssb_core_disable(struct ssb_device *dev, u32 core_specific_flags);
     248
     249static inline dma_addr_t ssb_dma_offset(struct ssb_device *dev)
     250{
     251        switch(dev->bus->bustype) {
     252        case SSB_BUSTYPE_SSB:
     253                return 0;
     254        case SSB_BUSTYPE_PCI:
     255                return SSB_PCI_DMA;
     256        }
     257        return 0;
     258}
     259
     260
     261
     262#endif /* __KERNEL__ */
     263#endif /* LINUX_SSB_H_ */
  • include/linux/ssb_driver_chipcommon.h

    diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_chipcommon.h linux-2.6.19/include/linux/ssb_driver_chipcommon.h
    old new  
     1#ifndef LINUX_SSB_CHIPCO_H_
     2#define LINUX_SSB_CHIPCO_H_
     3
     4/* SonicsSiliconBackplane CHIPCOMMON core hardware definitions
     5 *
     6 * The chipcommon core provides chip identification, SB control,
     7 * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
     8 * gpio interface, extbus, and support for serial and parallel flashes.
     9 *
     10 * Copyright 2005, Broadcom Corporation
     11 * Copyright 2006, Michael Buesch <mb@bu3sch.de>
     12 *
     13 * Licensed under the GPL version 2. See COPYING for details.
     14 */
     15#ifdef __KERNEL__
     16
     17/** ChipCommon core registers. **/
     18
     19#define SSB_CHIPCO_CHIPID               0x0000
     20#define  SSB_CHIPCO_IDMASK              0x0000FFFF
     21#define  SSB_CHIPCO_REVMASK             0x000F0000
     22#define  SSB_CHIPCO_REVSHIFT            16
     23#define  SSB_CHIPCO_PACKMASK            0x00F00000
     24#define  SSB_CHIPCO_PACKSHIFT           20
     25#define  SSB_CHIPCO_NRCORESMASK         0x0F000000
     26#define  SSB_CHIPCO_NRCORESSHIFT        24
     27#define SSB_CHIPCO_CAP                  0x0004          /* Capabilities */
     28#define  SSB_CHIPCO_CAP_NRUART          0x00000003      /* # of UARTs */
     29#define  SSB_CHIPCO_CAP_MIPSEB          0x00000004      /* MIPS in BigEndian Mode */
     30#define  SSB_CHIPCO_CAP_UARTCLK         0x00000018      /* UART clock select */
     31#define   SSB_CHIPCO_CAP_UARTCLK_INT    0x00000008      /* UARTs are driven by internal divided clock */
     32#define  SSB_CHIPCO_CAP_UARTGPIO        0x00000020      /* UARTs on GPIO 15-12 */
     33#define  SSB_CHIPCO_CAP_EXTBUS          0x000000C0      /* External buses present */
     34#define  SSB_CHIPCO_CAP_FLASHT          0x00000700      /* Flash Type */
     35#define   SSB_CHIPCO_FLASHT_NONE        0x00000000      /* No flash */
     36#define   SSB_CHIPCO_FLASHT_STSER       0x00000100      /* ST serial flash */
     37#define   SSB_CHIPCO_FLASHT_ATSER       0x00000200      /* Atmel serial flash */
     38#define   SSB_CHIPCO_FLASHT_PARA        0x00000700      /* Parallel flash */
     39#define  SSB_CHIPCO_CAP_PLLT            0x00038000      /* PLL Type */
     40#define   SSB_PLLTYPE_NONE              0x00000000
     41#define   SSB_PLLTYPE_1                 0x00010000      /* 48Mhz base, 3 dividers */
     42#define   SSB_PLLTYPE_2                 0x00020000      /* 48Mhz, 4 dividers */
     43#define   SSB_PLLTYPE_3                 0x00030000      /* 25Mhz, 2 dividers */
     44#define   SSB_PLLTYPE_4                 0x00008000      /* 48Mhz, 4 dividers */
     45#define   SSB_PLLTYPE_5                 0x00018000      /* 25Mhz, 4 dividers */
     46#define   SSB_PLLTYPE_6                 0x00028000      /* 100/200 or 120/240 only */
     47#define   SSB_PLLTYPE_7                 0x00038000      /* 25Mhz, 4 dividers */
     48#define  SSB_CHIPCO_CAP_PCTL            0x00040000      /* Power Control */
     49#define  SSB_CHIPCO_CAP_OTPS            0x00380000      /* OTP size */
     50#define  SSB_CHIPCO_CAP_OTPS_SHIFT      19
     51#define  SSB_CHIPCO_CAP_OTPS_BASE       5
     52#define  SSB_CHIPCO_CAP_JTAGM           0x00400000      /* JTAG master present */
     53#define  SSB_CHIPCO_CAP_BROM            0x00800000      /* Internal boot ROM active */
     54#define  SSB_CHIPCO_CAP_64BIT           0x08000000      /* 64-bit Backplane */
     55#define SSB_CHIPCO_CORECTL              0x0008
     56#define  SSB_CHIPCO_CORECTL_UARTCLK0    0x00000001      /* Drive UART with internal clock */
     57#define  SSB_CHIPCO_CORECTL_SE          0x00000002      /* sync clk out enable (corerev >= 3) */
     58#define SSB_CHIPCO_BIST                 0x000C
     59#define SSB_CHIPCO_OTPS                 0x0010          /* OTP status */
     60#define  SSB_CHIPCO_OTPS_PROGFAIL       0x80000000
     61#define  SSB_CHIPCO_OTPS_PROTECT        0x00000007
     62#define  SSB_CHIPCO_OTPS_HW_PROTECT     0x00000001
     63#define  SSB_CHIPCO_OTPS_SW_PROTECT     0x00000002
     64#define  SSB_CHIPCO_OTPS_CID_PROTECT    0x00000004
     65#define SSB_CHIPCO_OTPC                 0x0014          /* OTP control */
     66#define  SSB_CHIPCO_OTPC_RECWAIT        0xFF000000
     67#define  SSB_CHIPCO_OTPC_PROGWAIT       0x00FFFF00
     68#define  SSB_CHIPCO_OTPC_PRW_SHIFT      8
     69#define  SSB_CHIPCO_OTPC_MAXFAIL        0x00000038
     70#define  SSB_CHIPCO_OTPC_VSEL           0x00000006
     71#define  SSB_CHIPCO_OTPC_SELVL          0x00000001
     72#define SSB_CHIPCO_OTPP                 0x0018          /* OTP prog */
     73#define  SSB_CHIPCO_OTPP_COL            0x000000FF
     74#define  SSB_CHIPCO_OTPP_ROW            0x0000FF00
     75#define  SSB_CHIPCO_OTPP_ROW_SHIFT      8
     76#define  SSB_CHIPCO_OTPP_READERR        0x10000000
     77#define  SSB_CHIPCO_OTPP_VALUE          0x20000000
     78#define  SSB_CHIPCO_OTPP_READ           0x40000000
     79#define  SSB_CHIPCO_OTPP_START          0x80000000
     80#define  SSB_CHIPCO_OTPP_BUSY           0x80000000
     81#define SSB_CHIPCO_IRQSTAT              0x0020
     82#define SSB_CHIPCO_IRQMASK              0x0024
     83#define  SSB_CHIPCO_IRQ_GPIO            0x00000001      /* gpio intr */
     84#define  SSB_CHIPCO_IRQ_EXT             0x00000002      /* ro: ext intr pin (corerev >= 3) */
     85#define  SSB_CHIPCO_IRQ_WDRESET         0x80000000      /* watchdog reset occurred */
     86#define SSB_CHIPCO_CHIPCTL              0x0028          /* Rev >= 11 only */
     87#define SSB_CHIPCO_CHIPSTAT             0x002C          /* Rev >= 11 only */
     88#define SSB_CHIPCO_JCMD                 0x0030          /* Rev >= 10 only */
     89#define  SSB_CHIPCO_JCMD_START          0x80000000
     90#define  SSB_CHIPCO_JCMD_BUSY           0x80000000
     91#define  SSB_CHIPCO_JCMD_PAUSE          0x40000000
     92#define  SSB_CHIPCO_JCMD0_ACC_MASK      0x0000F000
     93#define  SSB_CHIPCO_JCMD0_ACC_IRDR      0x00000000
     94#define  SSB_CHIPCO_JCMD0_ACC_DR        0x00001000
     95#define  SSB_CHIPCO_JCMD0_ACC_IR        0x00002000
     96#define  SSB_CHIPCO_JCMD0_ACC_RESET     0x00003000
     97#define  SSB_CHIPCO_JCMD0_ACC_IRPDR     0x00004000
     98#define  SSB_CHIPCO_JCMD0_ACC_PDR       0x00005000
     99#define  SSB_CHIPCO_JCMD0_IRW_MASK      0x00000F00
     100#define  SSB_CHIPCO_JCMD_ACC_MASK       0x000F0000      /* Changes for corerev 11 */
     101#define  SSB_CHIPCO_JCMD_ACC_IRDR       0x00000000
     102#define  SSB_CHIPCO_JCMD_ACC_DR         0x00010000
     103#define  SSB_CHIPCO_JCMD_ACC_IR         0x00020000
     104#define  SSB_CHIPCO_JCMD_ACC_RESET      0x00030000
     105#define  SSB_CHIPCO_JCMD_ACC_IRPDR      0x00040000
     106#define  SSB_CHIPCO_JCMD_ACC_PDR        0x00050000
     107#define  SSB_CHIPCO_JCMD_IRW_MASK       0x00001F00
     108#define  SSB_CHIPCO_JCMD_IRW_SHIFT      8
     109#define  SSB_CHIPCO_JCMD_DRW_MASK       0x0000003F
     110#define SSB_CHIPCO_JIR                  0x0034          /* Rev >= 10 only */
     111#define SSB_CHIPCO_JDR                  0x0038          /* Rev >= 10 only */
     112#define SSB_CHIPCO_JCTL                 0x003C          /* Rev >= 10 only */
     113#define  SSB_CHIPCO_JCTL_FORCE_CLK      4               /* Force clock */
     114#define  SSB_CHIPCO_JCTL_EXT_EN         2               /* Enable external targets */
     115#define  SSB_CHIPCO_JCTL_EN             1               /* Enable Jtag master */
     116#define SSB_CHIPCO_FLASHCTL             0x0040
     117#define  SSB_CHIPCO_FLASHCTL_START      0x80000000
     118#define  SSB_CHIPCO_FLASHCTL_BUSY       SSB_CHIPCO_FLASHCTL_START
     119#define SSB_CHIPCO_FLASHADDR            0x0044
     120#define SSB_CHIPCO_FLASHDATA            0x0048
     121#define SSB_CHIPCO_BCAST_ADDR           0x0050
     122#define SSB_CHIPCO_BCAST_DATA           0x0054
     123#define SSB_CHIPCO_GPIOIN               0x0060
     124#define SSB_CHIPCO_GPIOOUT              0x0064
     125#define SSB_CHIPCO_GPIOOUTEN            0x0068
     126#define SSB_CHIPCO_GPIOCTL              0x006C
     127#define SSB_CHIPCO_GPIOPOL              0x0070
     128#define SSB_CHIPCO_GPIOIRQ              0x0074
     129#define SSB_CHIPCO_WATCHDOG             0x0080
     130#define SSB_CHIPCO_GPIOTIMER            0x0088          /* LED powersave (corerev >= 16) */
     131#define  SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT      16
     132#define SSB_CHIPCO_GPIOTOUTM            0x008C          /* LED powersave (corerev >= 16) */
     133#define SSB_CHIPCO_CLOCK_N              0x0090
     134#define SSB_CHIPCO_CLOCK_SB             0x0094
     135#define SSB_CHIPCO_CLOCK_PCI            0x0098
     136#define SSB_CHIPCO_CLOCK_M2             0x009C
     137#define SSB_CHIPCO_CLOCK_MIPS           0x00A0
     138#define SSB_CHIPCO_CLKDIV               0x00A4          /* Rev >= 3 only */
     139#define  SSB_CHIPCO_CLKDIV_SFLASH       0x0F000000
     140#define  SSB_CHIPCO_CLKDIV_SFLASH_SHIFT 24
     141#define  SSB_CHIPCO_CLKDIV_OTP          0x000F0000
     142#define  SSB_CHIPCO_CLKDIV_OTP_SHIFT    16
     143#define  SSB_CHIPCO_CLKDIV_JTAG         0x00000F00
     144#define  SSB_CHIPCO_CLKDIV_JTAG_SHIFT   8
     145#define  SSB_CHIPCO_CLKDIV_UART         0x000000FF
     146#define SSB_CHIPCO_PLLONDELAY           0x00B0          /* Rev >= 4 only */
     147#define SSB_CHIPCO_FREFSELDELAY         0x00B4          /* Rev >= 4 only */
     148#define SSB_CHIPCO_SLOWCLKCTL           0x00B8          /* 6 <= Rev <= 9 only */
     149#define  SSB_CHIPCO_SLOWCLKCTL_SRC      0x00000007      /* slow clock source mask */
     150#define   SSB_CHIPCO_SLOWCLKCTL_SRC_LPO         0x00000000      /* source of slow clock is LPO */
     151#define   SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL        0x00000001      /* source of slow clock is crystal */
     152#define   SSB_CHIPCO_SLOECLKCTL_SRC_PCI         0x00000002      /* source of slow clock is PCI */
     153#define  SSB_CHIPCO_SLOWCLKCTL_LPOFREQ  0x00000200      /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
     154#define  SSB_CHIPCO_SLOWCLKCTL_LPOPD    0x00000400      /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
     155#define  SSB_CHIPCO_SLOWCLKCTL_FSLOW    0x00000800      /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
     156#define  SSB_CHIPCO_SLOWCLKCTL_IPLL     0x00001000      /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
     157#define  SSB_CHIPCO_SLOWCLKCTL_ENXTAL   0x00002000      /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
     158#define  SSB_CHIPCO_SLOWCLKCTL_XTALPU   0x00004000      /* XtalPU (RO), 1/0: crystal running/disabled */
     159#define  SSB_CHIPCO_SLOWCLKCTL_CLKDIV   0xFFFF0000      /* ClockDivider (SlowClk = 1/(4+divisor)) */
     160#define  SSB_CHIPCO_SLOWCLKCTL_CLKDIV_SHIFT     16
     161#define SSB_CHIPCO_SYSCLKCTL            0x00C0          /* Rev >= 3 only */
     162#define  SSB_CHIPCO_SYSCLKCTL_IDLPEN    0x00000001      /* ILPen: Enable Idle Low Power */
     163#define  SSB_CHIPCO_SYSCLKCTL_ALPEN     0x00000002      /* ALPen: Enable Active Low Power */
     164#define  SSB_CHIPCO_SYSCLKCTL_PLLEN     0x00000004      /* ForcePLLOn */
     165#define  SSB_CHIPCO_SYSCLKCTL_FORCEALP  0x00000008      /* Force ALP (or HT if ALPen is not set */
     166#define  SSB_CHIPCO_SYSCLKCTL_FORCEHT   0x00000010      /* Force HT */
     167#define  SSB_CHIPCO_SYSCLKCTL_CLKDIV    0xFFFF0000      /* ClkDiv  (ILP = 1/(4+divisor)) */
     168#define  SSB_CHIPCO_SYSCLKCTL_CLKDIV_SHIFT      16
     169#define SSB_CHIPCO_CLKSTSTR             0x00C4          /* Rev >= 3 only */
     170#define SSB_CHIPCO_PCMCIA_CFG           0x0100
     171#define SSB_CHIPCO_PCMCIA_MEMWAIT       0x0104
     172#define SSB_CHIPCO_PCMCIA_ATTRWAIT      0x0108
     173#define SSB_CHIPCO_PCMCIA_IOWAIT        0x010C
     174#define SSB_CHIPCO_IDE_CFG              0x0110
     175#define SSB_CHIPCO_IDE_MEMWAIT          0x0114
     176#define SSB_CHIPCO_IDE_ATTRWAIT         0x0118
     177#define SSB_CHIPCO_IDE_IOWAIT           0x011C
     178#define SSB_CHIPCO_PROG_CFG             0x0120
     179#define SSB_CHIPCO_PROG_WAITCNT         0x0124
     180#define SSB_CHIPCO_FLASH_CFG            0x0128
     181#define SSB_CHIPCO_FLASH_WAITCNT        0x012C
     182#define SSB_CHIPCO_UART0_DATA           0x0300
     183#define SSB_CHIPCO_UART0_IMR            0x0304
     184#define SSB_CHIPCO_UART0_FCR            0x0308
     185#define SSB_CHIPCO_UART0_LCR            0x030C
     186#define SSB_CHIPCO_UART0_MCR            0x0310
     187#define SSB_CHIPCO_UART0_LSR            0x0314
     188#define SSB_CHIPCO_UART0_MSR            0x0318
     189#define SSB_CHIPCO_UART0_SCRATCH        0x031C
     190#define SSB_CHIPCO_UART1_DATA           0x0400
     191#define SSB_CHIPCO_UART1_IMR            0x0404
     192#define SSB_CHIPCO_UART1_FCR            0x0408
     193#define SSB_CHIPCO_UART1_LCR            0x040C
     194#define SSB_CHIPCO_UART1_MCR            0x0410
     195#define SSB_CHIPCO_UART1_LSR            0x0414
     196#define SSB_CHIPCO_UART1_MSR            0x0418
     197#define SSB_CHIPCO_UART1_SCRATCH        0x041C
     198
     199
     200
     201/** Clockcontrol masks and values **/
     202
     203/* SSB_CHIPCO_CLOCK_N */
     204#define SSB_CHIPCO_CLK_N1               0x0000003F      /* n1 control */
     205#define SSB_CHIPCO_CLK_N2               0x00003F00      /* n2 control */
     206#define SSB_CHIPCO_CLK_N2_SHIFT         8
     207#define SSB_CHIPCO_CLK_PLLC             0x000F0000      /* pll control */
     208#define SSB_CHIPCO_CLK_PLLC_SHIFT       16
     209
     210/* SSB_CHIPCO_CLOCK_SB/PCI/UART */
     211#define SSB_CHIPCO_CLK_M1               0x0000003F      /* m1 control */
     212#define SSB_CHIPCO_CLK_M2               0x00003F00      /* m2 control */
     213#define SSB_CHIPCO_CLK_M2_SHIFT         8
     214#define SSB_CHIPCO_CLK_M3               0x003F0000      /* m3 control */
     215#define SSB_CHIPCO_CLK_M3_SHIFT         16
     216#define SSB_CHIPCO_CLK_MC               0x1F000000      /* mux control */
     217#define SSB_CHIPCO_CLK_MC_SHIFT         24
     218
     219/* N3M Clock control magic field values */
     220#define SSB_CHIPCO_CLK_F6_2             0x02            /* A factor of 2 in */
     221#define SSB_CHIPCO_CLK_F6_3             0x03            /* 6-bit fields like */
     222#define SSB_CHIPCO_CLK_F6_4             0x05            /* N1, M1 or M3 */
     223#define SSB_CHIPCO_CLK_F6_5             0x09
     224#define SSB_CHIPCO_CLK_F6_6             0x11
     225#define SSB_CHIPCO_CLK_F6_7             0x21
     226
     227#define SSB_CHIPCO_CLK_F5_BIAS          5               /* 5-bit fields get this added */
     228
     229#define SSB_CHIPCO_CLK_MC_BYPASS        0x08
     230#define SSB_CHIPCO_CLK_MC_M1            0x04
     231#define SSB_CHIPCO_CLK_MC_M1M2          0x02
     232#define SSB_CHIPCO_CLK_MC_M1M2M3        0x01
     233#define SSB_CHIPCO_CLK_MC_M1M3          0x11
     234
     235/* Type 2 Clock control magic field values */
     236#define SSB_CHIPCO_CLK_T2_BIAS          2               /* n1, n2, m1 & m3 bias */
     237#define SSB_CHIPCO_CLK_T2M2_BIAS        3               /* m2 bias */
     238
     239#define SSB_CHIPCO_CLK_T2MC_M1BYP       1
     240#define SSB_CHIPCO_CLK_T2MC_M2BYP       2
     241#define SSB_CHIPCO_CLK_T2MC_M3BYP       4
     242
     243/* Type 6 Clock control magic field values */
     244#define SSB_CHIPCO_CLK_T6_MMASK         1               /* bits of interest in m */
     245#define SSB_CHIPCO_CLK_T6_M0            120000000       /* sb clock for m = 0 */
     246#define SSB_CHIPCO_CLK_T6_M1            100000000       /* sb clock for m = 1 */
     247#define SSB_CHIPCO_CLK_SB2MIPS_T6(sb)   (2 * (sb))
     248
     249/* Common clock base */
     250#define SSB_CHIPCO_CLK_BASE1            24000000        /* Half the clock freq */
     251#define SSB_CHIPCO_CLK_BASE2            12500000        /* Alternate crystal on some PLL's */
     252
     253/* Clock control values for 200Mhz in 5350 */
     254#define SSB_CHIPCO_CLK_5350_N           0x0311
     255#define SSB_CHIPCO_CLK_5350_M           0x04020009
     256
     257
     258/** Bits in the config registers **/
     259
     260#define SSB_CHIPCO_CFG_EN               0x0001          /* Enable */
     261#define SSB_CHIPCO_CFG_EXTM             0x000E          /* Extif Mode */
     262#define  SSB_CHIPCO_CFG_EXTM_ASYNC      0x0002          /* Async/Parallel flash */
     263#define  SSB_CHIPCO_CFG_EXTM_SYNC       0x0004          /* Synchronous */
     264#define  SSB_CHIPCO_CFG_EXTM_PCMCIA     0x0008          /* PCMCIA */
     265#define  SSB_CHIPCO_CFG_EXTM_IDE        0x000A          /* IDE */
     266#define SSB_CHIPCO_CFG_DS16             0x0010          /* Data size, 0=8bit, 1=16bit */
     267#define SSB_CHIPCO_CFG_CLKDIV           0x0060          /* Sync: Clock divisor */
     268#define SSB_CHIPCO_CFG_CLKEN            0x0080          /* Sync: Clock enable */
     269#define SSB_CHIPCO_CFG_BSTRO            0x0100          /* Sync: Size/Bytestrobe */
     270
     271
     272/** Flash-specific control/status values */
     273
     274/* flashcontrol opcodes for ST flashes */
     275#define SSB_CHIPCO_FLASHCTL_ST_WREN     0x0006          /* Write Enable */
     276#define SSB_CHIPCO_FLASHCTL_ST_WRDIS    0x0004          /* Write Disable */
     277#define SSB_CHIPCO_FLASHCTL_ST_RDSR     0x0105          /* Read Status Register */
     278#define SSB_CHIPCO_FLASHCTL_ST_WRSR     0x0101          /* Write Status Register */
     279#define SSB_CHIPCO_FLASHCTL_ST_READ     0x0303          /* Read Data Bytes */
     280#define SSB_CHIPCO_FLASHCTL_ST_PP       0x0302          /* Page Program */
     281#define SSB_CHIPCO_FLASHCTL_ST_SE       0x02D8          /* Sector Erase */
     282#define SSB_CHIPCO_FLASHCTL_ST_BE       0x00C7          /* Bulk Erase */
     283#define SSB_CHIPCO_FLASHCTL_ST_DP       0x00B9          /* Deep Power-down */
     284#define SSB_CHIPCO_FLASHCTL_ST_RSIG     0x03AB          /* Read Electronic Signature */
     285
     286/* Status register bits for ST flashes */
     287#define SSB_CHIPCO_FLASHSTA_ST_WIP      0x01            /* Write In Progress */
     288#define SSB_CHIPCO_FLASHSTA_ST_WEL      0x02            /* Write Enable Latch */
     289#define SSB_CHIPCO_FLASHSTA_ST_BP       0x1C            /* Block Protect */
     290#define SSB_CHIPCO_FLASHSTA_ST_BP_SHIFT 2
     291#define SSB_CHIPCO_FLASHSTA_ST_SRWD     0x80            /* Status Register Write Disable */
     292
     293/* flashcontrol opcodes for Atmel flashes */
     294#define SSB_CHIPCO_FLASHCTL_AT_READ             0x07E8
     295#define SSB_CHIPCO_FLASHCTL_AT_PAGE_READ        0x07D2
     296#define SSB_CHIPCO_FLASHCTL_AT_BUF1_READ        /* FIXME */
     297#define SSB_CHIPCO_FLASHCTL_AT_BUF2_READ        /* FIXME */
     298#define SSB_CHIPCO_FLASHCTL_AT_STATUS           0x01D7
     299#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRITE       0x0384
     300#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRITE       0x0387
     301#define SSB_CHIPCO_FLASHCTL_AT_BUF1_ERASE_PRGM  0x0283  /* Erase program */
     302#define SSB_CHIPCO_FLASHCTL_AT_BUF2_ERASE_PRGM  0x0286  /* Erase program */
     303#define SSB_CHIPCO_FLASHCTL_AT_BUF1_PROGRAM     0x0288
     304#define SSB_CHIPCO_FLASHCTL_AT_BUF2_PROGRAM     0x0289
     305#define SSB_CHIPCO_FLASHCTL_AT_PAGE_ERASE       0x0281
     306#define SSB_CHIPCO_FLASHCTL_AT_BLOCK_ERASE      0x0250
     307#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRER_PRGM   0x0382  /* Write erase program */
     308#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRER_PRGM   0x0385  /* Write erase program */
     309#define SSB_CHIPCO_FLASHCTL_AT_BUF1_LOAD        0x0253
     310#define SSB_CHIPCO_FLASHCTL_AT_BUF2_LOAD        0x0255
     311#define SSB_CHIPCO_FLASHCTL_AT_BUF1_COMPARE     0x0260
     312#define SSB_CHIPCO_FLASHCTL_AT_BUF2_COMPARE     0x0261
     313#define SSB_CHIPCO_FLASHCTL_AT_BUF1_REPROGRAM   0x0258
     314#define SSB_CHIPCO_FLASHCTL_AT_BUF2_REPROGRAM   0x0259
     315
     316/* Status register bits for Atmel flashes */
     317#define SSB_CHIPCO_FLASHSTA_AT_READY    0x80
     318#define SSB_CHIPCO_FLASHSTA_AT_MISMATCH 0x40
     319#define SSB_CHIPCO_FLASHSTA_AT_ID       0x38
     320#define SSB_CHIPCO_FLASHSTA_AT_ID_SHIFT 3
     321
     322
     323/** OTP **/
     324
     325/* OTP regions */
     326#define SSB_CHIPCO_OTP_HW_REGION        SSB_CHIPCO_OTPS_HW_PROTECT
     327#define SSB_CHIPCO_OTP_SW_REGION        SSB_CHIPCO_OTPS_SW_PROTECT
     328#define SSB_CHIPCO_OTP_CID_REGION       SSB_CHIPCO_OTPS_CID_PROTECT
     329
     330/* OTP regions (Byte offsets from otp size) */
     331#define SSB_CHIPCO_OTP_SWLIM_OFF        (-8)
     332#define SSB_CHIPCO_OTP_CIDBASE_OFF      0
     333#define SSB_CHIPCO_OTP_CIDLIM_OFF       8
     334
     335/* Predefined OTP words (Word offset from otp size) */
     336#define SSB_CHIPCO_OTP_BOUNDARY_OFF     (-4)
     337#define SSB_CHIPCO_OTP_HWSIGN_OFF       (-3)
     338#define SSB_CHIPCO_OTP_SWSIGN_OFF       (-2)
     339#define SSB_CHIPCO_OTP_CIDSIGN_OFF      (-1)
     340
     341#define SSB_CHIPCO_OTP_CID_OFF          0
     342#define SSB_CHIPCO_OTP_PKG_OFF          1
     343#define SSB_CHIPCO_OTP_FID_OFF          2
     344#define SSB_CHIPCO_OTP_RSV_OFF          3
     345#define SSB_CHIPCO_OTP_LIM_OFF          4
     346
     347#define SSB_CHIPCO_OTP_SIGNATURE        0x578A
     348#define SSB_CHIPCO_OTP_MAGIC            0x4E56
     349
     350
     351struct ssb_device;
     352struct ssb_serial_port;
     353
     354struct ssb_chipcommon {
     355        struct ssb_device *dev;
     356        u32 capabilities;
     357};
     358
     359enum ssb_clkmode {
     360        SSB_CLKMODE_SLOW,
     361        SSB_CLKMODE_FAST,
     362        SSB_CLKMODE_DYNAMIC,
     363};
     364
     365extern void ssb_chipcommon_init(struct ssb_chipcommon *cc);
     366extern void ssb_chipcommon_exit(struct ssb_chipcommon *cc);
     367
     368extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
     369                                        u32 *plltype, u32 *n, u32 *m);
     370extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
     371                                   unsigned long ns_per_cycle);
     372
     373#ifdef CONFIG_SSB_SERIAL
     374extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
     375                                  struct ssb_serial_port *ports);
     376#endif /* CONFIG_SSB_SERIAL */
     377
     378#endif /* __KERNEL__ */
     379#endif /* LINUX_SSB_CHIPCO_H_ */
  • include/linux/ssb_driver_extif.h

    diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_extif.h linux-2.6.19/include/linux/ssb_driver_extif.h
    old new  
     1/*
     2 * Hardware-specific External Interface I/O core definitions
     3 * for the BCM47xx family of SiliconBackplane-based chips.
     4 *
     5 * The External Interface core supports a total of three external chip selects
     6 * supporting external interfaces. One of the external chip selects is
     7 * used for Flash, one is used for PCMCIA, and the other may be
     8 * programmed to support either a synchronous interface or an
     9 * asynchronous interface. The asynchronous interface can be used to
     10 * support external devices such as UARTs and the BCM2019 Bluetooth
     11 * baseband processor.
     12 * The external interface core also contains 2 on-chip 16550 UARTs, clock
     13 * frequency control, a watchdog interrupt timer, and a GPIO interface.
     14 *
     15 * Copyright 2005, Broadcom Corporation     
     16 * Copyright 2006, Michael Buesch
     17 *
     18 * Licensed under the GPL version 2. See COPYING for details.
     19 */
     20#ifndef LINUX_SSB_EXTIFCORE_H_
     21#define LINUX_SSB_EXTIFCORE_H_
     22
     23#ifdef __KERNEL__
     24
     25/* external interface address space */
     26#define SSB_EXTIF_PCMCIA_MEMBASE(x)     (x)
     27#define SSB_EXTIF_PCMCIA_IOBASE(x)      ((x) + 0x100000)
     28#define SSB_EXTIF_PCMCIA_CFGBASE(x)     ((x) + 0x200000)
     29#define SSB_EXTIF_CFGIF_BASE(x)         ((x) + 0x800000)
     30#define SSB_EXTIF_FLASH_BASE(x)         ((x) + 0xc00000)
     31
     32#define SSB_EXTIF_NR_GPIOOUT            5
     33/* GPIO NOTE:
     34 * The multiple instances of output and output enable registers
     35 * are present to allow driver software for multiple cores to control
     36 * gpio outputs without needing to share a single register pair.
     37 * Use the following helper macro to get a register offset value.
     38 */
     39#define SSB_EXTIF_GPIO_OUT(index)       ({              \
     40        BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT);    \
     41        SSB_EXTIF_GPIO_OUT_BASE + ((index) * 8);        \
     42                                        })
     43#define SSB_EXTIF_GPIO_OUTEN(index)     ({              \
     44        BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT);    \
     45        SSB_EXTIF_GPIO_OUTEN_BASE + ((index) * 8);      \
     46                                        })
     47
     48/** EXTIF core registers **/
     49
     50#define SSB_EXTIF_CTL                   0x0000
     51#define  SSB_EXTIF_CTL_UARTEN           (1 << 0) /* UART enable */
     52#define SSB_EXTIF_EXTSTAT               0x0004
     53#define  SSB_EXTIF_EXTSTAT_EMODE        (1 << 0) /* Endian mode (ro) */
     54#define  SSB_EXTIF_EXTSTAT_EIRQPIN      (1 << 1) /* External interrupt pin (ro) */
     55#define  SSB_EXTIF_EXTSTAT_GPIOIRQPIN   (1 << 2) /* GPIO interrupt pin (ro) */
     56#define SSB_EXTIF_PCMCIA_CFG            0x0010
     57#define SSB_EXTIF_PCMCIA_MEMWAIT        0x0014
     58#define SSB_EXTIF_PCMCIA_ATTRWAIT       0x0018
     59#define SSB_EXTIF_PCMCIA_IOWAIT         0x001C
     60#define SSB_EXTIF_PROG_CFG              0x0020
     61#define SSB_EXTIF_PROG_WAITCNT          0x0024
     62#define SSB_EXTIF_FLASH_CFG             0x0028
     63#define SSB_EXTIF_FLASH_WAITCNT         0x002C
     64#define SSB_EXTIF_WATCHDOG              0x0040
     65#define SSB_EXTIF_CLOCK_N               0x0044
     66#define SSB_EXTIF_CLOCK_SB              0x0048
     67#define SSB_EXTIF_CLOCK_PCI             0x004C
     68#define SSB_EXTIF_CLOCK_MII             0x0050
     69#define SSB_EXTIF_GPIO_IN               0x0060
     70#define SSB_EXTIF_GPIO_OUT_BASE         0x0064
     71#define SSB_EXTIF_GPIO_OUTEN_BASE       0x0068
     72#define SSB_EXTIF_EJTAG_OUTEN           0x0090
     73#define SSB_EXTIF_GPIO_INTPOL           0x0094
     74#define SSB_EXTIF_GPIO_INTMASK          0x0098
     75#define SSB_EXTIF_UART_DATA             0x0300
     76#define SSB_EXTIF_UART_TIMER            0x0310
     77#define SSB_EXTIF_UART_FCR              0x0320
     78#define SSB_EXTIF_UART_LCR              0x0330
     79#define SSB_EXTIF_UART_MCR              0x0340
     80#define SSB_EXTIF_UART_LSR              0x0350
     81#define SSB_EXTIF_UART_MSR              0x0360
     82#define SSB_EXTIF_UART_SCRATCH          0x0370
     83
     84
     85
     86
     87/* pcmcia/prog/flash_config */
     88#define SSB_EXTCFG_EN                   (1 << 0)        /* enable */
     89#define SSB_EXTCFG_MODE                 0xE             /* mode */
     90#define SSB_EXTCFG_MODE_SHIFT           1
     91#define  SSB_EXTCFG_MODE_FLASH          0x0             /* flash/asynchronous mode */
     92#define  SSB_EXTCFG_MODE_SYNC           0x2             /* synchronous mode */
     93#define  SSB_EXTCFG_MODE_PCMCIA         0x4             /* pcmcia mode */
     94#define SSB_EXTCFG_DS16                 (1 << 4)        /* destsize:  0=8bit, 1=16bit */
     95#define SSB_EXTCFG_BSWAP                (1 << 5)        /* byteswap */
     96#define SSB_EXTCFG_CLKDIV               0xC0            /* clock divider */
     97#define SSB_EXTCFG_CLKDIV_SHIFT         6
     98#define  SSB_EXTCFG_CLKDIV_2            0x0             /* backplane/2 */
     99#define  SSB_EXTCFG_CLKDIV_3            0x40            /* backplane/3 */
     100#define  SSB_EXTCFG_CLKDIV_4            0x80            /* backplane/4 */
     101#define SSB_EXTCFG_CLKEN                (1 << 8)        /* clock enable */
     102#define SSB_EXTCFG_STROBE               (1 << 9)        /* size/bytestrobe (synch only) */
     103
     104/* pcmcia_memwait */
     105#define SSB_PCMCIA_MEMW_0               0x0000003F      /* waitcount0 */
     106#define SSB_PCMCIA_MEMW_1               0x00001F00      /* waitcount1 */
     107#define SSB_PCMCIA_MEMW_1_SHIFT         8
     108#define SSB_PCMCIA_MEMW_2               0x001F0000      /* waitcount2 */
     109#define SSB_PCMCIA_MEMW_2_SHIFT         16
     110#define SSB_PCMCIA_MEMW_3               0x1F000000      /* waitcount3 */
     111#define SSB_PCMCIA_MEMW_3_SHIFT         24
     112
     113/* pcmcia_attrwait */
     114#define SSB_PCMCIA_ATTW_0               0x0000003F      /* waitcount0 */
     115#define SSB_PCMCIA_ATTW_1               0x00001F00      /* waitcount1 */
     116#define SSB_PCMCIA_ATTW_1_SHIFT         8
     117#define SSB_PCMCIA_ATTW_2               0x001F0000      /* waitcount2 */
     118#define SSB_PCMCIA_ATTW_2_SHIFT         16
     119#define SSB_PCMCIA_ATTW_3               0x1F000000      /* waitcount3 */
     120#define SSB_PCMCIA_ATTW_3_SHIFT         24
     121
     122/* pcmcia_iowait */
     123#define SSB_PCMCIA_IOW_0                0x0000003F      /* waitcount0 */
     124#define SSB_PCMCIA_IOW_1                0x00001F00      /* waitcount1 */
     125#define SSB_PCMCIA_IOW_1_SHIFT          8
     126#define SSB_PCMCIA_IOW_2                0x001F0000      /* waitcount2 */
     127#define SSB_PCMCIA_IOW_2_SHIFT          16
     128#define SSB_PCMCIA_IOW_3                0x1F000000      /* waitcount3 */
     129#define SSB_PCMCIA_IOW_3_SHIFT          24
     130
     131/* prog_waitcount */
     132#define SSB_PROG_WCNT_0                 0x0000001F      /* waitcount0 */
     133#define SSB_PROG_WCNT_1                 0x00001F00      /* waitcount1 */
     134#define SSB_PROG_WCNT_1_SHIFT           8
     135#define SSB_PROG_WCNT_2                 0x001F0000      /* waitcount2 */
     136#define SSB_PROG_WCNT_2_SHIFT           16
     137#define SSB_PROG_WCNT_3                 0x1F000000      /* waitcount3 */
     138#define SSB_PROG_WCNT_3_SHIFT           24
     139
     140#define SSB_PROG_W0                     0x0000000C
     141#define SSB_PROG_W1                     0x00000A00
     142#define SSB_PROG_W2                     0x00020000
     143#define SSB_PROG_W3                     0x01000000
     144
     145/* flash_waitcount */
     146#define SSB_FLASH_WCNT_0                0x0000001F      /* waitcount0 */
     147#define SSB_FLASH_WCNT_1                0x00001F00      /* waitcount1 */
     148#define SSB_FLASH_WCNT_1_SHIFT          8
     149#define SSB_FLASH_WCNT_2                0x001F0000      /* waitcount2 */
     150#define SSB_FLASH_WCNT_2_SHIFT          16
     151#define SSB_FLASH_WCNT_3                0x1F000000      /* waitcount3 */
     152#define SSB_FLASH_WCNT_3_SHIFT          24
     153
     154/* watchdog */
     155#define SSB_EXTIF_WATCHDOG_CLK          48000000        /* Hz */
     156
     157
     158#endif /* __KERNEL__ */
     159#endif /* LINUX_SSB_EXTIFCORE_H_ */
  • include/linux/ssb_driver_mips.h

    diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_mips.h linux-2.6.19/include/linux/ssb_driver_mips.h
    old new  
     1#ifndef LINUX_SSB_MIPSCORE_H_
     2#define LINUX_SSB_MIPSCORE_H_
     3
     4#ifdef __KERNEL__
     5
     6#ifdef CONFIG_SSB_DRIVER_MIPS
     7
     8struct ssb_device;
     9
     10struct ssb_serial_port {
     11        void *regs;
     12        unsigned int irq;
     13        unsigned int baud_base;
     14        unsigned int reg_shift;
     15};
     16
     17
     18struct ssb_mipscore {
     19        struct ssb_device *dev;
     20       
     21        int nr_serial_ports;
     22        struct ssb_serial_port serial_ports[4];
     23
     24        u32 flash_window;
     25        u32 flash_window_size;
     26};
     27
     28extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
     29
     30extern unsigned int ssb_mips_irq(struct ssb_device *dev);
     31
     32
     33#else /* CONFIG_SSB_DRIVER_MIPS */
     34
     35struct ssb_mipscore {
     36};
     37
     38static inline
     39void ssb_mipscore_init(struct ssb_mipscore *mcore)
     40{
     41}
     42
     43#endif /* CONFIG_SSB_DRIVER_MIPS */
     44
     45#endif /* __KERNEL__ */
     46#endif /* LINUX_SSB_MIPSCORE_H_ */
  • include/linux/ssb_driver_pci.h

    diff -Nru linux-2.6.19.ori/include/linux/ssb_driver_pci.h linux-2.6.19/include/linux/ssb_driver_pci.h
    old new  
     1#ifndef LINUX_SSB_PCICORE_H_
     2#define LINUX_SSB_PCICORE_H_
     3#ifndef __KERNEL__
     4
     5
     6/* PCI core registers. */
     7#define SSB_PCICORE_CTL         0x0000  /* PCI Control */
     8#define SSB_PCICORE_ARBCTL      0x0010  /* PCI Arbiter Control */
     9#define SSB_PCICORE_ISTAT       0x0020  /* Interrupt status */
     10#define SSB_PCICORE_IMASK       0x0024  /* Interrupt mask */
     11#define SSB_PCICORE_MBOX        0x0028  /* Backplane to PCI Mailbox */
     12#define SSB_PCICORE_BCAST_ADDR  0x0050  /* Backplane Broadcast Address */
     13#define SSB_PCICORE_BCAST_DATA  0x0054  /* Backplane Broadcast Data */
     14#define SSB_PCICORE_GPIO_IN     0x0060  /* rev >= 2 only */
     15#define SSB_PCICORE_GPIO_OUT    0x0064  /* rev >= 2 only */
     16#define SSB_PCICORE_GPIO_ENABLE 0x0068  /* rev >= 2 only */
     17#define SSB_PCICORE_GPIO_CTL    0x006C  /* rev >= 2 only */
     18#define SSB_PCICORE_TRANS0      0x0100  /* Backplane to PCI translation 0 (sbtopci0) */
     19#define SSB_PCICORE_TRANS1      0x0104  /* Backplane to PCI translation 1 (sbtopci1) */
     20#define SSB_PCICORE_TRANS2      0x0108  /* Backplane to PCI translation 2 (dbtopci2) */
     21#define  SSB_PCICORE_TRANS2_MEM         0x00000000
     22#define  SSB_PCICORE_TRANS2_IO          0x00000001
     23#define  SSB_PCICORE_TRANS2_CFG0        0x00000002
     24#define  SSB_PCICORE_TRANS2_CFG1        0x00000003
     25#define  SSB_PCICORE_TRANS2_PREF        0x00000004      /* Prefetch enable */
     26#define  SSB_PCICORE_TRANS2_BURST       0x00000008      /* Burst enable */
     27#define  SSB_PCICORE_TRANS2_MRM         0x00000020      /* Memory Read Multiple */
     28#define  SSB_PCICORE_TRANS2_MASK0       0xfc000000
     29#define  SSB_PCICORE_TRANS2_MASK1       0xfc000000
     30#define  SSB_PCICORE_TRANS2_MASK2       0xc0000000
     31
     32
     33
     34#endif /* __KERNEL__ */
     35#endif /* LINUX_SSB_PCICORE_H_ */
  • include/linux/ssb_regs.h

    diff -Nru linux-2.6.19.ori/include/linux/ssb_regs.h linux-2.6.19/include/linux/ssb_regs.h
    old new  
     1#ifndef LINUX_SSB_REGS_H_
     2#define LINUX_SSB_REGS_H_
     3#ifdef __KERNEL__
     4
     5
     6/* SiliconBackplane Address Map.
     7 * All regions may not exist on all chips.
     8 */
     9#define SSB_SDRAM_BASE          0x00000000      /* Physical SDRAM */
     10#define SSB_PCI_MEM             0x08000000      /* Host Mode sb2pcitranslation0 (64 MB) */
     11#define SSB_PCI_CFG             0x0c000000      /* Host Mode sb2pcitranslation1 (64 MB) */
     12#define SSB_SDRAM_SWAPPED       0x10000000      /* Byteswapped Physical SDRAM */
     13#define SSB_ENUM_BASE           0x18000000      /* Enumeration space base */
     14#define SSB_ENUM_LIMIT          0x18010000      /* Enumeration space limit */
     15
     16#define SSB_FLASH2              0x1c000000      /* Flash Region 2 (region 1 shadowed here) */
     17#define SSB_FLASH2_SZ           0x02000000      /* Size of Flash Region 2 */
     18
     19#define SSB_EXTIF_BASE          0x1f000000      /* External Interface region base address */
     20#define SSB_FLASH1              0x1fc00000      /* Flash Region 1 */
     21#define SSB_FLASH1_SZ           0x00400000      /* Size of Flash Region 1 */
     22
     23#define SSB_PCI_DMA             0x40000000      /* Client Mode sb2pcitranslation2 (1 GB) */
     24#define SSB_PCI_DMA_SZ          0x40000000      /* Client Mode sb2pcitranslation2 size in bytes */
     25#define SSB_PCIE_DMA_L32                0x00000000      /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
     26#define SSB_PCIE_DMA_H32                0x80000000      /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
     27#define SSB_EUART               (SB_EXTIF_BASE + 0x00800000)
     28#define SSB_LED                 (SB_EXTIF_BASE + 0x00900000)
     29
     30
     31/* Enumeration space constants */
     32#define SSB_CORE_SIZE           0x1000  /* Size of a core MMIO area */
     33#define SSB_MAX_NR_CORES        ((SSB_ENUM_LIMIT - SSB_ENUM_BASE) / SSB_CORE_SIZE)
     34
     35
     36/* mips address */
     37#define SSB_EJTAG               0xff200000      /* MIPS EJTAG space (2M) */
     38
     39
     40/* SSB PCI config space registers. */
     41#define SSB_BAR0_WIN            0x80    /* Backplane address space 0 */
     42#define SSB_BAR1_WIN            0x84    /* Backplane address space 1 */
     43#define SSB_SPROMCTL            0x88    /* SPROM control */
     44#define  SSB_SPROMCTL_WE        0x10    /* SPROM write enable */
     45#define SSB_BAR1_CONTROL        0x8c    /* Address space 1 burst control */
     46#define SSB_PCI_IRQS            0x90    /* PCI interrupts */
     47#define SSB_PCI_IRQMASK         0x94    /* PCI IRQ control and mask (pcirev >= 6 only) */
     48#define SSB_BACKPLANE_IRQS      0x98    /* Backplane Interrupts */
     49#define SSB_GPIO_IN             0xB0    /* GPIO Input (pcirev >= 3 only) */
     50#define SSB_GPIO_OUT            0xB4    /* GPIO Output (pcirev >= 3 only) */
     51#define SSB_GPIO_OUT_ENABLE     0xB8    /* GPIO Output Enable/Disable (pcirev >= 3 only) */
     52#define  SSB_GPIO_SCS           0x10    /* PCI config space bit 4 for 4306c0 slow clock source */
     53#define  SSB_GPIO_HWRAD         0x20    /* PCI config space GPIO 13 for hw radio disable */
     54#define  SSB_GPIO_XTAL          0x40    /* PCI config space GPIO 14 for Xtal powerup */
     55#define  SSB_GPIO_PLL           0x80    /* PCI config space GPIO 15 for PLL powerdown */
     56
     57
     58#define SSB_BAR0_MAX_RETRIES    50
     59
     60/* Silicon backplane configuration register definitions */
     61#define SSB_IPSFLAG             0x0F08
     62#define  SSB_IPSFLAG_IRQ1       0x0000003F /* which sbflags get routed to mips interrupt 1 */
     63#define  SSB_IPSFLAG_IRQ1_SHIFT 0
     64#define  SSB_IPSFLAG_IRQ2       0x00003F00 /* which sbflags get routed to mips interrupt 2 */
     65#define  SSB_IPSFLAG_IRQ2_SHIFT 8
     66#define  SSB_IPSFLAG_IRQ3       0x003F0000 /* which sbflags get routed to mips interrupt 3 */
     67#define  SSB_IPSFLAG_IRQ3_SHIFT 16
     68#define  SSB_IPSFLAG_IRQ4       0x3F000000 /* which sbflags get routed to mips interrupt 4 */
     69#define  SSB_IPSFLAG_IRQ4_SHIFT 24
     70#define SSB_TPSFLAG             0x0F18
     71#define  SSB_TPSFLAG_BPFLAG     0x0000003F /* Backplane flag # */
     72#define  SSB_TPSFLAG_ALWAYSIRQ  0x00000040 /* IRQ is always sent on the Backplane */
     73#define SSB_TMERRLOGA           0x0F48
     74#define SSB_TMERRLOG            0x0F50
     75#define SSB_ADMATCH3            0x0F60
     76#define SSB_ADMATCH2            0x0F68
     77#define SSB_ADMATCH1            0x0F70
     78#define SSB_IMSTATE             0x0F90     /* SB Initiator Agent State */
     79#define  SSB_IMSTATE_PC         0x0000000f /* Pipe Count */
     80#define  SSB_IMSTATE_AP_MASK    0x00000030 /* Arbitration Priority */
     81#define  SSB_IMSTATE_AP_BOTH    0x00000000 /* Use both timeslices and token */
     82#define  SSB_IMSTATE_AP_TS      0x00000010 /* Use timeslices only */
     83#define  SSB_IMSTATE_AP_TK      0x00000020 /* Use token only */
     84#define  SSB_IMSTATE_AP_RSV     0x00000030 /* Reserved */
     85#define  SSB_IMSTATE_IBE        0x00020000 /* In Band Error */
     86#define  SSB_IMSTATE_TO         0x00040000 /* Timeout */
     87#define SSB_INTVEC              0x0F94     /* SB Interrupt Mask */
     88#define  SSB_INTVEC_PCI         0x00000001 /* Enable interrupts for PCI */
     89#define  SSB_INTVEC_ENET0       0x00000002 /* Enable interrupts for enet 0 */
     90#define  SSB_INTVEC_ILINE20     0x00000004 /* Enable interrupts for iline20 */
     91#define  SSB_INTVEC_CODEC       0x00000008 /* Enable interrupts for v90 codec */
     92#define  SSB_INTVEC_USB         0x00000010 /* Enable interrupts for usb */
     93#define  SSB_INTVEC_EXTIF       0x00000020 /* Enable interrupts for external i/f */
     94#define  SSB_INTVEC_ENET1       0x00000040 /* Enable interrupts for enet 1 */
     95#define SSB_TMSLOW              0x0F98     /* SB Target State Low */
     96#define  SSB_TMSLOW_RESET       0x00000001 /* Reset */
     97#define  SSB_TMSLOW_REJECT      0x00000002 /* Reject */
     98#define  SSB_TMSLOW_CLOCK       0x00010000 /* Clock Enable */
     99#define  SSB_TMSLOW_FGC         0x00020000 /* Force Gated Clocks On */
     100#define  SSB_TMSLOW_PE          0x40000000 /* Power Management Enable */
     101#define  SSB_TMSLOW_BE          0x80000000 /* BIST Enable */
     102#define SSB_TMSHIGH             0x0F9C     /* SB Target State High */
     103#define  SSB_TMSHIGH_SERR       0x00000001 /* S-error */
     104#define  SSB_TMSHIGH_INT        0x00000002 /* Interrupt */
     105#define  SSB_TMSHIGH_BUSY       0x00000004 /* Busy */
     106#define  SSB_TMSHIGH_TO         0x00000020 /* Timeout. Backplane rev >= 2.3 only */
     107#define  SSB_TMSHIGH_COREFL     0x1FFF0000 /* Core specific flags */
     108#define  SSB_TMSHIGH_COREFL_SHIFT       16
     109#define  SSB_TMSHIGH_DMA64      0x10000000 /* 64bit DMA supported */
     110#define  SSB_TMSHIGH_GCR        0x20000000 /* Gated Clock Request */
     111#define  SSB_TMSHIGH_BISTF      0x40000000 /* BIST Failed */
     112#define  SSB_TMSHIGH_BISTD      0x80000000 /* BIST Done */
     113#define SSB_BWA0                0x0FA0
     114#define SSB_IMCFGLO             0x0FA8
     115#define  SSB_IMCFGLO_SERTO      0x00000007 /* Service timeout */
     116#define  SSB_IMCFGLO_REQTO      0x00000070 /* Request timeout */
     117#define  SSB_IMCFGLO_REQTO_SHIFT        4
     118#define  SSB_IMCFGLO_CONNID     0x00FF0000 /* Connection ID */
     119#define  SSB_IMCFGLO_CONNID_SHIFT       16
     120#define SSB_IMCFGHI             0x0FAC
     121#define SSB_BCONFIG             0x0FC0
     122#define SSB_BSTATE              0x0FC8
     123#define SSB_ACTCFG              0x0FD8
     124#define SSB_FLAGST              0x0FE8
     125#define SSB_IDLOW               0x0FF8
     126#define  SSB_IDLOW_CFGSP        0x00000003 /* Config Space */
     127#define  SSB_IDLOW_ADDRNGE      0x00000038 /* Address Ranges supported */
     128#define  SSB_IDLOW_ADDRNGE_SHIFT        3
     129#define  SSB_IDLOW_SYNC         0x00000040
     130#define  SSB_IDLOW_INITIATOR    0x00000080
     131#define  SSB_IDLOW_MIBL         0x00000F00 /* Minimum Backplane latency */
     132#define  SSB_IDLOW_MIBL_SHIFT   8
     133#define  SSB_IDLOW_MABL         0x0000F000 /* Maximum Backplane latency */
     134#define  SSB_IDLOW_MABL_SHIFT   12
     135#define  SSB_IDLOW_TIF          0x00010000 /* This Initiator is first */
     136#define  SSB_IDLOW_CCW          0x000C0000 /* Cycle counter width */
     137#define  SSB_IDLOW_CCW_SHIFT    18
     138#define  SSB_IDLOW_TPT          0x00F00000 /* Target ports */
     139#define  SSB_IDLOW_TPT_SHIFT    20
     140#define  SSB_IDLOW_INITP        0x0F000000 /* Initiator ports */
     141#define  SSB_IDLOW_INITP_SHIFT  24
     142#define  SSB_IDLOW_SSBREV       0xF0000000 /* Sonics Backplane Revision code */
     143#define  SSB_IDLOW_SSBREV_22    0x00000000 /* <= 2.2 */
     144#define  SSB_IDLOW_SSBREV_23    0x10000000 /* 2.3 */
     145#define SSB_IDHIGH              0x0FFC     /* SB Identification High */
     146#define  SSB_IDHIGH_RCLO        0x0000000F /* Revision Code (low part) */
     147#define  SSB_IDHIGH_CC          0x00008FF0 /* Core Code */
     148#define  SSB_IDHIGH_CC_SHIFT    4
     149#define  SSB_IDHIGH_RCHI        0x00007000 /* Revision Code (high part) */
     150#define  SSB_IDHIGH_RCHI_SHIFT  8          /* yes, shift 8 is right */
     151#define  SSB_IDHIGH_VC          0xFFFF0000 /* Vendor Code */
     152#define  SSB_IDHIGH_VC_SHIFT    16
     153
     154/* SPROM shadow area. If not otherwise noted, fields are
     155 * two bytes wide. Note that the SPROM can _only_ be read
     156 * in two-byte quantinies.
     157 */
     158#define SSB_SPROMSIZE_WORDS             64
     159#define SSB_SPROMSIZE_BYTES             (SSB_SPROMSIZE_WORDS * sizeof(u16))
     160#define SSB_SPROM_BASE                  0x1000
     161#define SSB_SPROM_REVISION              0x107E
     162#define  SSB_SPROM_REVISION_REV         0x00FF  /* SPROM Revision number */
     163#define  SSB_SPROM_REVISION_CRC         0xFF00  /* SPROM CRC8 value */
     164#define  SSB_SPROM_REVISION_CRC_SHIFT   8
     165/* SPROM Revision 1 */
     166#define SSB_SPROM1_SPID                 0x1004  /* Subsystem Product ID for PCI */
     167#define SSB_SPROM1_SVID                 0x1006  /* Subsystem Vendor ID for PCI */
     168#define SSB_SPROM1_PID                  0x1008  /* Product ID for PCI */
     169#define SSB_SPROM1_IL0MAC               0x1048  /* 6 bytes MAC address for 802.11b/g */
     170#define SSB_SPROM1_ET0MAC               0x104E  /* 6 bytes MAC address for Ethernet */
     171#define SSB_SPROM1_ET1MAC               0x1054  /* 6 bytes MAC address for 802.11a */
     172#define SSB_SPROM1_ETHPHY               0x105A  /* Ethernet PHY settings */
     173#define  SSB_SPROM1_ETHPHY_ET0A         0x001F  /* MII Address for enet0 */
     174#define  SSB_SPROM1_ETHPHY_ET1A         0x03E0  /* MII Address for enet1 */
     175#define  SSB_SPROM1_ETHPHY_ET1A_SHIFT   5
     176#define  SSB_SPROM1_ETHPHY_ET0M         (1<<14) /* MDIO for enet0 */
     177#define  SSB_SPROM1_ETHPHY_ET1M         (1<<15) /* MDIO for enet1 */
     178#define SSB_SPROM1_BINF                 0x105C  /* Board info */
     179#define  SSB_SPROM1_BINF_BREV           0x00FF  /* Board Revision */
     180#define  SSB_SPROM1_BINF_CCODE          0x0F00  /* Country Code */
     181#define  SSB_SPROM1_BINF_CCODE_SHIFT    8
     182#define  SSB_SPROM1_BINF_ANTA           0x3000  /* Available A-PHY antennas */
     183#define  SSB_SPROM1_BINF_ANTA_SHIFT     12
     184#define  SSB_SPROM1_BINF_ANTBG          0xC000  /* Available B-PHY antennas */
     185#define  SSB_SPROM1_BINF_ANTBG_SHIFT    14
     186#define SSB_SPROM1_PA0B0                0x105E
     187#define SSB_SPROM1_PA0B1                0x1060
     188#define SSB_SPROM1_PA0B2                0x1062
     189#define SSB_SPROM1_GPIOA                0x1064  /* General Purpose IO pins 0 and 1 */
     190#define  SSB_SPROM1_GPIOA_P0            0x00FF  /* Pin 0 */
     191#define  SSB_SPROM1_GPIOA_P1            0xFF00  /* Pin 1 */
     192#define  SSB_SPROM1_GPIOA_P1_SHIFT      8
     193#define SSB_SPROM1_GPIOB                0x1066  /* General Purpuse IO pins 2 and 3 */
     194#define  SSB_SPROM1_GPIOB_P2            0x00FF  /* Pin 2 */
     195#define  SSB_SPROM1_GPIOB_P3            0xFF00  /* Pin 3 */
     196#define  SSB_SPROM1_GPIOB_P3_SHIFT      8
     197#define SSB_SPROM1_MAXPWR               0x1068  /* Power Amplifier Max Power */
     198#define  SSB_SPROM1_MAXPWR_A            0x00FF  /* A-PHY (in dBm Q5.2) */
     199#define  SSB_SPROM1_MAXPWR_BG           0xFF00  /* B-PHY and G-PHY (in dBm Q5.2) */
     200#define  SSB_SPROM1_MAXPWR_BG_SHIFT     8
     201#define SSB_SPROM1_PA1B0                0x106A
     202#define SSB_SPROM1_PA1B1                0x106C
     203#define SSB_SPROM1_PA1B2                0x106E
     204#define SSB_SPROM1_ITSSI                0x1070  /* Idle TSSI Target */
     205#define  SSB_SPROM1_ITSSI_A             0x00FF  /* A-PHY */
     206#define  SSB_SPROM1_ITSSI_BG            0xFF00  /* B-PHY and G-PHY */
     207#define  SSB_SPROM1_ITSSI_BG_SHIFT      8
     208#define SSB_SPROM1_BFLLO                0x1072  /* Boardflags (low 16 bits) */
     209#define SSB_SPROM1_AGAIN                0x1074  /* Antenna Gain (in dBm Q5.2) */
     210#define  SSB_SPROM1_AGAIN_A             0x00FF  /* A-PHY */
     211#define  SSB_SPROM1_AGAIN_BG            0xFF00  /* B-PHY and G-PHY */
     212#define  SSB_SPROM1_AGAIN_BG_SHIFT      8
     213#define SSB_SPROM1_OEM                  0x1076  /* 8 bytes OEM string (rev 1 only) */
     214/* SPROM Revision 2 (inherits from rev 1) */
     215#define SSB_SPROM2_BFLHI                0x1038  /* Boardflags (high 16 bits) */
     216#define SSB_SPROM2_MAXP_A               0x103A  /* A-PHY Max Power */
     217#define  SSB_SPROM2_MAXP_A_HI           0x00FF  /* Max Power High */
     218#define  SSB_SPROM2_MAXP_A_LO           0xFF00  /* Max Power Low */
     219#define  SSB_SPROM2_MAXP_A_LO_SHIFT     8
     220#define SSB_SPROM2_PA1LOB0              0x103C  /* A-PHY PowerAmplifier Low Settings */
     221#define SSB_SPROM2_PA1LOB1              0x103E  /* A-PHY PowerAmplifier Low Settings */
     222#define SSB_SPROM2_PA1LOB2              0x1040  /* A-PHY PowerAmplifier Low Settings */
     223#define SSB_SPROM2_PA1HIB0              0x1042  /* A-PHY PowerAmplifier High Settings */
     224#define SSB_SPROM2_PA1HIB1              0x1044  /* A-PHY PowerAmplifier High Settings */
     225#define SSB_SPROM2_PA1HIB2              0x1046  /* A-PHY PowerAmplifier High Settings */
     226#define SSB_SPROM2_OPO                  0x1078  /* OFDM Power Offset from CCK Level */
     227#define  SSB_SPROM2_OPO_VALUE           0x00FF
     228#define  SSB_SPROM2_OPO_UNUSED          0xFF00
     229#define SSB_SPROM2_CCODE                0x107C  /* Two char Country Code */
     230/* SPROM Revision 3 (inherits from rev 2) */
     231#define SSB_SPROM3_OFDMAPO              0x102C  /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
     232#define SSB_SPROM3_OFDMALPO             0x1030  /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
     233#define SSB_SPROM3_OFDMAHPO             0x1034  /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
     234#define SSB_SPROM3_GPIOLDC              0x1042  /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
     235#define  SSB_SPROM3_GPIOLDC_OFF         0x0000FF00      /* Off Count */
     236#define  SSB_SPROM3_GPIOLDC_OFF_SHIFT   8
     237#define  SSB_SPROM3_GPIOLDC_ON          0x00FF0000      /* On Count */
     238#define  SSB_SPROM3_GPIOLDC_ON_SHIFT    16
     239#define SSB_SPROM3_CCKPO                0x1078  /* CCK Power Offset */
     240#define  SSB_SPROM3_CCKPO_1M            0x000F  /* 1M Rate PO */
     241#define  SSB_SPROM3_CCKPO_2M            0x00F0  /* 2M Rate PO */
     242#define  SSB_SPROM3_CCKPO_2M_SHIFT      4
     243#define  SSB_SPROM3_CCKPO_55M           0x0F00  /* 5.5M Rate PO */
     244#define  SSB_SPROM3_CCKPO_55M_SHIFT     8
     245#define  SSB_SPROM3_CCKPO_11M           0xF000  /* 11M Rate PO */
     246#define  SSB_SPROM3_CCKPO_11M_SHIFT     12
     247#define  SSB_SPROM3_OFDMGPO             0x107A  /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
     248
     249/* Values for SSB_SPROM1_BINF_CCODE */
     250enum {
     251        SSB_SPROM1CCODE_WORLD = 0,
     252        SSB_SPROM1CCODE_THAILAND,
     253        SSB_SPROM1CCODE_ISRAEL,
     254        SSB_SPROM1CCODE_JORDAN,
     255        SSB_SPROM1CCODE_CHINA,
     256        SSB_SPROM1CCODE_JAPAN,
     257        SSB_SPROM1CCODE_USA_CANADA_ANZ,
     258        SSB_SPROM1CCODE_EUROPE,
     259        SSB_SPROM1CCODE_USA_LOW,
     260        SSB_SPROM1CCODE_JAPAN_HIGH,
     261        SSB_SPROM1CCODE_ALL,
     262        SSB_SPROM1CCODE_NONE,
     263};
     264
     265
     266#endif /* __KERNEL__ */
     267#endif /* LINUX_SSB_REGS_H_ */
Note: See TracBrowser for help on using the repository browser.