0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/init.h>
0013 #include <linux/pci.h>
0014 #include <linux/irq.h>
0015 #include <linux/irqdomain.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/of_address.h>
0018
0019 #include <asm/byteorder.h>
0020 #include <asm/io.h>
0021 #include <asm/irq.h>
0022 #include <linux/uaccess.h>
0023 #include <asm/machdep.h>
0024 #include <asm/pci-bridge.h>
0025 #include <asm/tsi108.h>
0026 #include <asm/tsi108_pci.h>
0027 #include <asm/tsi108_irq.h>
0028
0029 #undef DEBUG
0030 #ifdef DEBUG
0031 #define DBG(x...) printk(x)
0032 #else
0033 #define DBG(x...)
0034 #endif
0035
0036 #define tsi_mk_config_addr(bus, devfunc, offset) \
0037 ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base)
0038
0039 u32 tsi108_pci_cfg_base;
0040 static u32 tsi108_pci_cfg_phys;
0041 u32 tsi108_csr_vir_base;
0042 static struct irq_domain *pci_irq_host;
0043
0044 extern u32 get_vir_csrbase(void);
0045 extern u32 tsi108_read_reg(u32 reg_offset);
0046 extern void tsi108_write_reg(u32 reg_offset, u32 val);
0047
0048 int
0049 tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc,
0050 int offset, int len, u32 val)
0051 {
0052 volatile unsigned char *cfg_addr;
0053 struct pci_controller *hose = pci_bus_to_host(bus);
0054
0055 if (ppc_md.pci_exclude_device)
0056 if (ppc_md.pci_exclude_device(hose, bus->number, devfunc))
0057 return PCIBIOS_DEVICE_NOT_FOUND;
0058
0059 cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
0060 devfunc, offset) |
0061 (offset & 0x03));
0062
0063 #ifdef DEBUG
0064 printk("PCI CFG write : ");
0065 printk("%d:0x%x:0x%x ", bus->number, devfunc, offset);
0066 printk("%d ADDR=0x%08x ", len, (uint) cfg_addr);
0067 printk("data = 0x%08x\n", val);
0068 #endif
0069
0070 switch (len) {
0071 case 1:
0072 out_8((u8 *) cfg_addr, val);
0073 break;
0074 case 2:
0075 out_le16((u16 *) cfg_addr, val);
0076 break;
0077 default:
0078 out_le32((u32 *) cfg_addr, val);
0079 break;
0080 }
0081
0082 return PCIBIOS_SUCCESSFUL;
0083 }
0084
0085 void tsi108_clear_pci_error(u32 pci_cfg_base)
0086 {
0087 u32 err_stat, err_addr, pci_stat;
0088
0089
0090
0091
0092
0093
0094
0095
0096 err_stat = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS);
0097 err_addr = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_AERR);
0098
0099 if (err_stat & TSI108_PB_ERRCS_ES) {
0100
0101 tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS,
0102 TSI108_PB_ERRCS_ES);
0103
0104
0105 tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ISR,
0106 TSI108_PB_ISR_PBS_RD_ERR);
0107
0108
0109 if ((err_addr & 0xFF000000) == pci_cfg_base) {
0110 pci_stat =
0111 tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR);
0112 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR,
0113 pci_stat);
0114 }
0115 }
0116
0117 return;
0118 }
0119
0120 #define __tsi108_read_pci_config(x, addr, op) \
0121 __asm__ __volatile__( \
0122 " "op" %0,0,%1\n" \
0123 "1: eieio\n" \
0124 "2:\n" \
0125 ".section .fixup,\"ax\"\n" \
0126 "3: li %0,-1\n" \
0127 " b 2b\n" \
0128 ".previous\n" \
0129 EX_TABLE(1b, 3b) \
0130 : "=r"(x) : "r"(addr))
0131
0132 int
0133 tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
0134 int len, u32 * val)
0135 {
0136 volatile unsigned char *cfg_addr;
0137 struct pci_controller *hose = pci_bus_to_host(bus);
0138 u32 temp;
0139
0140 if (ppc_md.pci_exclude_device)
0141 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
0142 return PCIBIOS_DEVICE_NOT_FOUND;
0143
0144 cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
0145 devfn,
0146 offset) | (offset &
0147 0x03));
0148
0149 switch (len) {
0150 case 1:
0151 __tsi108_read_pci_config(temp, cfg_addr, "lbzx");
0152 break;
0153 case 2:
0154 __tsi108_read_pci_config(temp, cfg_addr, "lhbrx");
0155 break;
0156 default:
0157 __tsi108_read_pci_config(temp, cfg_addr, "lwbrx");
0158 break;
0159 }
0160
0161 *val = temp;
0162
0163 #ifdef DEBUG
0164 if ((0xFFFFFFFF != temp) && (0xFFFF != temp) && (0xFF != temp)) {
0165 printk("PCI CFG read : ");
0166 printk("%d:0x%x:0x%x ", bus->number, devfn, offset);
0167 printk("%d ADDR=0x%08x ", len, (uint) cfg_addr);
0168 printk("data = 0x%x\n", *val);
0169 }
0170 #endif
0171 return PCIBIOS_SUCCESSFUL;
0172 }
0173
0174 void tsi108_clear_pci_cfg_error(void)
0175 {
0176 tsi108_clear_pci_error(tsi108_pci_cfg_phys);
0177 }
0178
0179 static struct pci_ops tsi108_direct_pci_ops = {
0180 .read = tsi108_direct_read_config,
0181 .write = tsi108_direct_write_config,
0182 };
0183
0184 int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
0185 {
0186 int len;
0187 struct pci_controller *hose;
0188 struct resource rsrc;
0189 const int *bus_range;
0190 int has_address = 0;
0191
0192
0193 tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE);
0194 tsi108_pci_cfg_phys = cfg_phys;
0195 DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __func__,
0196 tsi108_pci_cfg_base);
0197
0198
0199 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
0200
0201
0202 bus_range = of_get_property(dev, "bus-range", &len);
0203 if (bus_range == NULL || len < 2 * sizeof(int)) {
0204 printk(KERN_WARNING "Can't get bus-range for %pOF, assume"
0205 " bus 0\n", dev);
0206 }
0207
0208 hose = pcibios_alloc_controller(dev);
0209
0210 if (!hose) {
0211 printk("PCI Host bridge init failed\n");
0212 return -ENOMEM;
0213 }
0214
0215 hose->first_busno = bus_range ? bus_range[0] : 0;
0216 hose->last_busno = bus_range ? bus_range[1] : 0xff;
0217
0218 (hose)->ops = &tsi108_direct_pci_ops;
0219
0220 printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. "
0221 "Firmware bus number: %d->%d\n",
0222 rsrc.start, hose->first_busno, hose->last_busno);
0223
0224
0225
0226 pci_process_bridge_OF_ranges(hose, dev, primary);
0227 return 0;
0228 }
0229
0230
0231
0232
0233
0234 static void tsi108_pci_int_mask(u_int irq)
0235 {
0236 u_int irp_cfg;
0237 int int_line = (irq - IRQ_PCI_INTAD_BASE);
0238
0239 irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
0240 mb();
0241 irp_cfg |= (1 << int_line);
0242 irp_cfg &= ~(3 << (8 + (int_line * 2)));
0243 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
0244 mb();
0245 irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
0246 }
0247
0248 static void tsi108_pci_int_unmask(u_int irq)
0249 {
0250 u_int irp_cfg;
0251 int int_line = (irq - IRQ_PCI_INTAD_BASE);
0252
0253 irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
0254 mb();
0255 irp_cfg &= ~(1 << int_line);
0256 irp_cfg |= (3 << (8 + (int_line * 2)));
0257 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
0258 mb();
0259 }
0260
0261 static void __init init_pci_source(void)
0262 {
0263 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL,
0264 0x0000ff00);
0265 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
0266 TSI108_PCI_IRP_ENABLE_P_INT);
0267 mb();
0268 }
0269
0270 static inline unsigned int get_pci_source(void)
0271 {
0272 u_int temp = 0;
0273 int irq = -1;
0274 int i;
0275 u_int pci_irp_stat;
0276 static int mask = 0;
0277
0278
0279 pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
0280 mb();
0281
0282 if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) {
0283
0284 temp =
0285 tsi108_read_reg(TSI108_PCI_OFFSET +
0286 TSI108_PCI_IRP_INTAD) & 0xf;
0287 mb();
0288 for (i = 0; i < 4; i++, mask++) {
0289 if (temp & (1 << mask % 4)) {
0290 irq = IRQ_PCI_INTA + mask % 4;
0291 mask++;
0292 break;
0293 }
0294 }
0295
0296
0297 temp = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
0298 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
0299 temp & ~TSI108_PCI_IRP_ENABLE_P_INT);
0300 mb();
0301 (void)tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
0302 mb();
0303 }
0304 #ifdef DEBUG
0305 else {
0306 printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n");
0307 pci_irp_stat =
0308 tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
0309 temp =
0310 tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD);
0311 mb();
0312 printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp);
0313 temp =
0314 tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
0315 mb();
0316 printk("cfg_ctl=0x%08x ", temp);
0317 temp =
0318 tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
0319 mb();
0320 printk("irp_enable=0x%08x\n", temp);
0321 }
0322 #endif
0323
0324 return irq;
0325 }
0326
0327
0328
0329
0330
0331
0332 static void tsi108_pci_irq_unmask(struct irq_data *d)
0333 {
0334 tsi108_pci_int_unmask(d->irq);
0335
0336
0337 tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
0338 tsi108_read_reg(TSI108_PCI_OFFSET +
0339 TSI108_PCI_IRP_ENABLE) |
0340 TSI108_PCI_IRP_ENABLE_P_INT);
0341 mb();
0342 }
0343
0344 static void tsi108_pci_irq_mask(struct irq_data *d)
0345 {
0346 tsi108_pci_int_mask(d->irq);
0347 }
0348
0349 static void tsi108_pci_irq_ack(struct irq_data *d)
0350 {
0351 tsi108_pci_int_mask(d->irq);
0352 }
0353
0354
0355
0356
0357
0358 static struct irq_chip tsi108_pci_irq = {
0359 .name = "tsi108_PCI_int",
0360 .irq_mask = tsi108_pci_irq_mask,
0361 .irq_ack = tsi108_pci_irq_ack,
0362 .irq_unmask = tsi108_pci_irq_unmask,
0363 };
0364
0365 static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
0366 const u32 *intspec, unsigned int intsize,
0367 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
0368 {
0369 *out_hwirq = intspec[0];
0370 *out_flags = IRQ_TYPE_LEVEL_HIGH;
0371 return 0;
0372 }
0373
0374 static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
0375 irq_hw_number_t hw)
0376 { unsigned int irq;
0377 DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
0378 if ((virq >= 1) && (virq <= 4)){
0379 irq = virq + IRQ_PCI_INTAD_BASE - 1;
0380 irq_set_status_flags(irq, IRQ_LEVEL);
0381 irq_set_chip(irq, &tsi108_pci_irq);
0382 }
0383 return 0;
0384 }
0385
0386 static const struct irq_domain_ops pci_irq_domain_ops = {
0387 .map = pci_irq_host_map,
0388 .xlate = pci_irq_host_xlate,
0389 };
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 void __init tsi108_pci_int_init(struct device_node *node)
0405 {
0406 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
0407
0408 pci_irq_host = irq_domain_add_legacy(node, NR_IRQS_LEGACY, 0, 0,
0409 &pci_irq_domain_ops, NULL);
0410 if (pci_irq_host == NULL) {
0411 printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
0412 return;
0413 }
0414
0415 init_pci_source();
0416 }
0417
0418 void tsi108_irq_cascade(struct irq_desc *desc)
0419 {
0420 struct irq_chip *chip = irq_desc_get_chip(desc);
0421 unsigned int cascade_irq = get_pci_source();
0422
0423 if (cascade_irq)
0424 generic_handle_irq(cascade_irq);
0425
0426 chip->irq_eoi(&desc->irq_data);
0427 }