X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-parisc%2Fpci.h;h=77bbafb7f73e2fb15b87a5a179b461e451054d7c;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=b091f0845662251c76191ac8b5818d7a74ce44ff;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index b091f0845..77bbafb7f 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -4,6 +4,8 @@ #include #include + + /* ** HP PCI platforms generally support multiple bus adapters. ** (workstations 1-~4, servers 2-~32) @@ -16,26 +18,16 @@ */ #define PCI_MAX_BUSSES 256 -/* [soapbox on] -** Who the hell can develop stuff without ASSERT or VASSERT? -** No one understands all the modules across all platforms. -** For linux add another dimension - processor architectures. -** -** This should be a standard/global macro used liberally -** in all code. Every respectable engineer I know in HP -** would support this argument. - grant -** [soapbox off] -*/ -#ifdef PCI_DEBUG -#define ASSERT(expr) \ - if(!(expr)) { \ - printk("\n%s:%d: Assertion " #expr " failed!\n", \ - __FILE__, __LINE__); \ - panic(#expr); \ - } -#else -#define ASSERT(expr) -#endif + +/* To be used as: mdelay(pci_post_reset_delay); + * + * post_reset is the time the kernel should stall to prevent anyone from + * accessing the PCI bus once #RESET is de-asserted. + * PCI spec somewhere says 1 second but with multi-PCI bus systems, + * this makes the boot time much longer than necessary. + * 20ms seems to work for all the HP PCI implementations to date. + */ +#define pci_post_reset_delay 50 /* @@ -48,7 +40,7 @@ ** Data needed by pcibios layer belongs here. */ struct pci_hba_data { - unsigned long base_addr; /* aka Host Physical Address */ + void __iomem *base_addr; /* aka Host Physical Address */ const struct parisc_device *dev; /* device from PA bus walk */ struct pci_bus *hba_bus; /* primary PCI bus below HBA */ int hba_num; /* I/O port space access "key" */ @@ -57,6 +49,7 @@ struct pci_hba_data { struct resource lmmio_space; /* bus addresses < 4Gb */ struct resource elmmio_space; /* additional bus addresses < 4Gb */ struct resource gmmio_space; /* bus addresses > 4Gb */ + /* NOTE: Dino code assumes it can use *all* of the lmmio_space, * elmmio_space and gmmio_space as a contiguous array of * resources. This #define represents the array size */ @@ -65,6 +58,12 @@ struct pci_hba_data { unsigned long lmmio_space_offset; /* CPU view - PCI view */ void * iommu; /* IOMMU this device is under */ /* REVISIT - spinlock to protect resources? */ + + #define HBA_NAME_SIZE 16 + char io_name[HBA_NAME_SIZE]; + char lmmio_name[HBA_NAME_SIZE]; + char elmmio_name[HBA_NAME_SIZE]; + char gmmio_name[HBA_NAME_SIZE]; }; #define HBA_DATA(d) ((struct pci_hba_data *) (d)) @@ -82,12 +81,41 @@ struct pci_hba_data { #define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS) #define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1)) +#ifdef CONFIG_64BIT +#define PCI_F_EXTEND 0xffffffff00000000UL +#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a) + +/* We need to know if an address is LMMMIO or GMMIO. + * LMMIO requires mangling and GMMIO we must use as-is. + */ +static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a) +{ + return(((a) & PCI_F_EXTEND) == PCI_F_EXTEND); +} + /* ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. -** Note that we currently support only LMMIO. +** See pci.c for more conversions used by Generic PCI code. +** +** Platform characteristics/firmware guarantee that +** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO +** (2) PA_VIEW == IO_VIEW for GMMIO */ -#define PCI_BUS_ADDR(hba,a) ((a) - hba->lmmio_space_offset) -#define PCI_HOST_ADDR(hba,a) ((a) + hba->lmmio_space_offset) +#define PCI_BUS_ADDR(hba,a) (PCI_IS_LMMIO(hba,a) \ + ? ((a) - hba->lmmio_space_offset) /* mangle LMMIO */ \ + : (a)) /* GMMIO */ +#define PCI_HOST_ADDR(hba,a) (((a) & PCI_F_EXTEND) == 0 \ + ? (a) + hba->lmmio_space_offset \ + : (a)) + +#else /* !CONFIG_64BIT */ + +#define PCI_BUS_ADDR(hba,a) (a) +#define PCI_HOST_ADDR(hba,a) (a) +#define PCI_F_EXTEND 0UL +#define PCI_IS_LMMIO(hba,a) (1) /* 32-bit doesn't support GMMIO */ + +#endif /* !CONFIG_64BIT */ /* ** KLUGE: linux/pci.h include asm/pci.h BEFORE declaring struct pci_bus @@ -96,11 +124,28 @@ struct pci_hba_data { struct pci_bus; struct pci_dev; -/* The PCI address space does equal the physical memory - * address space. The networking and block device layers use +/* + * If the PCI device's view of memory is the same as the CPU's view of memory, + * PCI_DMA_BUS_IS_PHYS is true. The networking and block device layers use * this boolean for bounce buffer decisions. */ -#define PCI_DMA_BUS_IS_PHYS (1) +#ifdef CONFIG_PA20 +/* All PA-2.0 machines have an IOMMU. */ +#define PCI_DMA_BUS_IS_PHYS 0 +#define parisc_has_iommu() do { } while (0) +#else + +#if defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA) +extern int parisc_bus_is_phys; /* in arch/parisc/kernel/setup.c */ +#define PCI_DMA_BUS_IS_PHYS parisc_bus_is_phys +#define parisc_has_iommu() do { parisc_bus_is_phys = 0; } while (0) +#else +#define PCI_DMA_BUS_IS_PHYS 1 +#define parisc_has_iommu() do { } while (0) +#endif + +#endif /* !CONFIG_PA20 */ + /* ** Most PCI devices (eg Tulip, NCR720) also export the same registers @@ -158,9 +203,6 @@ struct pci_bios_ops { */ extern struct pci_port_ops *pci_port; extern struct pci_bios_ops *pci_bios; -extern int pci_post_reset_delay; /* delay after de-asserting #RESET */ -extern int pci_hba_count; -extern struct pci_hba_data *parisc_pci_hba[]; #ifdef CONFIG_PCI extern void pcibios_register_hba(struct pci_hba_data *); @@ -172,16 +214,27 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x) #endif /* -** used by drivers/pci/pci.c:pci_do_scan_bus() -** 0 == check if bridge is numbered before re-numbering. -** 1 == pci_do_scan_bus() should automatically number all PCI-PCI bridges. -** -** REVISIT: -** To date, only alpha sets this to one. We'll need to set this -** to zero for legacy platforms and one for PAT platforms. -*/ -#define pcibios_assign_all_busses() (pdc_type == PDC_TYPE_PAT) -#define pcibios_scan_all_fns(a, b) 0 + * pcibios_assign_all_busses() is used in drivers/pci/pci.c:pci_do_scan_bus() + * 0 == check if bridge is numbered before re-numbering. + * 1 == pci_do_scan_bus() should automatically number all PCI-PCI bridges. + * + * We *should* set this to zero for "legacy" platforms and one + * for PAT platforms. + * + * But legacy platforms also need to renumber the busses below a Host + * Bus controller. Adding a 4-port Tulip card on the first PCI root + * bus of a C200 resulted in the secondary bus being numbered as 1. + * The second PCI host bus controller's root bus had already been + * assigned bus number 1 by firmware and sysfs complained. + * + * Firmware isn't doing anything wrong here since each controller + * is its own PCI domain. It's simpler and easier for us to renumber + * the busses rather than treat each Dino as a separate PCI domain. + * Eventually, we may want to introduce PCI domains for Superdome or + * rp7420/8420 boxes and then revisit this issue. + */ +#define pcibios_assign_all_busses() (1) +#define pcibios_scan_all_fns(a, b) (0) #define PCIBIOS_MIN_IO 0x10 #define PCIBIOS_MIN_MEM 0x1000 /* NBPG - but pci/setup-res.c dies */ @@ -192,12 +245,53 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x) /* export the pci_ DMA API in terms of the dma_ one */ #include +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} +#endif + extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); +extern void +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region); + +static inline struct resource * +pcibios_select_root(struct pci_dev *pdev, struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; + + return root; +} + static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } +static inline void pcibios_penalize_isa_irq(int irq, int active) +{ + /* We don't need to penalize isa irq's */ +} + #endif /* __ASM_PARISC_PCI_H */