linux/arch/alpha/kernel/core_polaris.c
<<
>>
Prefs
   1/*
   2 *      linux/arch/alpha/kernel/core_polaris.c
   3 *
   4 * POLARIS chip-specific code
   5 */
   6
   7#define __EXTERN_INLINE inline
   8#include <asm/io.h>
   9#include <asm/core_polaris.h>
  10#undef __EXTERN_INLINE
  11
  12#include <linux/types.h>
  13#include <linux/pci.h>
  14#include <linux/sched.h>
  15#include <linux/init.h>
  16
  17#include <asm/ptrace.h>
  18
  19#include "proto.h"
  20#include "pci_impl.h"
  21
  22/*
  23 * BIOS32-style PCI interface:
  24 */
  25
  26#define DEBUG_CONFIG 0
  27
  28#if DEBUG_CONFIG
  29# define DBG_CFG(args)  printk args
  30#else
  31# define DBG_CFG(args)
  32#endif
  33
  34
  35/*
  36 * Given a bus, device, and function number, compute resulting
  37 * configuration space address.  This is fairly straightforward
  38 * on POLARIS, since the chip itself generates Type 0 or Type 1
  39 * cycles automatically depending on the bus number (Bus 0 is
  40 * hardwired to Type 0, all others are Type 1.  Peer bridges
  41 * are not supported).
  42 *
  43 * All types:
  44 *
  45 *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
  46 *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
  47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  48 * |1|1|1|1|1|0|0|1|1|1|1|1|1|1|1|0|B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|x|x|
  49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  50 *
  51 *      23:16   bus number (8 bits = 128 possible buses)
  52 *      15:11   Device number (5 bits)
  53 *      10:8    function number
  54 *       7:2    register number
  55 *  
  56 * Notes:
  57 *      The function number selects which function of a multi-function device 
  58 *      (e.g., scsi and ethernet).
  59 * 
  60 *      The register selects a DWORD (32 bit) register offset.  Hence it
  61 *      doesn't get shifted by 2 bits as we want to "drop" the bottom two
  62 *      bits.
  63 */
  64
  65static int
  66mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
  67             unsigned long *pci_addr, u8 *type1)
  68{
  69        u8 bus = pbus->number;
  70
  71        *type1 = (bus == 0) ? 0 : 1;
  72        *pci_addr = (bus << 16) | (device_fn << 8) | (where) |
  73                    POLARIS_DENSE_CONFIG_BASE;
  74
  75        DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
  76                 " returning address 0x%p\n"
  77                 bus, device_fn, where, *pci_addr));
  78
  79        return 0;
  80}
  81
  82static int
  83polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,
  84                    int size, u32 *value)
  85{
  86        unsigned long addr;
  87        unsigned char type1;
  88
  89        if (mk_conf_addr(bus, devfn, where, &addr, &type1))
  90                return PCIBIOS_DEVICE_NOT_FOUND;
  91
  92        switch (size) {
  93        case 1:
  94                *value = __kernel_ldbu(*(vucp)addr);
  95                break;
  96        case 2:
  97                *value = __kernel_ldwu(*(vusp)addr);
  98                break;
  99        case 4:
 100                *value = *(vuip)addr;
 101                break;
 102        }
 103
 104        return PCIBIOS_SUCCESSFUL;
 105}
 106
 107
 108static int 
 109polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,
 110                     int size, u32 value)
 111{
 112        unsigned long addr;
 113        unsigned char type1;
 114
 115        if (mk_conf_addr(bus, devfn, where, &addr, &type1))
 116                return PCIBIOS_DEVICE_NOT_FOUND;
 117
 118        switch (size) {
 119        case 1:
 120                __kernel_stb(value, *(vucp)addr);
 121                mb();
 122                __kernel_ldbu(*(vucp)addr);
 123                break;
 124        case 2:
 125                __kernel_stw(value, *(vusp)addr);
 126                mb();
 127                __kernel_ldwu(*(vusp)addr);
 128                break;
 129        case 4:
 130                *(vuip)addr = value;
 131                mb();
 132                *(vuip)addr;
 133                break;
 134        }
 135
 136        return PCIBIOS_SUCCESSFUL;
 137}
 138
 139struct pci_ops polaris_pci_ops = 
 140{
 141        .read =         polaris_read_config,
 142        .write =        polaris_write_config,
 143};
 144
 145void __init
 146polaris_init_arch(void)
 147{
 148        struct pci_controller *hose;
 149
 150        /* May need to initialize error reporting (see PCICTL0/1), but
 151         * for now assume that the firmware has done the right thing
 152         * already.
 153         */
 154#if 0
 155        printk("polaris_init_arch(): trusting firmware for setup\n");
 156#endif
 157
 158        /*
 159         * Create our single hose.
 160         */
 161
 162        pci_isa_hose = hose = alloc_pci_controller();
 163        hose->io_space = &ioport_resource;
 164        hose->mem_space = &iomem_resource;
 165        hose->index = 0;
 166
 167        hose->sparse_mem_base = 0;
 168        hose->dense_mem_base = POLARIS_DENSE_MEM_BASE - IDENT_ADDR;
 169        hose->sparse_io_base = 0;
 170        hose->dense_io_base = POLARIS_DENSE_IO_BASE - IDENT_ADDR;
 171
 172        hose->sg_isa = hose->sg_pci = NULL;
 173
 174        /* The I/O window is fixed at 2G @ 2G.  */
 175        __direct_map_base = 0x80000000;
 176        __direct_map_size = 0x80000000;
 177}
 178
 179static inline void
 180polaris_pci_clr_err(void)
 181{
 182        *(vusp)POLARIS_W_STATUS;
 183        /* Write 1's to settable bits to clear errors */
 184        *(vusp)POLARIS_W_STATUS = 0x7800;
 185        mb();
 186        *(vusp)POLARIS_W_STATUS;
 187}
 188
 189void
 190polaris_machine_check(unsigned long vector, unsigned long la_ptr)
 191{
 192        /* Clear the error before any reporting.  */
 193        mb();
 194        mb();
 195        draina();
 196        polaris_pci_clr_err();
 197        wrmces(0x7);
 198        mb();
 199
 200        process_mcheck_info(vector, la_ptr, "POLARIS",
 201                            mcheck_expected(0));
 202}
 203
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.