* (C) Copyright 2002
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * aloong with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _PCI_H
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CLASS_CODE 0x0b /* Device class code */
+#define PCI_CLASS_CODE_TOO_OLD 0x00
+#define PCI_CLASS_CODE_STORAGE 0x01
+#define PCI_CLASS_CODE_NETWORK 0x02
+#define PCI_CLASS_CODE_DISPLAY 0x03
+#define PCI_CLASS_CODE_MULTIMEDIA 0x04
+#define PCI_CLASS_CODE_MEMORY 0x05
+#define PCI_CLASS_CODE_BRIDGE 0x06
+#define PCI_CLASS_CODE_COMM 0x07
+#define PCI_CLASS_CODE_PERIPHERAL 0x08
+#define PCI_CLASS_CODE_INPUT 0x09
+#define PCI_CLASS_CODE_DOCKING 0x0A
+#define PCI_CLASS_CODE_PROCESSOR 0x0B
+#define PCI_CLASS_CODE_SERIAL 0x0C
+#define PCI_CLASS_CODE_WIRELESS 0x0D
+#define PCI_CLASS_CODE_I2O 0x0E
+#define PCI_CLASS_CODE_SATELLITE 0x0F
+#define PCI_CLASS_CODE_CRYPTO 0x10
+#define PCI_CLASS_CODE_DATA 0x11
+/* Base Class 0x12 - 0xFE is reserved */
+#define PCI_CLASS_CODE_OTHER 0xFF
+
#define PCI_CLASS_SUB_CODE 0x0a /* Device sub-class code */
+#define PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA 0x00
+#define PCI_CLASS_SUB_CODE_TOO_OLD_VGA 0x01
+#define PCI_CLASS_SUB_CODE_STORAGE_SCSI 0x00
+#define PCI_CLASS_SUB_CODE_STORAGE_IDE 0x01
+#define PCI_CLASS_SUB_CODE_STORAGE_FLOPPY 0x02
+#define PCI_CLASS_SUB_CODE_STORAGE_IPIBUS 0x03
+#define PCI_CLASS_SUB_CODE_STORAGE_RAID 0x04
+#define PCI_CLASS_SUB_CODE_STORAGE_ATA 0x05
+#define PCI_CLASS_SUB_CODE_STORAGE_SATA 0x06
+#define PCI_CLASS_SUB_CODE_STORAGE_SAS 0x07
+#define PCI_CLASS_SUB_CODE_STORAGE_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_NETWORK_ETHERNET 0x00
+#define PCI_CLASS_SUB_CODE_NETWORK_TOKENRING 0x01
+#define PCI_CLASS_SUB_CODE_NETWORK_FDDI 0x02
+#define PCI_CLASS_SUB_CODE_NETWORK_ATM 0x03
+#define PCI_CLASS_SUB_CODE_NETWORK_ISDN 0x04
+#define PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP 0x05
+#define PCI_CLASS_SUB_CODE_NETWORK_PICMG 0x06
+#define PCI_CLASS_SUB_CODE_NETWORK_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_DISPLAY_VGA 0x00
+#define PCI_CLASS_SUB_CODE_DISPLAY_XGA 0x01
+#define PCI_CLASS_SUB_CODE_DISPLAY_3D 0x02
+#define PCI_CLASS_SUB_CODE_DISPLAY_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO 0x00
+#define PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO 0x01
+#define PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE 0x02
+#define PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_MEMORY_RAM 0x00
+#define PCI_CLASS_SUB_CODE_MEMORY_FLASH 0x01
+#define PCI_CLASS_SUB_CODE_MEMORY_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_BRIDGE_HOST 0x00
+#define PCI_CLASS_SUB_CODE_BRIDGE_ISA 0x01
+#define PCI_CLASS_SUB_CODE_BRIDGE_EISA 0x02
+#define PCI_CLASS_SUB_CODE_BRIDGE_MCA 0x03
+#define PCI_CLASS_SUB_CODE_BRIDGE_PCI 0x04
+#define PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA 0x05
+#define PCI_CLASS_SUB_CODE_BRIDGE_NUBUS 0x06
+#define PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS 0x07
+#define PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY 0x08
+#define PCI_CLASS_SUB_CODE_BRIDGE_SEMI_PCI 0x09
+#define PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND 0x0A
+#define PCI_CLASS_SUB_CODE_BRIDGE_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_COMM_SERIAL 0x00
+#define PCI_CLASS_SUB_CODE_COMM_PARALLEL 0x01
+#define PCI_CLASS_SUB_CODE_COMM_MULTIPORT 0x02
+#define PCI_CLASS_SUB_CODE_COMM_MODEM 0x03
+#define PCI_CLASS_SUB_CODE_COMM_GPIB 0x04
+#define PCI_CLASS_SUB_CODE_COMM_SMARTCARD 0x05
+#define PCI_CLASS_SUB_CODE_COMM_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_PIC 0x00
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_DMA 0x01
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER 0x02
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_RTC 0x03
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_SD 0x05
+#define PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_INPUT_KEYBOARD 0x00
+#define PCI_CLASS_SUB_CODE_INPUT_DIGITIZER 0x01
+#define PCI_CLASS_SUB_CODE_INPUT_MOUSE 0x02
+#define PCI_CLASS_SUB_CODE_INPUT_SCANNER 0x03
+#define PCI_CLASS_SUB_CODE_INPUT_GAMEPORT 0x04
+#define PCI_CLASS_SUB_CODE_INPUT_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_DOCKING_GENERIC 0x00
+#define PCI_CLASS_SUB_CODE_DOCKING_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_PROCESSOR_386 0x00
+#define PCI_CLASS_SUB_CODE_PROCESSOR_486 0x01
+#define PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM 0x02
+#define PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA 0x10
+#define PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC 0x20
+#define PCI_CLASS_SUB_CODE_PROCESSOR_MIPS 0x30
+#define PCI_CLASS_SUB_CODE_PROCESSOR_COPROC 0x40
+#define PCI_CLASS_SUB_CODE_SERIAL_1394 0x00
+#define PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS 0x01
+#define PCI_CLASS_SUB_CODE_SERIAL_SSA 0x02
+#define PCI_CLASS_SUB_CODE_SERIAL_USB 0x03
+#define PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN 0x04
+#define PCI_CLASS_SUB_CODE_SERIAL_SMBUS 0x05
+#define PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND 0x06
+#define PCI_CLASS_SUB_CODE_SERIAL_IPMI 0x07
+#define PCI_CLASS_SUB_CODE_SERIAL_SERCOS 0x08
+#define PCI_CLASS_SUB_CODE_SERIAL_CANBUS 0x09
+#define PCI_CLASS_SUB_CODE_WIRELESS_IRDA 0x00
+#define PCI_CLASS_SUB_CODE_WIRELESS_IR 0x01
+#define PCI_CLASS_SUB_CODE_WIRELESS_RF 0x10
+#define PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11
+#define PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12
+#define PCI_CLASS_SUB_CODE_WIRELESS_80211A 0x20
+#define PCI_CLASS_SUB_CODE_WIRELESS_80211B 0x21
+#define PCI_CLASS_SUB_CODE_WIRELESS_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_I2O_V1_0 0x00
+#define PCI_CLASS_SUB_CODE_SATELLITE_TV 0x01
+#define PCI_CLASS_SUB_CODE_SATELLITE_AUDIO 0x02
+#define PCI_CLASS_SUB_CODE_SATELLITE_VOICE 0x03
+#define PCI_CLASS_SUB_CODE_SATELLITE_DATA 0x04
+#define PCI_CLASS_SUB_CODE_CRYPTO_NETWORK 0x00
+#define PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10
+#define PCI_CLASS_SUB_CODE_CRYPTO_OTHER 0x80
+#define PCI_CLASS_SUB_CODE_DATA_DPIO 0x00
+#define PCI_CLASS_SUB_CODE_DATA_PERFCNTR 0x01
+#define PCI_CLASS_SUB_CODE_DATA_COMMSYNC 0x10
+#define PCI_CLASS_SUB_CODE_DATA_MGMT 0x20
+#define PCI_CLASS_SUB_CODE_DATA_OTHER 0x80
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
-#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
-#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fULL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03ULL)
/* bit 1 is reserved if address_space = 1 */
/* Header type 0 (normal devices) */
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
#define PCI_ROM_ADDRESS_ENABLE 0x01
-#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+#define PCI_ROM_ADDRESS_MASK (~0x7ffULL)
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
+#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
#define PCI_CAP_SIZEOF 4
#define PCI_MAX_PCI_DEVICES 32
#define PCI_MAX_PCI_FUNCTIONS 8
-#define PCI_DCR 0x54 /* PCIe Device Control Register */
-#define PCI_DSR 0x56 /* PCIe Device Status Register */
-#define PCI_LSR 0x5e /* PCIe Link Status Register */
-#define PCI_LTSSM 0x404 /* PCIe Link Training, Status State Machine */
-#define PCI_LTSSM_L0 0x16 /* L0 state */
+#define PCI_FIND_CAP_TTL 0x48
+#define CAP_START_POS 0x40
/* Include the ID list */
#include <pci_ids.h>
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_SYS_PCI_64BIT
+typedef u64 pci_addr_t;
+typedef u64 pci_size_t;
+#else
+typedef u32 pci_addr_t;
+typedef u32 pci_size_t;
+#endif
+
struct pci_region {
- unsigned long bus_start; /* Start on the bus */
- unsigned long phys_start; /* Start in physical address space */
- unsigned long size; /* Size */
- unsigned long flags; /* Resource flags */
+ pci_addr_t bus_start; /* Start on the bus */
+ phys_addr_t phys_start; /* Start in physical address space */
+ pci_size_t size; /* Size */
+ unsigned long flags; /* Resource flags */
- unsigned long bus_lower;
+ pci_addr_t bus_lower;
};
#define PCI_REGION_MEM 0x00000000 /* PCI memory space */
#define PCI_REGION_TYPE 0x00000001
#define PCI_REGION_PREFETCH 0x00000008 /* prefetchable PCI memory */
-#define PCI_REGION_MEMORY 0x00000100 /* System memory */
+#define PCI_REGION_SYS_MEMORY 0x00000100 /* System memory */
#define PCI_REGION_RO 0x00000200 /* Read-only memory */
-extern __inline__ void pci_set_region(struct pci_region *reg,
- unsigned long bus_start,
- unsigned long phys_start,
- unsigned long size,
+static inline void pci_set_region(struct pci_region *reg,
+ pci_addr_t bus_start,
+ phys_addr_t phys_start,
+ pci_size_t size,
unsigned long flags) {
reg->bus_start = bus_start;
reg->phys_start = phys_start;
#define MAX_PCI_REGIONS 7
+#define INDIRECT_TYPE_NO_PCIE_LINK 1
+
/*
* Structure of a PCI controller (host bridge)
*/
volatile unsigned int *cfg_addr;
volatile unsigned char *cfg_data;
+ int indirect_type;
+
struct pci_region regions[MAX_PCI_REGIONS];
int region_count;
/* Used by ppc405 autoconfig*/
struct pci_region *pci_fb;
int current_busno;
+
+ void *priv_data;
};
-extern __inline__ void pci_set_ops(struct pci_controller *hose,
+static inline void pci_set_ops(struct pci_controller *hose,
int (*read_byte)(struct pci_controller*,
pci_dev_t, int where, u8 *),
int (*read_word)(struct pci_controller*,
hose->write_dword = write_dword;
}
+#ifdef CONFIG_PCI_INDIRECT_BRIDGE
extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
+#endif
-extern unsigned long pci_hose_bus_to_phys(struct pci_controller* hose,
- unsigned long addr, unsigned long flags);
-extern unsigned long pci_hose_phys_to_bus(struct pci_controller* hose,
- unsigned long addr, unsigned long flags);
+extern phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
+ pci_addr_t addr, unsigned long flags);
+extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
+ phys_addr_t addr, unsigned long flags);
#define pci_phys_to_bus(dev, addr, flags) \
pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
#define pci_bus_to_phys(dev, addr, flags) \
pci_hose_bus_to_phys(pci_bus_to_hose(PCI_BUS(dev)), (addr), (flags))
-#define pci_phys_to_mem(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
-#define pci_mem_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
-#define pci_phys_to_io(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
-#define pci_io_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+#define pci_virt_to_bus(dev, addr, flags) \
+ pci_hose_phys_to_bus(pci_bus_to_hose(PCI_BUS(dev)), \
+ (virt_to_phys(addr)), (flags))
+#define pci_bus_to_virt(dev, addr, flags, len, map_flags) \
+ map_physmem(pci_hose_bus_to_phys(pci_bus_to_hose(PCI_BUS(dev)), \
+ (addr), (flags)), \
+ (len), (map_flags))
+
+#define pci_phys_to_mem(dev, addr) \
+ pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+#define pci_mem_to_phys(dev, addr) \
+ pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+#define pci_phys_to_io(dev, addr) pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+#define pci_io_to_phys(dev, addr) pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+
+#define pci_virt_to_mem(dev, addr) \
+ pci_virt_to_bus((dev), (addr), PCI_REGION_MEM)
+#define pci_mem_to_virt(dev, addr, len, map_flags) \
+ pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags))
+#define pci_virt_to_io(dev, addr) \
+ pci_virt_to_bus((dev), (addr), PCI_REGION_IO)
+#define pci_io_to_virt(dev, addr, len, map_flags) \
+ pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
extern int pci_hose_read_config_byte(struct pci_controller *hose,
pci_dev_t dev, int where, u8 *val);
extern int pci_hose_write_config_word_via_dword(struct pci_controller *hose,
pci_dev_t dev, int where, u16 val);
+extern void *pci_map_bar(pci_dev_t pdev, int bar, int flags);
extern void pci_register_hose(struct pci_controller* hose);
extern struct pci_controller* pci_bus_to_hose(int bus);
+extern struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr);
extern int pci_hose_scan(struct pci_controller *hose);
extern int pci_hose_scan_bus(struct pci_controller *hose, int bus);
extern void pciauto_region_init(struct pci_region* res);
-extern void pciauto_region_align(struct pci_region *res, unsigned long size);
-extern int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
+extern void pciauto_region_align(struct pci_region *res, pci_size_t size);
+extern int pciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar);
extern void pciauto_setup_device(struct pci_controller *hose,
pci_dev_t dev, int bars_num,
struct pci_region *mem,
struct pci_region *prefetch,
struct pci_region *io);
-int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+extern void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+ pci_dev_t dev, int sub_bus);
+extern void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+ pci_dev_t dev, int sub_bus);
+extern void pciauto_config_init(struct pci_controller *hose);
+extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
extern int pci_hose_config_device(struct pci_controller *hose,
pci_dev_t dev,
unsigned long io,
- unsigned long mem,
+ pci_addr_t mem,
unsigned long command);
+extern int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev,
+ int cap);
+extern int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
+ u8 hdr_type);
+extern int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos,
+ int cap);
+
+const char * pci_class_str(u8 class);
+int pci_last_busno(void);
+
#ifdef CONFIG_MPC824X
extern void pci_mpc824x_init (struct pci_controller *hose);
#endif
#ifdef CONFIG_MPC85xx
extern void pci_mpc85xx_init (struct pci_controller *hose);
#endif
-#endif /* _PCI_H */
+
+#endif /* __ASSEMBLY__ */
+#endif /* _PCI_H */