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 */
148 int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */
159 /* Check if PCI device is behind a Card-mode Dino. */
164 dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge)); in pci_dev_is_behind_card_dino()
165 return is_card_dino(&dino_dev->hba.dev->id); in pci_dev_is_behind_card_dino()
176 * tries to keep a global bus count total so that when we discover an
184 struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_cfg_read()
185 u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; in dino_cfg_read()
187 void __iomem *base_addr = d->hba.base_addr; in dino_cfg_read()
192 spin_lock_irqsave(&d->dinosaur_pen, flags); in dino_cfg_read()
206 spin_unlock_irqrestore(&d->dinosaur_pen, flags); in dino_cfg_read()
219 struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_cfg_write()
220 u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; in dino_cfg_write()
222 void __iomem *base_addr = d->hba.base_addr; in dino_cfg_write()
227 spin_lock_irqsave(&d->dinosaur_pen, flags); in dino_cfg_write()
244 spin_unlock_irqrestore(&d->dinosaur_pen, flags); in dino_cfg_write()
268 spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
270 __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
272 v = read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
273 spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
285 spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
287 __raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
289 write##type(val, d->base_addr+DINO_IO_DATA+(addr&mask)); \
290 spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
309 int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS); in dino_mask_irq()
311 DBG(KERN_WARNING "%s(0x%px, %d)\n", __func__, dino_dev, d->irq); in dino_mask_irq()
314 dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq)); in dino_mask_irq()
315 __raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); in dino_mask_irq()
321 int local_irq = gsc_find_local_irq(d->irq, dino_dev->global_irq, DINO_LOCAL_IRQS); in dino_unmask_irq()
324 DBG(KERN_WARNING "%s(0x%px, %d)\n", __func__, dino_dev, d->irq); in dino_unmask_irq()
332 __raw_readl(dino_dev->hba.base_addr+DINO_IPR); in dino_unmask_irq()
335 dino_dev->imr |= DINO_MASK_IRQ(local_irq); /* used in dino_isr() */ in dino_unmask_irq()
336 __raw_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR); in dino_unmask_irq()
347 tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR); in dino_unmask_irq()
351 gsc_writel(dino_dev->txn_data, dino_dev->txn_addr); in dino_unmask_irq()
356 .name = "GSC-PCI",
376 dino_dev->dino_irr0 = in dino_isr()
378 mask = __raw_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK; in dino_isr()
386 int irq = dino_dev->global_irq[local_irq]; in dino_isr()
400 mask = __raw_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr; in dino_isr()
402 if (--ilr_loop > 0) in dino_isr()
405 dino_dev->hba.base_addr, mask); in dino_isr()
417 dino->global_irq[local_irq] = irq; in dino_assign_irq()
425 switch (dev->id.sversion) { in dino_choose_irq()
432 dino_assign_irq(dino, irq, &dev->irq); in dino_choose_irq()
438 …* (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem…
442 u8 new_irq = dev->irq - 1; in quirk_cirrus_cardbus()
444 pci_name(dev), dev->irq, new_irq); in quirk_cirrus_cardbus()
445 dev->irq = new_irq; in quirk_cirrus_cardbus()
456 pr_warn("%s: HP HSC-PCI Cards with card-mode Dino not yet supported.\n", in pci_fixup_tulip()
459 memset(&dev->resource[0], 0, sizeof(dev->resource[0])); in pci_fixup_tulip()
460 memset(&dev->resource[1], 0, sizeof(dev->resource[1])); in pci_fixup_tulip()
472 * dino_card_setup - Set up the memory space for a Dino in card mode.
483 struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_card_setup()
488 res = &dino_dev->hba.lmmio_space; in dino_card_setup()
489 res->flags = IORESOURCE_MEM; in dino_card_setup()
491 dev_name(bus->bridge)); in dino_card_setup()
492 res->name = kmalloc(size+1, GFP_KERNEL); in dino_card_setup()
493 if(res->name) in dino_card_setup()
494 strcpy((char *)res->name, name); in dino_card_setup()
496 res->name = dino_dev->hba.lmmio_space.name; in dino_card_setup()
499 if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB, in dino_card_setup()
505 dev_name(bus->bridge)); in dino_card_setup()
507 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { in dino_card_setup()
508 list_del(&dev->bus_list); in dino_card_setup()
513 bus->resource[1] = res; in dino_card_setup()
514 bus->resource[0] = &(dino_dev->hba.io_space); in dino_card_setup()
518 if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB))) in dino_card_setup()
522 i, res->start, base_addr + DINO_IO_ADDR_EN); in dino_card_setup()
532 ** REVISIT: card-mode PCI-PCI expansion chassis do exist. in dino_card_fixup()
536 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { in dino_card_fixup()
537 panic("Card-Mode Dino: PCI-PCI Bridge not supported\n"); in dino_card_fixup()
544 dino_cfg_write(dev->bus, dev->devfn, in dino_card_fixup()
548 ** Program INT_LINE for card-mode devices. in dino_card_fixup()
553 ** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range. in dino_card_fixup()
554 ** The additional "-1" adjusts for skewing the IRQ<->slot. in dino_card_fixup()
556 dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); in dino_card_fixup()
557 dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; in dino_card_fixup()
562 dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq); in dino_card_fixup()
573 struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); in dino_fixup_bus()
576 __func__, bus, bus->busn_res.start, in dino_fixup_bus()
577 bus->bridge->platform_data); in dino_fixup_bus()
579 /* Firmware doesn't set up card-mode dino, so we have to */ in dino_fixup_bus()
580 if (is_card_dino(&dino_dev->hba.dev->id)) { in dino_fixup_bus()
581 dino_card_setup(bus, dino_dev->hba.base_addr); in dino_fixup_bus()
582 } else if (bus->parent) { in dino_fixup_bus()
589 if((bus->self->resource[i].flags & in dino_fixup_bus()
593 if(bus->self->resource[i].flags & IORESOURCE_MEM) { in dino_fixup_bus()
596 * is the alignment and start-end is in dino_fixup_bus()
600 …bus->self->resource[i].end = bus->self->resource[i].end - bus->self->resource[i].start + DINO_BRID… in dino_fixup_bus()
601 bus->self->resource[i].start = DINO_BRIDGE_ALIGN; in dino_fixup_bus()
606 dev_name(&bus->self->dev), i, in dino_fixup_bus()
607 &bus->self->resource[i]); in dino_fixup_bus()
608 WARN_ON(pci_assign_resource(bus->self, i)); in dino_fixup_bus()
610 dev_name(&bus->self->dev), i, in dino_fixup_bus()
611 &bus->self->resource[i]); in dino_fixup_bus()
616 list_for_each_entry(dev, &bus->devices, bus_list) { in dino_fixup_bus()
617 if (is_card_dino(&dino_dev->hba.dev->id)) in dino_fixup_bus()
624 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { in dino_fixup_bus()
632 dev->resource[PCI_ROM_RESOURCE].flags = 0; in dino_fixup_bus()
634 if(dev->irq == 255) { in dino_fixup_bus()
642 * pin<->interrupt line mapping varies by bus in dino_fixup_bus()
647 dino_cfg_read(dev->bus, dev->devfn, in dino_fixup_bus()
649 irq_pin = pci_swizzle_interrupt_pin(dev, irq_pin) - 1; in dino_fixup_bus()
652 dino_cfg_write(dev->bus, dev->devfn, in dino_fixup_bus()
654 dino_assign_irq(dino_dev, irq_pin, &dev->irq); in dino_fixup_bus()
656 dev->irq = 65535; in dino_fixup_bus()
661 dino_assign_irq(dino_dev, dev->irq, &dev->irq); in dino_fixup_bus()
682 status = __raw_readl(dino_dev->hba.base_addr+DINO_IO_STATUS); in dino_card_init()
685 dino_dev->hba.base_addr+DINO_IO_COMMAND); in dino_card_init()
689 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK); in dino_card_init()
690 __raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN); in dino_card_init()
691 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR); in dino_card_init()
694 /* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */ in dino_card_init()
696 ** PCX-L processors don't support XQL like Dino wants it. in dino_card_init()
697 ** PCX-L2 ignore XQL signal and it doesn't matter. in dino_card_init()
701 __raw_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT); in dino_card_init()
708 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN); in dino_card_init()
710 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE); in dino_card_init()
711 __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR); in dino_card_init()
712 __raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR); in dino_card_init()
714 __raw_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM); in dino_card_init()
715 __raw_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL); in dino_card_init()
716 __raw_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM); in dino_card_init()
719 __raw_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR); in dino_card_init()
720 __raw_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR); in dino_card_init()
721 __raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR); in dino_card_init()
728 __raw_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD); in dino_card_init()
731 ** to recover from the #RESET being de-asserted. in dino_card_init()
733 ** This short-cut speeds up booting significantly. in dino_card_init()
745 * Decoding IO_ADDR_EN only works for Built-in Dino in dino_bridge_init()
746 * since PDC has already initialized this. in dino_bridge_init()
749 io_addr = __raw_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN); in dino_bridge_init()
752 return -ENODEV; in dino_bridge_init()
755 res = &dino_dev->hba.lmmio_space; in dino_bridge_init()
763 end = start + 8 * 1024 * 1024 - 1; in dino_bridge_init()
765 DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, in dino_bridge_init()
768 if(prevres && prevres->end + 1 == start) { in dino_bridge_init()
769 prevres->end = end; in dino_bridge_init()
772 …printk(KERN_ERR "%s is out of resource windows for range %d (0x%lx-0x%lx)\n", name, count, start, … in dino_bridge_init()
776 res->start = start; in dino_bridge_init()
777 res->end = end; in dino_bridge_init()
778 res->flags = IORESOURCE_MEM; in dino_bridge_init()
779 res->name = kmalloc(64, GFP_KERNEL); in dino_bridge_init()
780 if(res->name) in dino_bridge_init()
781 snprintf((char *)res->name, 64, "%s LMMIO %d", in dino_bridge_init()
788 res = &dino_dev->hba.lmmio_space; in dino_bridge_init()
794 result = ccio_request_resource(dino_dev->hba.dev, &res[i]); in dino_bridge_init()
812 pcibios_register_hba(&dino_dev->hba); in dino_common_init()
821 ** still only has 11 IRQ input lines - just map some of them in dino_common_init()
824 dev->irq = gsc_alloc_irq(&gsc_irq); in dino_common_init()
825 dino_dev->txn_addr = gsc_irq.txn_addr; in dino_common_init()
826 dino_dev->txn_data = gsc_irq.txn_data; in dino_common_init()
833 if (dev->irq < 0) { in dino_common_init()
838 status = request_irq(dev->irq, dino_isr, 0, name, dino_dev); in dino_common_init()
845 /* Support the serial port which is sometimes attached on built-in in dino_common_init()
856 __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0); in dino_common_init()
862 __raw_readl(dino_dev->hba.base_addr+DINO_IRR0); in dino_common_init()
865 res = &dino_dev->hba.io_space; in dino_common_init()
866 if (!is_cujo(&dev->id)) { in dino_common_init()
867 res->name = "Dino I/O Port"; in dino_common_init()
869 res->name = "Cujo I/O Port"; in dino_common_init()
871 res->start = HBA_PORT_BASE(dino_dev->hba.hba_num); in dino_common_init()
872 res->end = res->start + (HBA_PORT_SPACE_SIZE - 1); in dino_common_init()
873 res->flags = IORESOURCE_IO; /* do not mark it busy ! */ in dino_common_init()
877 name, (unsigned long)res->start, (unsigned long)res->end, in dino_common_init()
878 dino_dev->hba.base_addr); in dino_common_init()
906 ** If so, initialize the chip appropriately (card-mode vs bridge mode).
917 unsigned long hpa = dev->hpa.start; in dino_probe()
921 if (is_card_dino(&dev->id)) { in dino_probe()
924 if (!is_cujo(&dev->id)) { in dino_probe()
925 if (dev->id.hversion_rev < 4) { in dino_probe()
926 version = dino_vers[dev->id.hversion_rev]; in dino_probe()
931 if (dev->id.hversion_rev < 2) { in dino_probe()
932 version = cujo_vers[dev->id.hversion_rev]; in dino_probe()
946 if (is_cujo && dev->id.hversion_rev == 1) { in dino_probe()
957 } else if (!is_cujo && !is_card_dino(&dev->id) && in dino_probe()
958 dev->id.hversion_rev < 3) { in dino_probe()
961 "data corruption. See Service Note Numbers: A4190A-01, A4191A-01.\n" in dino_probe()
964 dev->id.hversion_rev); in dino_probe()
972 printk("dino_init_chip - couldn't alloc dino_device\n"); in dino_probe()
976 dino_dev->hba.dev = dev; in dino_probe()
977 dino_dev->hba.base_addr = ioremap(hpa, 4096); in dino_probe()
978 dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND; in dino_probe()
979 spin_lock_init(&dino_dev->dinosaur_pen); in dino_probe()
980 dino_dev->hba.iommu = ccio_get_iommu(dev); in dino_probe()
982 if (is_card_dino(&dev->id)) { in dino_probe()
991 dev->dev.platform_data = dino_dev; in dino_probe()
993 pci_add_resource_offset(&resources, &dino_dev->hba.io_space, in dino_probe()
994 HBA_PORT_BASE(dino_dev->hba.hba_num)); in dino_probe()
995 if (dino_dev->hba.lmmio_space.flags) in dino_probe()
996 pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space, in dino_probe()
997 dino_dev->hba.lmmio_space_offset); in dino_probe()
998 if (dino_dev->hba.elmmio_space.flags) in dino_probe()
999 pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space, in dino_probe()
1000 dino_dev->hba.lmmio_space_offset); in dino_probe()
1001 if (dino_dev->hba.gmmio_space.flags) in dino_probe()
1002 pci_add_resource(&resources, &dino_dev->hba.gmmio_space); in dino_probe()
1004 dino_dev->hba.bus_num.start = dino_current_bus; in dino_probe()
1005 dino_dev->hba.bus_num.end = 255; in dino_probe()
1006 dino_dev->hba.bus_num.flags = IORESOURCE_BUS; in dino_probe()
1007 pci_add_resource(&resources, &dino_dev->hba.bus_num); in dino_probe()
1012 dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev, in dino_probe()
1016 dev_name(&dev->dev), dino_current_bus); in dino_probe()
1027 * if it isn't, this global bus number count will fail in dino_probe()
1038 * Unfortunately, the J2240 PDC reports the wrong hversion for the first
1039 * Dino, so we have to test for Dino, Cujo and Dino-in-a-J2240.
1040 * For card-mode Dino, most machines report an sversion of 9D. But 715
1045 { HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */
1047 { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */
1048 { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x682, 0xa }, /* Bridge-mode Cujo */