1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * linux/arch/alpha/kernel/core_polaris.c
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * POLARIS chip-specific code
61da177e4SLinus Torvalds */
71da177e4SLinus Torvalds
81da177e4SLinus Torvalds #define __EXTERN_INLINE inline
91da177e4SLinus Torvalds #include <asm/io.h>
101da177e4SLinus Torvalds #include <asm/core_polaris.h>
111da177e4SLinus Torvalds #undef __EXTERN_INLINE
121da177e4SLinus Torvalds
131da177e4SLinus Torvalds #include <linux/types.h>
141da177e4SLinus Torvalds #include <linux/pci.h>
151da177e4SLinus Torvalds #include <linux/sched.h>
161da177e4SLinus Torvalds #include <linux/init.h>
171da177e4SLinus Torvalds
181da177e4SLinus Torvalds #include <asm/ptrace.h>
191da177e4SLinus Torvalds
201da177e4SLinus Torvalds #include "proto.h"
211da177e4SLinus Torvalds #include "pci_impl.h"
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds /*
241da177e4SLinus Torvalds * BIOS32-style PCI interface:
251da177e4SLinus Torvalds */
261da177e4SLinus Torvalds
271da177e4SLinus Torvalds #define DEBUG_CONFIG 0
281da177e4SLinus Torvalds
291da177e4SLinus Torvalds #if DEBUG_CONFIG
301da177e4SLinus Torvalds # define DBG_CFG(args) printk args
311da177e4SLinus Torvalds #else
321da177e4SLinus Torvalds # define DBG_CFG(args)
331da177e4SLinus Torvalds #endif
341da177e4SLinus Torvalds
351da177e4SLinus Torvalds
361da177e4SLinus Torvalds /*
371da177e4SLinus Torvalds * Given a bus, device, and function number, compute resulting
381da177e4SLinus Torvalds * configuration space address. This is fairly straightforward
391da177e4SLinus Torvalds * on POLARIS, since the chip itself generates Type 0 or Type 1
401da177e4SLinus Torvalds * cycles automatically depending on the bus number (Bus 0 is
411da177e4SLinus Torvalds * hardwired to Type 0, all others are Type 1. Peer bridges
421da177e4SLinus Torvalds * are not supported).
431da177e4SLinus Torvalds *
441da177e4SLinus Torvalds * All types:
451da177e4SLinus Torvalds *
461da177e4SLinus Torvalds * 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
471da177e4SLinus Torvalds * 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
481da177e4SLinus Torvalds * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
491da177e4SLinus Torvalds * |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|
501da177e4SLinus Torvalds * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511da177e4SLinus Torvalds *
521da177e4SLinus Torvalds * 23:16 bus number (8 bits = 128 possible buses)
531da177e4SLinus Torvalds * 15:11 Device number (5 bits)
541da177e4SLinus Torvalds * 10:8 function number
551da177e4SLinus Torvalds * 7:2 register number
561da177e4SLinus Torvalds *
571da177e4SLinus Torvalds * Notes:
581da177e4SLinus Torvalds * The function number selects which function of a multi-function device
591da177e4SLinus Torvalds * (e.g., scsi and ethernet).
601da177e4SLinus Torvalds *
611da177e4SLinus Torvalds * The register selects a DWORD (32 bit) register offset. Hence it
621da177e4SLinus Torvalds * doesn't get shifted by 2 bits as we want to "drop" the bottom two
631da177e4SLinus Torvalds * bits.
641da177e4SLinus Torvalds */
651da177e4SLinus Torvalds
661da177e4SLinus Torvalds static int
mk_conf_addr(struct pci_bus * pbus,unsigned int device_fn,int where,unsigned long * pci_addr,u8 * type1)671da177e4SLinus Torvalds mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
681da177e4SLinus Torvalds unsigned long *pci_addr, u8 *type1)
691da177e4SLinus Torvalds {
701da177e4SLinus Torvalds u8 bus = pbus->number;
711da177e4SLinus Torvalds
721da177e4SLinus Torvalds *type1 = (bus == 0) ? 0 : 1;
731da177e4SLinus Torvalds *pci_addr = (bus << 16) | (device_fn << 8) | (where) |
741da177e4SLinus Torvalds POLARIS_DENSE_CONFIG_BASE;
751da177e4SLinus Torvalds
761da177e4SLinus Torvalds DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
771da177e4SLinus Torvalds " returning address 0x%p\n"
781da177e4SLinus Torvalds bus, device_fn, where, *pci_addr));
791da177e4SLinus Torvalds
801da177e4SLinus Torvalds return 0;
811da177e4SLinus Torvalds }
821da177e4SLinus Torvalds
831da177e4SLinus Torvalds static int
polaris_read_config(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * value)841da177e4SLinus Torvalds polaris_read_config(struct pci_bus *bus, unsigned int devfn, int where,
851da177e4SLinus Torvalds int size, u32 *value)
861da177e4SLinus Torvalds {
871da177e4SLinus Torvalds unsigned long addr;
881da177e4SLinus Torvalds unsigned char type1;
891da177e4SLinus Torvalds
901da177e4SLinus Torvalds if (mk_conf_addr(bus, devfn, where, &addr, &type1))
911da177e4SLinus Torvalds return PCIBIOS_DEVICE_NOT_FOUND;
921da177e4SLinus Torvalds
931da177e4SLinus Torvalds switch (size) {
941da177e4SLinus Torvalds case 1:
951da177e4SLinus Torvalds *value = __kernel_ldbu(*(vucp)addr);
961da177e4SLinus Torvalds break;
971da177e4SLinus Torvalds case 2:
981da177e4SLinus Torvalds *value = __kernel_ldwu(*(vusp)addr);
991da177e4SLinus Torvalds break;
1001da177e4SLinus Torvalds case 4:
1011da177e4SLinus Torvalds *value = *(vuip)addr;
1021da177e4SLinus Torvalds break;
1031da177e4SLinus Torvalds }
1041da177e4SLinus Torvalds
1051da177e4SLinus Torvalds return PCIBIOS_SUCCESSFUL;
1061da177e4SLinus Torvalds }
1071da177e4SLinus Torvalds
1081da177e4SLinus Torvalds
1091da177e4SLinus Torvalds static int
polaris_write_config(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 value)1101da177e4SLinus Torvalds polaris_write_config(struct pci_bus *bus, unsigned int devfn, int where,
1111da177e4SLinus Torvalds int size, u32 value)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds unsigned long addr;
1141da177e4SLinus Torvalds unsigned char type1;
1151da177e4SLinus Torvalds
1161da177e4SLinus Torvalds if (mk_conf_addr(bus, devfn, where, &addr, &type1))
1171da177e4SLinus Torvalds return PCIBIOS_DEVICE_NOT_FOUND;
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds switch (size) {
1201da177e4SLinus Torvalds case 1:
1211da177e4SLinus Torvalds __kernel_stb(value, *(vucp)addr);
1221da177e4SLinus Torvalds mb();
1231da177e4SLinus Torvalds __kernel_ldbu(*(vucp)addr);
1241da177e4SLinus Torvalds break;
1251da177e4SLinus Torvalds case 2:
1261da177e4SLinus Torvalds __kernel_stw(value, *(vusp)addr);
1271da177e4SLinus Torvalds mb();
1281da177e4SLinus Torvalds __kernel_ldwu(*(vusp)addr);
1291da177e4SLinus Torvalds break;
1301da177e4SLinus Torvalds case 4:
1311da177e4SLinus Torvalds *(vuip)addr = value;
1321da177e4SLinus Torvalds mb();
1331da177e4SLinus Torvalds *(vuip)addr;
1341da177e4SLinus Torvalds break;
1351da177e4SLinus Torvalds }
1361da177e4SLinus Torvalds
1371da177e4SLinus Torvalds return PCIBIOS_SUCCESSFUL;
1381da177e4SLinus Torvalds }
1391da177e4SLinus Torvalds
1401da177e4SLinus Torvalds struct pci_ops polaris_pci_ops =
1411da177e4SLinus Torvalds {
1421da177e4SLinus Torvalds .read = polaris_read_config,
1431da177e4SLinus Torvalds .write = polaris_write_config,
1441da177e4SLinus Torvalds };
1451da177e4SLinus Torvalds
1461da177e4SLinus Torvalds void __init
polaris_init_arch(void)1471da177e4SLinus Torvalds polaris_init_arch(void)
1481da177e4SLinus Torvalds {
1491da177e4SLinus Torvalds struct pci_controller *hose;
1501da177e4SLinus Torvalds
1511da177e4SLinus Torvalds /* May need to initialize error reporting (see PCICTL0/1), but
1521da177e4SLinus Torvalds * for now assume that the firmware has done the right thing
1531da177e4SLinus Torvalds * already.
1541da177e4SLinus Torvalds */
1551da177e4SLinus Torvalds #if 0
1561da177e4SLinus Torvalds printk("polaris_init_arch(): trusting firmware for setup\n");
1571da177e4SLinus Torvalds #endif
1581da177e4SLinus Torvalds
1591da177e4SLinus Torvalds /*
1601da177e4SLinus Torvalds * Create our single hose.
1611da177e4SLinus Torvalds */
1621da177e4SLinus Torvalds
1631da177e4SLinus Torvalds pci_isa_hose = hose = alloc_pci_controller();
1641da177e4SLinus Torvalds hose->io_space = &ioport_resource;
1651da177e4SLinus Torvalds hose->mem_space = &iomem_resource;
1661da177e4SLinus Torvalds hose->index = 0;
1671da177e4SLinus Torvalds
1681da177e4SLinus Torvalds hose->sparse_mem_base = 0;
1691da177e4SLinus Torvalds hose->dense_mem_base = POLARIS_DENSE_MEM_BASE - IDENT_ADDR;
1701da177e4SLinus Torvalds hose->sparse_io_base = 0;
1711da177e4SLinus Torvalds hose->dense_io_base = POLARIS_DENSE_IO_BASE - IDENT_ADDR;
1721da177e4SLinus Torvalds
1731da177e4SLinus Torvalds hose->sg_isa = hose->sg_pci = NULL;
1741da177e4SLinus Torvalds
1751da177e4SLinus Torvalds /* The I/O window is fixed at 2G @ 2G. */
1761da177e4SLinus Torvalds __direct_map_base = 0x80000000;
1771da177e4SLinus Torvalds __direct_map_size = 0x80000000;
1781da177e4SLinus Torvalds }
1791da177e4SLinus Torvalds
1801da177e4SLinus Torvalds static inline void
polaris_pci_clr_err(void)1811da177e4SLinus Torvalds polaris_pci_clr_err(void)
1821da177e4SLinus Torvalds {
1831da177e4SLinus Torvalds *(vusp)POLARIS_W_STATUS;
1841da177e4SLinus Torvalds /* Write 1's to settable bits to clear errors */
1851da177e4SLinus Torvalds *(vusp)POLARIS_W_STATUS = 0x7800;
1861da177e4SLinus Torvalds mb();
1871da177e4SLinus Torvalds *(vusp)POLARIS_W_STATUS;
1881da177e4SLinus Torvalds }
1891da177e4SLinus Torvalds
1901da177e4SLinus Torvalds void
polaris_machine_check(unsigned long vector,unsigned long la_ptr)1914fa1970aSAl Viro polaris_machine_check(unsigned long vector, unsigned long la_ptr)
1921da177e4SLinus Torvalds {
1931da177e4SLinus Torvalds /* Clear the error before any reporting. */
1941da177e4SLinus Torvalds mb();
1951da177e4SLinus Torvalds mb();
1961da177e4SLinus Torvalds draina();
1971da177e4SLinus Torvalds polaris_pci_clr_err();
1981da177e4SLinus Torvalds wrmces(0x7);
1991da177e4SLinus Torvalds mb();
2001da177e4SLinus Torvalds
2014fa1970aSAl Viro process_mcheck_info(vector, la_ptr, "POLARIS",
2021da177e4SLinus Torvalds mcheck_expected(0));
2031da177e4SLinus Torvalds }
204