source: trunk/target/linux/brcm47xx/patches-3.0/0005-bcma-add-mips-driver.patch @ 27301

Last change on this file since 27301 was 27301, checked in by hauke, 5 years ago

brcm47xx: add initial support for devices with bcma bus.

Ethernet and wifi are not working and this is highly experimental.

File size: 10.7 KB
  • drivers/bcma/Kconfig

    From 0a1a5fd8aab864e7b531ab88fd317ff7278d884d Mon Sep 17 00:00:00 2001
    From: Hauke Mehrtens <hauke@hauke-m.de>
    Date: Mon, 6 Jun 2011 00:07:32 +0200
    Subject: [PATCH 05/14] bcma: add mips driver
    
    This adds a mips driver to bcma. This is only found on embedded
    devices. For now the driver just initializes the irqs used on this
    system.
    
    Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
    ---
     drivers/bcma/Kconfig                  |   11 ++-
     drivers/bcma/Makefile                 |    1 +
     drivers/bcma/driver_mips.c            |  234 +++++++++++++++++++++++++++++++++
     drivers/bcma/main.c                   |   19 +++
     include/linux/bcma/bcma.h             |    2 +
     include/linux/bcma/bcma_driver_mips.h |   49 +++++++
     6 files changed, 315 insertions(+), 1 deletions(-)
     create mode 100644 drivers/bcma/driver_mips.c
     create mode 100644 include/linux/bcma/bcma_driver_mips.h
    
    a b config BCMA_HOST_PCI 
    2929 
    3030config BCMA_HOST_SOC 
    3131        bool 
    32         depends on BCMA && MIPS 
     32        depends on BCMA_DRIVER_MIPS 
    3333        default n 
    3434 
     35config BCMA_DRIVER_MIPS 
     36        bool "BCMA Broadcom MIPS core driver" 
     37        depends on BCMA && MIPS 
     38        help 
     39          Driver for the Broadcom MIPS core attached to Broadcom specific 
     40          Advanced Microcontroller Bus. 
     41 
     42          If unsure, say N 
     43 
    3544config BCMA_DEBUG 
    3645        bool "BCMA debugging" 
    3746        depends on BCMA 
  • drivers/bcma/Makefile

    a b  
    11bcma-y                                  += main.o scan.o core.o sprom.o 
    22bcma-y                                  += driver_chipcommon.o driver_chipcommon_pmu.o 
    33bcma-y                                  += driver_pci.o 
     4bcma-$(CONFIG_BCMA_DRIVER_MIPS)         += driver_mips.o 
    45bcma-$(CONFIG_BCMA_HOST_PCI)            += host_pci.o 
    56bcma-$(CONFIG_BCMA_HOST_SOC)            += host_soc.o 
    67obj-$(CONFIG_BCMA)                      += bcma.o 
  • new file drivers/bcma/driver_mips.c

    - +  
     1/* 
     2 * Broadcom specific AMBA 
     3 * Broadcom MIPS32 74K core driver 
     4 * 
     5 * Copyright 2009, Broadcom Corporation 
     6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de> 
     7 * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com> 
     8 * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de> 
     9 * 
     10 * Licensed under the GNU/GPL. See COPYING for details. 
     11 */ 
     12 
     13#include "bcma_private.h" 
     14 
     15#include <linux/bcma/bcma.h> 
     16 
     17#include <linux/serial.h> 
     18#include <linux/serial_core.h> 
     19#include <linux/serial_reg.h> 
     20#include <linux/time.h> 
     21 
     22/* The 47162a0 hangs when reading its registers */ 
     23static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev) 
     24{ 
     25        return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 && 
     26               dev->id.id == BCMA_CORE_MIPS_74K; 
     27} 
     28 
     29static inline u32 mips_read32(struct bcma_drv_mips *mcore, 
     30                              u16 offset) 
     31{ 
     32        return bcma_read32(mcore->core, offset); 
     33} 
     34 
     35static inline void mips_write32(struct bcma_drv_mips *mcore, 
     36                                u16 offset, 
     37                                u32 value) 
     38{ 
     39        bcma_write32(mcore->core, offset, value); 
     40} 
     41 
     42static const u32 ipsflag_irq_mask[] = { 
     43        0, 
     44        BCMA_MIPS_IPSFLAG_IRQ1, 
     45        BCMA_MIPS_IPSFLAG_IRQ2, 
     46        BCMA_MIPS_IPSFLAG_IRQ3, 
     47        BCMA_MIPS_IPSFLAG_IRQ4, 
     48}; 
     49 
     50static const u32 ipsflag_irq_shift[] = { 
     51        0, 
     52        BCMA_MIPS_IPSFLAG_IRQ1_SHIFT, 
     53        BCMA_MIPS_IPSFLAG_IRQ2_SHIFT, 
     54        BCMA_MIPS_IPSFLAG_IRQ3_SHIFT, 
     55        BCMA_MIPS_IPSFLAG_IRQ4_SHIFT, 
     56}; 
     57 
     58static u32 bcma_core_mips_irqflag(struct bcma_device *dev) 
     59{ 
     60        u32 flag; 
     61 
     62        if (bcma_core_mips_bcm47162a0_quirk(dev)) 
     63                return dev->core_index; 
     64        flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30); 
     65 
     66        return flag & 0x1F; 
     67} 
     68 
     69 
     70/* Get the MIPS IRQ assignment for a specified device. 
     71 * If unassigned, 0 is returned. 
     72 * If disabled, 5 is returned. 
     73 */ 
     74unsigned int bcma_core_mips_irq(struct bcma_device *dev) 
     75{ 
     76        struct bcma_device *mdev = dev->bus->drv_mips.core; 
     77        u32 irqflag; 
     78        unsigned int irq; 
     79 
     80        irqflag = bcma_core_mips_irqflag(dev); 
     81 
     82        for (irq = 1; irq <= 4; irq++) 
     83                if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) & 
     84                    (1 << irqflag)) 
     85                        return irq; 
     86 
     87        return 0; 
     88} 
     89EXPORT_SYMBOL(bcma_core_mips_irq); 
     90 
     91static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq) 
     92{ 
     93        unsigned int oldirq = bcma_core_mips_irq(dev); 
     94        struct bcma_bus *bus = dev->bus; 
     95        struct bcma_device *mdev = bus->drv_mips.core; 
     96        u32 irqflag; 
     97 
     98        irqflag = bcma_core_mips_irqflag(dev); 
     99        BUG_ON(oldirq == 6); 
     100 
     101        dev->irq = irq + 2; 
     102 
     103        /* clear the old irq */ 
     104        if (oldirq == 0) 
     105                bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0), 
     106                            bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) & 
     107                            ~(1 << irqflag)); 
     108        else 
     109                bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0); 
     110 
     111        /* assign the new one */ 
     112        if (irq == 0) { 
     113                bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0), 
     114                            bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) | 
     115                            (1 << irqflag)); 
     116        } else { 
     117                u32 oldirqflag = bcma_read32(mdev, 
     118                                             BCMA_MIPS_MIPS74K_INTMASK(irq)); 
     119                if (oldirqflag) { 
     120                        struct bcma_device *core; 
     121 
     122                        /* backplane irq line is in use, find out who uses 
     123                         * it and set user to irq 0 
     124                         */ 
     125                        list_for_each_entry_reverse(core, &bus->cores, list) { 
     126                                if ((1 << bcma_core_mips_irqflag(core)) == 
     127                                    oldirqflag) { 
     128                                        bcma_core_mips_set_irq(core, 0); 
     129                                        break; 
     130                                } 
     131                        } 
     132                } 
     133                bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 
     134                             1 << irqflag); 
     135        } 
     136 
     137        pr_info("set_irq: core 0x%04x, irq %d => %d\n", 
     138                dev->id.id, oldirq + 2, irq + 2); 
     139} 
     140 
     141static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq) 
     142{ 
     143        int i; 
     144        static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"}; 
     145        printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id); 
     146        for (i = 0; i <= 6; i++) 
     147                printk(" %s%s", irq_name[i], i == irq ? "*" : " "); 
     148        printk("\n"); 
     149} 
     150 
     151static void bcma_core_mips_dump_irq(struct bcma_bus *bus) 
     152{ 
     153        struct bcma_device *core; 
     154 
     155        list_for_each_entry_reverse(core, &bus->cores, list) { 
     156                bcma_core_mips_print_irq(core, bcma_core_mips_irq(core)); 
     157        } 
     158} 
     159 
     160static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) 
     161{ 
     162        struct bcma_bus *bus = mcore->core->bus; 
     163 
     164        mcore->flash_buswidth = 2; 
     165        if (bus->drv_cc.core) { 
     166                mcore->flash_window = 0x1c000000; 
     167                mcore->flash_window_size = 0x02000000; 
     168                switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { 
     169                case BCMA_CC_FLASHT_STSER: 
     170                case BCMA_CC_FLASHT_ATSER: 
     171                        pr_err("Serial flash not supported.\n"); 
     172                        break; 
     173                case BCMA_CC_FLASHT_PARA: 
     174                        if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) & 
     175                             BCMA_CC_OTPS) == 0) 
     176                                mcore->flash_buswidth = 1; 
     177                        break; 
     178                } 
     179        } else { 
     180                mcore->flash_window = 0x1fc00000; 
     181                mcore->flash_window_size = 0x00400000; 
     182        } 
     183} 
     184 
     185void bcma_core_mips_init(struct bcma_drv_mips *mcore) 
     186{ 
     187        struct bcma_bus *bus; 
     188        struct bcma_device *core; 
     189        bus = mcore->core->bus; 
     190 
     191        pr_info("Initializing MIPS core...\n"); 
     192 
     193        if (!mcore->setup_done) 
     194                mcore->assigned_irqs = 1; 
     195 
     196        /* Assign IRQs to all cores on the bus */ 
     197        list_for_each_entry_reverse(core, &bus->cores, list) { 
     198                int mips_irq; 
     199                if (core->irq) 
     200                        continue; 
     201 
     202                mips_irq = bcma_core_mips_irq(core); 
     203                if (mips_irq > 4) 
     204                        core->irq = 0; 
     205                else 
     206                        core->irq = mips_irq + 2; 
     207                if (core->irq > 5) 
     208                        continue; 
     209                switch (core->id.id) { 
     210                case BCMA_CORE_PCI: 
     211                case BCMA_CORE_PCIE: 
     212                case BCMA_CORE_ETHERNET: 
     213                case BCMA_CORE_ETHERNET_GBIT: 
     214                case BCMA_CORE_MAC_GBIT: 
     215                case BCMA_CORE_80211: 
     216                case BCMA_CORE_USB20_HOST: 
     217                        /* These devices get their own IRQ line if available, 
     218                         * the rest goes on IRQ0 
     219                         */ 
     220                        if (mcore->assigned_irqs <= 4) 
     221                                bcma_core_mips_set_irq(core, 
     222                                                       mcore->assigned_irqs++); 
     223                        break; 
     224                } 
     225        } 
     226        pr_info("IRQ reconfiguration done\n"); 
     227        bcma_core_mips_dump_irq(bus); 
     228 
     229        if (mcore->setup_done) 
     230                return; 
     231 
     232        bcma_core_mips_flash_detect(mcore); 
     233        mcore->setup_done = true; 
     234} 
  • drivers/bcma/main.c

    a b static int bcma_register_cores(struct bc 
    8080                case BCMA_CORE_CHIPCOMMON: 
    8181                case BCMA_CORE_PCI: 
    8282                case BCMA_CORE_PCIE: 
     83                case BCMA_CORE_MIPS_74K: 
    8384                        continue; 
    8485                } 
    8586 
    int bcma_bus_register(struct bcma_bus *b 
    141142                bcma_core_chipcommon_init(&bus->drv_cc); 
    142143        } 
    143144 
     145#ifdef CONFIG_BCMA_DRIVER_MIPS 
     146        /* Init MIPS core */ 
     147        core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); 
     148        if (core) { 
     149                bus->drv_mips.core = core; 
     150                bcma_core_mips_init(&bus->drv_mips); 
     151        } 
     152#endif 
     153 
    144154        /* Init PCIE core */ 
    145155        core = bcma_find_core(bus, BCMA_CORE_PCIE); 
    146156        if (core) { 
    int __init bcma_bus_early_register(struc 
    208218                bcma_core_chipcommon_init(&bus->drv_cc); 
    209219        } 
    210220 
     221#ifdef CONFIG_BCMA_DRIVER_MIPS 
     222        /* Init MIPS core */ 
     223        core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); 
     224        if (core) { 
     225                bus->drv_mips.core = core; 
     226                bcma_core_mips_init(&bus->drv_mips); 
     227        } 
     228#endif 
     229 
    211230        pr_info("Early bus registered\n"); 
    212231 
    213232        return 0; 
  • include/linux/bcma/bcma.h

    a b  
    66 
    77#include <linux/bcma/bcma_driver_chipcommon.h> 
    88#include <linux/bcma/bcma_driver_pci.h> 
     9#include <linux/bcma/bcma_driver_mips.h> 
    910#include <linux/ssb/ssb.h> /* SPROM sharing */ 
    1011 
    1112#include "bcma_regs.h" 
    struct bcma_bus { 
    193194 
    194195        struct bcma_drv_cc drv_cc; 
    195196        struct bcma_drv_pci drv_pci; 
     197        struct bcma_drv_mips drv_mips; 
    196198 
    197199        /* We decided to share SPROM struct with SSB as long as we do not need 
    198200         * any hacks for BCMA. This simplifies drivers code. */ 
  • new file include/linux/bcma/bcma_driver_mips.h

    - +  
     1#ifndef LINUX_BCMA_DRIVER_MIPS_H_ 
     2#define LINUX_BCMA_DRIVER_MIPS_H_ 
     3 
     4#define BCMA_MIPS_IPSFLAG               0x0F08 
     5/* which sbflags get routed to mips interrupt 1 */ 
     6#define  BCMA_MIPS_IPSFLAG_IRQ1         0x0000003F 
     7#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT   0 
     8/* which sbflags get routed to mips interrupt 2 */ 
     9#define  BCMA_MIPS_IPSFLAG_IRQ2         0x00003F00 
     10#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT   8 
     11/* which sbflags get routed to mips interrupt 3 */ 
     12#define  BCMA_MIPS_IPSFLAG_IRQ3         0x003F0000 
     13#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT   16 
     14/* which sbflags get routed to mips interrupt 4 */ 
     15#define  BCMA_MIPS_IPSFLAG_IRQ4         0x3F000000 
     16#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT   24 
     17 
     18/* MIPS 74K core registers */ 
     19#define BCMA_MIPS_MIPS74K_CORECTL       0x0000 
     20#define BCMA_MIPS_MIPS74K_EXCEPTBASE    0x0004 
     21#define BCMA_MIPS_MIPS74K_BIST          0x000C 
     22#define BCMA_MIPS_MIPS74K_INTMASK_INT0  0x0014 
     23#define BCMA_MIPS_MIPS74K_INTMASK(int) \ 
     24        ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0) 
     25#define BCMA_MIPS_MIPS74K_NMIMASK       0x002C 
     26#define BCMA_MIPS_MIPS74K_GPIOSEL       0x0040 
     27#define BCMA_MIPS_MIPS74K_GPIOOUT       0x0044 
     28#define BCMA_MIPS_MIPS74K_GPIOEN        0x0048 
     29#define BCMA_MIPS_MIPS74K_CLKCTLST      0x01E0 
     30 
     31#define BCMA_MIPS_OOBSELOUTA30          0x100 
     32 
     33struct bcma_device; 
     34 
     35struct bcma_drv_mips { 
     36        struct bcma_device *core; 
     37        u8 setup_done:1; 
     38        unsigned int assigned_irqs; 
     39 
     40        u8 flash_buswidth; 
     41        u32 flash_window; 
     42        u32 flash_window_size; 
     43}; 
     44 
     45extern void bcma_core_mips_init(struct bcma_drv_mips *mcore); 
     46 
     47extern unsigned int bcma_core_mips_irq(struct bcma_device *dev); 
     48 
     49#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ 
Note: See TracBrowser for help on using the repository browser.