Lines Matching +full:pdc +full:- +full:global
1 // SPDX-License-Identifier: GPL-2.0-or-later
7 ** (c) Copyright 1999,2000 Hewlett-Packard Company
9 ** (c) Copyright 2006-2019 Helge Deller
21 ** The different between Built-in Dino and Card-Mode
24 ** Linux drivers can only use Card-Mode Dino if pci devices I/O port
32 ** 2001-06-14 : Clement Moyroud (moyroudc@esiee.fr)
33 ** - added support for the integrated RS232.
53 #include <asm/pdc.h>
70 ** Config accessor functions only pass in the 8-bit bus number
71 ** and not the 8-bit "PCI Segment" number. Each Dino will be
83 #define is_card_dino(id) ((id)->hw_type == HPHW_A_DMA)
84 #define is_cujo(id) ((id)->hversion == 0x682)
123 #define DINO_IRQS 11 /* bits 0-10 are architected */
136 /* #define xxx 0x080 - bit 7 is "default" */
137 /* #define xxx 0x100 - bit 8 not used */
138 /* #define xxx 0x200 - bit 9 not used */
143 struct pci_hba_data hba; /* 'C' inheritance - must be first */
147 int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */
166 * tries to keep a global bus count total so that when we discover an
174 struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_cfg_read()
175 u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; in dino_cfg_read()
177 void __iomem *base_addr = d->hba.base_addr; in dino_cfg_read()
182 spin_lock_irqsave(&d->dinosaur_pen, flags); in dino_cfg_read()
196 spin_unlock_irqrestore(&d->dinosaur_pen, flags); in dino_cfg_read()
209 struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_cfg_write()
210 u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; in dino_cfg_write()
212 void __iomem *base_addr = d->hba.base_addr; in dino_cfg_write()
217 spin_lock_irqsave(&d->dinosaur_pen, flags); in dino_cfg_write()
234 spin_unlock_irqrestore(&d->dinosaur_pen, flags); in dino_cfg_write()
258 spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
260 __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
262 v = read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
263 spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
275 spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
277 __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
279 write##type(val, d->base_addr+DINO_IO_DATA+(addr&mask)); \
280 spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
299 int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS); in dino_mask_irq()
301 DBG(KERN_WARNING "%s(0x%px, %d)\n", __func__, dino_dev, d->irq); in dino_mask_irq()
304 dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq)); in dino_mask_irq()
305 __raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); in dino_mask_irq()
311 int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS); in dino_unmask_irq()
314 DBG(KERN_WARNING "%s(0x%px, %d)\n", __func__, dino_dev, d->irq); in dino_unmask_irq()
322 __raw_readl(dino_dev->hba.base_addr+DINO_IPR); in dino_unmask_irq()
325 dino_dev->imr |= DINO_MASK_IRQ(local_irq); /* used in dino_isr() */ in dino_unmask_irq()
326 __raw_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); in dino_unmask_irq()
337 tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR); in dino_unmask_irq()
341 gsc_writel(dino_dev->gsc_irq.txn_data, dino_dev->gsc_irq.txn_addr); in dino_unmask_irq()
355 return -EINVAL; in dino_set_affinity_irq()
361 dino_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq); in dino_set_affinity_irq()
362 eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data; in dino_set_affinity_irq()
363 __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0); in dino_set_affinity_irq()
372 .name = "GSC-PCI",
395 dino_dev->dino_irr0 = in dino_isr()
397 mask = __raw_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK; in dino_isr()
405 int irq = dino_dev->global_irq[local_irq]; in dino_isr()
419 mask = __raw_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr; in dino_isr()
421 if (--ilr_loop > 0) in dino_isr()
424 dino_dev->hba.base_addr, mask); in dino_isr()
436 dino->global_irq[local_irq] = irq; in dino_assign_irq()
444 switch (dev->id.sversion) { in dino_choose_irq()
451 dino_assign_irq(dino, irq, &dev->irq); in dino_choose_irq()
457 …* (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem…
461 u8 new_irq = dev->irq - 1; in quirk_cirrus_cardbus()
463 pci_name(dev), dev->irq, new_irq); in quirk_cirrus_cardbus()
464 dev->irq = new_irq; in quirk_cirrus_cardbus()
469 /* Check if PCI device is behind a Card-mode Dino. */
474 dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge)); in pci_dev_is_behind_card_dino()
475 return is_card_dino(&dino_dev->hba.dev->id); in pci_dev_is_behind_card_dino()
484 pr_warn("%s: HP HSC-PCI Cards with card-mode Dino not yet supported.\n", in pci_fixup_tulip()
487 memset(&dev->resource[0], 0, sizeof(dev->resource[0])); in pci_fixup_tulip()
488 memset(&dev->resource[1], 0, sizeof(dev->resource[1])); in pci_fixup_tulip()
500 * dino_card_setup - Set up the memory space for a Dino in card mode.
511 struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_card_setup()
516 res = &dino_dev->hba.lmmio_space; in dino_card_setup()
517 res->flags = IORESOURCE_MEM; in dino_card_setup()
519 dev_name(bus->bridge)); in dino_card_setup()
520 res->name = kmalloc(size+1, GFP_KERNEL); in dino_card_setup()
521 if(res->name) in dino_card_setup()
522 strcpy((char *)res->name, name); in dino_card_setup()
524 res->name = dino_dev->hba.lmmio_space.name; in dino_card_setup()
527 if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB, in dino_card_setup()
533 dev_name(bus->bridge)); in dino_card_setup()
535 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { in dino_card_setup()
536 list_del(&dev->bus_list); in dino_card_setup()
541 bus->resource[1] = res; in dino_card_setup()
542 bus->resource[0] = &(dino_dev->hba.io_space); in dino_card_setup()
546 if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB))) in dino_card_setup()
550 i, res->start, base_addr + DINO_IO_ADDR_EN); in dino_card_setup()
560 ** REVISIT: card-mode PCI-PCI expansion chassis do exist. in dino_card_fixup()
564 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { in dino_card_fixup()
565 panic("Card-Mode Dino: PCI-PCI Bridge not supported\n"); in dino_card_fixup()
572 dino_cfg_write(dev->bus, dev->devfn, in dino_card_fixup()
576 ** Program INT_LINE for card-mode devices. in dino_card_fixup()
581 ** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range. in dino_card_fixup()
582 ** The additional "-1" adjusts for skewing the IRQ<->slot. in dino_card_fixup()
584 dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); in dino_card_fixup()
585 dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; in dino_card_fixup()
590 dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq); in dino_card_fixup()
601 struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_fixup_bus()
604 __func__, bus, bus->busn_res.start, in dino_fixup_bus()
605 bus->bridge->platform_data); in dino_fixup_bus()
607 /* Firmware doesn't set up card-mode dino, so we have to */ in dino_fixup_bus()
608 if (is_card_dino(&dino_dev->hba.dev->id)) { in dino_fixup_bus()
609 dino_card_setup(bus, dino_dev->hba.base_addr); in dino_fixup_bus()
610 } else if (bus->parent) { in dino_fixup_bus()
617 if((bus->self->resource[i].flags & in dino_fixup_bus()
621 if(bus->self->resource[i].flags & IORESOURCE_MEM) { in dino_fixup_bus()
624 * is the alignment and start-end is in dino_fixup_bus()
628 …bus->self->resource[i].end = bus->self->resource[i].end - bus->self->resource[i].start + DINO_BRID… in dino_fixup_bus()
629 bus->self->resource[i].start = DINO_BRIDGE_ALIGN; in dino_fixup_bus()
634 dev_name(&bus->self->dev), i, in dino_fixup_bus()
635 &bus->self->resource[i]); in dino_fixup_bus()
636 WARN_ON(pci_assign_resource(bus->self, i)); in dino_fixup_bus()
638 dev_name(&bus->self->dev), i, in dino_fixup_bus()
639 &bus->self->resource[i]); in dino_fixup_bus()
644 list_for_each_entry(dev, &bus->devices, bus_list) { in dino_fixup_bus()
645 if (is_card_dino(&dino_dev->hba.dev->id)) in dino_fixup_bus()
652 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { in dino_fixup_bus()
660 dev->resource[PCI_ROM_RESOURCE].flags = 0; in dino_fixup_bus()
662 if(dev->irq == 255) { in dino_fixup_bus()
670 * pin<->interrupt line mapping varies by bus in dino_fixup_bus()
675 dino_cfg_read(dev->bus, dev->devfn, in dino_fixup_bus()
677 irq_pin = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; in dino_fixup_bus()
680 dino_cfg_write(dev->bus, dev->devfn, in dino_fixup_bus()
682 dino_assign_irq(dino_dev, irq_pin, &dev->irq); in dino_fixup_bus()
684 dev->irq = 65535; in dino_fixup_bus()
689 dino_assign_irq(dino_dev, dev->irq, &dev->irq); in dino_fixup_bus()
710 status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS); in dino_card_init()
713 dino_dev->hba.base_addr+DINO_IO_COMMAND); in dino_card_init()
717 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK); in dino_card_init()
718 __raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN); in dino_card_init()
719 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR); in dino_card_init()
722 /* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */ in dino_card_init()
724 ** PCX-L processors don't support XQL like Dino wants it. in dino_card_init()
725 ** PCX-L2 ignore XQL signal and it doesn't matter. in dino_card_init()
729 __raw_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT); in dino_card_init()
736 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN); in dino_card_init()
738 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE); in dino_card_init()
739 __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR); in dino_card_init()
740 __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR); in dino_card_init()
742 __raw_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM); in dino_card_init()
743 __raw_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL); in dino_card_init()
744 __raw_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM); in dino_card_init()
747 __raw_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR); in dino_card_init()
748 __raw_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR); in dino_card_init()
749 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR); in dino_card_init()
756 __raw_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD); in dino_card_init()
759 ** to recover from the #RESET being de-asserted. in dino_card_init()
761 ** This short-cut speeds up booting significantly. in dino_card_init()
773 * Decoding IO_ADDR_EN only works for Built-in Dino in dino_bridge_init()
774 * since PDC has already initialized this. in dino_bridge_init()
777 io_addr = __raw_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN); in dino_bridge_init()
780 return -ENODEV; in dino_bridge_init()
783 res = &dino_dev->hba.lmmio_space; in dino_bridge_init()
791 end = start + 8 * 1024 * 1024 - 1; in dino_bridge_init()
793 DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, in dino_bridge_init()
796 if(prevres && prevres->end + 1 == start) { in dino_bridge_init()
797 prevres->end = end; in dino_bridge_init()
800 …printk(KERN_ERR "%s is out of resource windows for range %d (0x%lx-0x%lx)\n", name, count, start, … in dino_bridge_init()
804 res->start = start; in dino_bridge_init()
805 res->end = end; in dino_bridge_init()
806 res->flags = IORESOURCE_MEM; in dino_bridge_init()
807 res->name = kmalloc(64, GFP_KERNEL); in dino_bridge_init()
808 if(res->name) in dino_bridge_init()
809 snprintf((char *)res->name, 64, "%s LMMIO %d", in dino_bridge_init()
816 res = &dino_dev->hba.lmmio_space; in dino_bridge_init()
822 result = ccio_request_resource(dino_dev->hba.dev, &res[i]); in dino_bridge_init()
839 pcibios_register_hba(&dino_dev->hba); in dino_common_init()
848 ** still only has 11 IRQ input lines - just map some of them in dino_common_init()
851 dev->irq = gsc_alloc_irq(&dino_dev->gsc_irq); in dino_common_init()
852 eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data; in dino_common_init()
858 if (dev->irq < 0) { in dino_common_init()
863 status = request_irq(dev->irq, dino_isr, 0, name, dino_dev); in dino_common_init()
870 /* Support the serial port which is sometimes attached on built-in in dino_common_init()
881 __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0); in dino_common_init()
887 __raw_readl(dino_dev->hba.base_addr+DINO_IRR0); in dino_common_init()
890 res = &dino_dev->hba.io_space; in dino_common_init()
891 if (!is_cujo(&dev->id)) { in dino_common_init()
892 res->name = "Dino I/O Port"; in dino_common_init()
894 res->name = "Cujo I/O Port"; in dino_common_init()
896 res->start = HBA_PORT_BASE(dino_dev->hba.hba_num); in dino_common_init()
897 res->end = res->start + (HBA_PORT_SPACE_SIZE - 1); in dino_common_init()
898 res->flags = IORESOURCE_IO; /* do not mark it busy ! */ in dino_common_init()
902 name, (unsigned long)res->start, (unsigned long)res->end, in dino_common_init()
903 dino_dev->hba.base_addr); in dino_common_init()
929 ** If so, initialize the chip appropriately (card-mode vs bridge mode).
940 unsigned long hpa = dev->hpa.start; in dino_probe()
944 if (is_card_dino(&dev->id)) { in dino_probe()
947 if (!is_cujo(&dev->id)) { in dino_probe()
948 if (dev->id.hversion_rev < 4) { in dino_probe()
949 version = dino_vers[dev->id.hversion_rev]; in dino_probe()
954 if (dev->id.hversion_rev < 2) { in dino_probe()
955 version = cujo_vers[dev->id.hversion_rev]; in dino_probe()
969 if (is_cujo && dev->id.hversion_rev == 1) { in dino_probe()
980 } else if (!is_cujo && !is_card_dino(&dev->id) && in dino_probe()
981 dev->id.hversion_rev < 3) { in dino_probe()
984 "data corruption. See Service Note Numbers: A4190A-01, A4191A-01.\n" in dino_probe()
987 dev->id.hversion_rev); in dino_probe()
995 printk("dino_init_chip - couldn't alloc dino_device\n"); in dino_probe()
999 dino_dev->hba.dev = dev; in dino_probe()
1000 dino_dev->hba.base_addr = ioremap(hpa, 4096); in dino_probe()
1001 dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND; in dino_probe()
1002 spin_lock_init(&dino_dev->dinosaur_pen); in dino_probe()
1003 dino_dev->hba.iommu = ccio_get_iommu(dev); in dino_probe()
1005 if (is_card_dino(&dev->id)) { in dino_probe()
1014 dev->dev.platform_data = dino_dev; in dino_probe()
1016 pci_add_resource_offset(&resources, &dino_dev->hba.io_space, in dino_probe()
1017 HBA_PORT_BASE(dino_dev->hba.hba_num)); in dino_probe()
1018 if (dino_dev->hba.lmmio_space.flags) in dino_probe()
1019 pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space, in dino_probe()
1020 dino_dev->hba.lmmio_space_offset); in dino_probe()
1021 if (dino_dev->hba.elmmio_space.flags) in dino_probe()
1022 pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space, in dino_probe()
1023 dino_dev->hba.lmmio_space_offset); in dino_probe()
1024 if (dino_dev->hba.gmmio_space.flags) in dino_probe()
1025 pci_add_resource(&resources, &dino_dev->hba.gmmio_space); in dino_probe()
1027 dino_dev->hba.bus_num.start = dino_current_bus; in dino_probe()
1028 dino_dev->hba.bus_num.end = 255; in dino_probe()
1029 dino_dev->hba.bus_num.flags = IORESOURCE_BUS; in dino_probe()
1030 pci_add_resource(&resources, &dino_dev->hba.bus_num); in dino_probe()
1035 dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev, in dino_probe()
1039 dev_name(&dev->dev), dino_current_bus); in dino_probe()
1050 * if it isn't, this global bus number count will fail in dino_probe()
1061 * Unfortunately, the J2240 PDC reports the wrong hversion for the first
1062 * Dino, so we have to test for Dino, Cujo and Dino-in-a-J2240.
1063 * For card-mode Dino, most machines report an sversion of 9D. But 715
1068 { HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */
1070 { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */
1071 { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x682, 0xa }, /* Bridge-mode Cujo */