root/arch/alpha/kernel/core_polaris.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mk_conf_addr
  2. polaris_read_config
  3. polaris_write_config
  4. polaris_init_arch
  5. polaris_pci_clr_err
  6. polaris_machine_check

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

/* [<][>][^][v][top][bottom][index][help] */