0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/types.h>
0022 #include <linux/pci.h>
0023 #include <linux/kernel.h>
0024 #include <linux/init.h>
0025 #include <linux/mm.h>
0026 #include <linux/console.h>
0027 #include <linux/tty.h>
0028
0029 #include <asm/sibyte/bcm1480_regs.h>
0030 #include <asm/sibyte/bcm1480_scd.h>
0031 #include <asm/sibyte/board.h>
0032 #include <asm/io.h>
0033
0034
0035
0036
0037
0038 #define CFGOFFSET(bus, devfn, where) (((bus)<<16)+((devfn)<<8)+(where))
0039 #define CFGADDR(bus, devfn, where) CFGOFFSET((bus)->number, (devfn), where)
0040
0041 static void *ht_cfg_space;
0042
0043 #define PCI_BUS_ENABLED 1
0044 #define PCI_DEVICE_MODE 2
0045
0046 static int bcm1480ht_bus_status;
0047
0048 #define PCI_BRIDGE_DEVICE 0
0049 #define HT_BRIDGE_DEVICE 1
0050
0051
0052
0053
0054
0055 unsigned long ht_eoi_space;
0056
0057
0058
0059
0060 static inline u32 READCFG32(u32 addr)
0061 {
0062 return *(u32 *)(ht_cfg_space + (addr&~3));
0063 }
0064
0065 static inline void WRITECFG32(u32 addr, u32 data)
0066 {
0067 *(u32 *)(ht_cfg_space + (addr & ~3)) = data;
0068 }
0069
0070
0071
0072
0073
0074
0075 static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
0076 {
0077 u32 devno;
0078
0079 if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
0080 return 0;
0081
0082 if (bus->number == 0) {
0083 devno = PCI_SLOT(devfn);
0084 if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
0085 return 0;
0086 }
0087 return 1;
0088 }
0089
0090
0091
0092
0093
0094
0095
0096 static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
0097 int where, int size, u32 * val)
0098 {
0099 u32 data = 0;
0100
0101 if ((size == 2) && (where & 1))
0102 return PCIBIOS_BAD_REGISTER_NUMBER;
0103 else if ((size == 4) && (where & 3))
0104 return PCIBIOS_BAD_REGISTER_NUMBER;
0105
0106 if (bcm1480ht_can_access(bus, devfn))
0107 data = READCFG32(CFGADDR(bus, devfn, where));
0108 else
0109 data = 0xFFFFFFFF;
0110
0111 if (size == 1)
0112 *val = (data >> ((where & 3) << 3)) & 0xff;
0113 else if (size == 2)
0114 *val = (data >> ((where & 3) << 3)) & 0xffff;
0115 else
0116 *val = data;
0117
0118 return PCIBIOS_SUCCESSFUL;
0119 }
0120
0121 static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
0122 int where, int size, u32 val)
0123 {
0124 u32 cfgaddr = CFGADDR(bus, devfn, where);
0125 u32 data = 0;
0126
0127 if ((size == 2) && (where & 1))
0128 return PCIBIOS_BAD_REGISTER_NUMBER;
0129 else if ((size == 4) && (where & 3))
0130 return PCIBIOS_BAD_REGISTER_NUMBER;
0131
0132 if (!bcm1480ht_can_access(bus, devfn))
0133 return PCIBIOS_BAD_REGISTER_NUMBER;
0134
0135 data = READCFG32(cfgaddr);
0136
0137 if (size == 1)
0138 data = (data & ~(0xff << ((where & 3) << 3))) |
0139 (val << ((where & 3) << 3));
0140 else if (size == 2)
0141 data = (data & ~(0xffff << ((where & 3) << 3))) |
0142 (val << ((where & 3) << 3));
0143 else
0144 data = val;
0145
0146 WRITECFG32(cfgaddr, data);
0147
0148 return PCIBIOS_SUCCESSFUL;
0149 }
0150
0151 static int bcm1480ht_pcibios_get_busno(void)
0152 {
0153 return 0;
0154 }
0155
0156 struct pci_ops bcm1480ht_pci_ops = {
0157 .read = bcm1480ht_pcibios_read,
0158 .write = bcm1480ht_pcibios_write,
0159 };
0160
0161 static struct resource bcm1480ht_mem_resource = {
0162 .name = "BCM1480 HT MEM",
0163 .start = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES,
0164 .end = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES + 0x1fffffffUL,
0165 .flags = IORESOURCE_MEM,
0166 };
0167
0168 static struct resource bcm1480ht_io_resource = {
0169 .name = "BCM1480 HT I/O",
0170 .start = A_BCM1480_PHYS_HT_IO_MATCH_BYTES,
0171 .end = A_BCM1480_PHYS_HT_IO_MATCH_BYTES + 0x01ffffffUL,
0172 .flags = IORESOURCE_IO,
0173 };
0174
0175 struct pci_controller bcm1480ht_controller = {
0176 .pci_ops = &bcm1480ht_pci_ops,
0177 .mem_resource = &bcm1480ht_mem_resource,
0178 .io_resource = &bcm1480ht_io_resource,
0179 .index = 1,
0180 .get_busno = bcm1480ht_pcibios_get_busno,
0181 .io_offset = A_BCM1480_PHYS_HT_IO_MATCH_BYTES,
0182 };
0183
0184 static int __init bcm1480ht_pcibios_init(void)
0185 {
0186 ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
0187
0188
0189 bcm1480ht_bus_status |= PCI_BUS_ENABLED;
0190
0191 ht_eoi_space = (unsigned long)
0192 ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
0193 4 * 1024 * 1024);
0194 bcm1480ht_controller.io_map_base = (unsigned long)
0195 ioremap(A_BCM1480_PHYS_HT_IO_MATCH_BYTES, 65536);
0196 bcm1480ht_controller.io_map_base -= bcm1480ht_controller.io_offset;
0197
0198 register_pci_controller(&bcm1480ht_controller);
0199
0200 return 0;
0201 }
0202
0203 arch_initcall(bcm1480ht_pcibios_init);