Path: blob/master/arch/alpha/kernel/core_polaris.c
10817 views
/*1* linux/arch/alpha/kernel/core_polaris.c2*3* POLARIS chip-specific code4*/56#define __EXTERN_INLINE inline7#include <asm/io.h>8#include <asm/core_polaris.h>9#undef __EXTERN_INLINE1011#include <linux/types.h>12#include <linux/pci.h>13#include <linux/sched.h>14#include <linux/init.h>1516#include <asm/ptrace.h>1718#include "proto.h"19#include "pci_impl.h"2021/*22* BIOS32-style PCI interface:23*/2425#define DEBUG_CONFIG 02627#if DEBUG_CONFIG28# define DBG_CFG(args) printk args29#else30# define DBG_CFG(args)31#endif323334/*35* Given a bus, device, and function number, compute resulting36* configuration space address. This is fairly straightforward37* on POLARIS, since the chip itself generates Type 0 or Type 138* cycles automatically depending on the bus number (Bus 0 is39* hardwired to Type 0, all others are Type 1. Peer bridges40* are not supported).41*42* All types:43*44* 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 145* 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 046* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+47* |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|48* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+49*50* 23:16 bus number (8 bits = 128 possible buses)51* 15:11 Device number (5 bits)52* 10:8 function number53* 7:2 register number54*55* Notes:56* The function number selects which function of a multi-function device57* (e.g., scsi and ethernet).58*59* The register selects a DWORD (32 bit) register offset. Hence it60* doesn't get shifted by 2 bits as we want to "drop" the bottom two61* bits.62*/6364static int65mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,66unsigned long *pci_addr, u8 *type1)67{68u8 bus = pbus->number;6970*type1 = (bus == 0) ? 0 : 1;71*pci_addr = (bus << 16) | (device_fn << 8) | (where) |72POLARIS_DENSE_CONFIG_BASE;7374DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"75" returning address 0x%p\n"76bus, device_fn, where, *pci_addr));7778return 0;79}8081static int82polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,83int size, u32 *value)84{85unsigned long addr;86unsigned char type1;8788if (mk_conf_addr(bus, devfn, where, &addr, &type1))89return PCIBIOS_DEVICE_NOT_FOUND;9091switch (size) {92case 1:93*value = __kernel_ldbu(*(vucp)addr);94break;95case 2:96*value = __kernel_ldwu(*(vusp)addr);97break;98case 4:99*value = *(vuip)addr;100break;101}102103return PCIBIOS_SUCCESSFUL;104}105106107static int108polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,109int size, u32 value)110{111unsigned long addr;112unsigned char type1;113114if (mk_conf_addr(bus, devfn, where, &addr, &type1))115return PCIBIOS_DEVICE_NOT_FOUND;116117switch (size) {118case 1:119__kernel_stb(value, *(vucp)addr);120mb();121__kernel_ldbu(*(vucp)addr);122break;123case 2:124__kernel_stw(value, *(vusp)addr);125mb();126__kernel_ldwu(*(vusp)addr);127break;128case 4:129*(vuip)addr = value;130mb();131*(vuip)addr;132break;133}134135return PCIBIOS_SUCCESSFUL;136}137138struct pci_ops polaris_pci_ops =139{140.read = polaris_read_config,141.write = polaris_write_config,142};143144void __init145polaris_init_arch(void)146{147struct pci_controller *hose;148149/* May need to initialize error reporting (see PCICTL0/1), but150* for now assume that the firmware has done the right thing151* already.152*/153#if 0154printk("polaris_init_arch(): trusting firmware for setup\n");155#endif156157/*158* Create our single hose.159*/160161pci_isa_hose = hose = alloc_pci_controller();162hose->io_space = &ioport_resource;163hose->mem_space = &iomem_resource;164hose->index = 0;165166hose->sparse_mem_base = 0;167hose->dense_mem_base = POLARIS_DENSE_MEM_BASE - IDENT_ADDR;168hose->sparse_io_base = 0;169hose->dense_io_base = POLARIS_DENSE_IO_BASE - IDENT_ADDR;170171hose->sg_isa = hose->sg_pci = NULL;172173/* The I/O window is fixed at 2G @ 2G. */174__direct_map_base = 0x80000000;175__direct_map_size = 0x80000000;176}177178static inline void179polaris_pci_clr_err(void)180{181*(vusp)POLARIS_W_STATUS;182/* Write 1's to settable bits to clear errors */183*(vusp)POLARIS_W_STATUS = 0x7800;184mb();185*(vusp)POLARIS_W_STATUS;186}187188void189polaris_machine_check(unsigned long vector, unsigned long la_ptr)190{191/* Clear the error before any reporting. */192mb();193mb();194draina();195polaris_pci_clr_err();196wrmces(0x7);197mb();198199process_mcheck_info(vector, la_ptr, "POLARIS",200mcheck_expected(0));201}202203204