blob: f0724e0f99abd7a1ff8bbc71ec62c584f4b99ffc [file] [log] [blame]
Eric Biederman5899fd82003-04-24 06:25:08 +00001/*
Eric Biederman5899fd82003-04-24 06:25:08 +00002 * PCI defines and function prototypes
3 * Copyright 1994, Drew Eckhardt
4 * Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
5 *
6 * For more information, please consult the following manuals (look at
7 * http://www.pcisig.com/ for how to get them):
8 *
9 * PCI BIOS Specification
10 * PCI Local Bus Specification
11 * PCI to PCI Bridge Specification
12 * PCI System Design Guide
13 */
14
15#ifndef PCI_H
16#define PCI_H
17
Martin Roth96345472017-06-24 14:13:53 -060018#if IS_ENABLED(CONFIG_PCI)
Kyösti Mälkki318066f2014-02-12 14:18:50 +020019
Uwe Hermanne4870472010-11-04 23:23:47 +000020#include <stdint.h>
Stefan Reinauer57879c92012-07-31 16:47:25 -070021#include <stddef.h>
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +020022#include <arch/io.h>
Eric Biederman52685572003-05-19 19:16:21 +000023#include <device/pci_def.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000024#include <device/resource.h>
25#include <device/device.h>
26#include <device/pci_ops.h>
Li-Ta Lo883b8792005-01-10 23:16:22 +000027#include <device/pci_rom.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000028
Kyösti Mälkkief844012013-06-25 23:17:43 +030029
Eric Biedermanb78c1972004-10-14 20:54:17 +000030/* Common pci operations without a standard interface */
31struct pci_operations {
Li-Ta Lo04930692004-11-25 17:37:19 +000032 /* set the Subsystem IDs for the PCI device */
Aaron Durbinc30d9132017-08-07 16:55:43 -060033 void (*set_subsystem)(struct device *dev, unsigned int vendor,
Lee Leahy0ca2a062017-03-06 18:01:04 -080034 unsigned int device);
Aaron Durbinc30d9132017-08-07 16:55:43 -060035 void (*set_L1_ss_latency)(struct device *dev, unsigned int off);
Eric Biedermanb78c1972004-10-14 20:54:17 +000036};
37
Eric Biedermana9e632c2004-11-18 22:38:08 +000038/* Common pci bus operations */
39struct pci_bus_operations {
Lee Leahybab6bc42017-03-07 16:10:21 -080040 uint8_t (*read8)(struct bus *pbus, int bus, int devfn, int where);
41 uint16_t (*read16)(struct bus *pbus, int bus, int devfn, int where);
42 uint32_t (*read32)(struct bus *pbus, int bus, int devfn, int where);
Lee Leahy6a566d72017-03-07 17:45:12 -080043 void (*write8)(struct bus *pbus, int bus, int devfn, int where,
44 uint8_t val);
45 void (*write16)(struct bus *pbus, int bus, int devfn, int where,
46 uint16_t val);
47 void (*write32)(struct bus *pbus, int bus, int devfn, int where,
48 uint32_t val);
Eric Biedermana9e632c2004-11-18 22:38:08 +000049};
50
Eric Biederman5899fd82003-04-24 06:25:08 +000051struct pci_driver {
Uwe Hermann312673c2009-10-27 21:49:33 +000052 const struct device_operations *ops;
Eric Biederman5899fd82003-04-24 06:25:08 +000053 unsigned short vendor;
54 unsigned short device;
Vadim Bendebury8049fc92012-04-24 12:53:19 -070055 const unsigned short *devices;
Eric Biederman5899fd82003-04-24 06:25:08 +000056};
57
Patrick Rudolph4e2f95b2018-05-16 14:56:22 +020058struct msix_entry {
59 union {
60 struct {
61 u32 lower_addr;
62 u32 upper_addr;
63 };
64 struct {
65 u64 addr;
66 };
67 };
68 u32 data;
69 u32 vec_control;
70};
71
Aaron Durbinc30d9132017-08-07 16:55:43 -060072#ifdef __SIMPLE_DEVICE__
73#define __pci_driver __attribute__((unused))
74#else
Stefan Reinauer6a001132017-07-13 02:20:27 +020075#define __pci_driver __attribute__((used, __section__(".rodata.pci_driver")))
Aaron Durbinc30d9132017-08-07 16:55:43 -060076#endif
Li-Ta Loe5266692004-03-23 21:28:05 +000077/** start of compile time generated pci driver array */
Aaron Durbin03758152015-09-03 17:23:08 -050078extern struct pci_driver _pci_drivers[];
Li-Ta Loe5266692004-03-23 21:28:05 +000079/** end of compile time generated pci driver array */
Aaron Durbin03758152015-09-03 17:23:08 -050080extern struct pci_driver _epci_drivers[];
Eric Biederman5899fd82003-04-24 06:25:08 +000081
Subrata Banikffc790b2017-12-11 10:29:49 +053082/* Set Subsystem ID operation for PCI devices */
83extern struct pci_operations pci_dev_ops_pci;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000084extern struct device_operations default_pci_ops_dev;
85extern struct device_operations default_pci_ops_bus;
Eric Biederman5899fd82003-04-24 06:25:08 +000086
Aaron Durbinc30d9132017-08-07 16:55:43 -060087void pci_dev_read_resources(struct device *dev);
88void pci_bus_read_resources(struct device *dev);
89void pci_dev_set_resources(struct device *dev);
90void pci_dev_enable_resources(struct device *dev);
91void pci_bus_enable_resources(struct device *dev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000092void pci_bus_reset(struct bus *bus);
Aaron Durbinc30d9132017-08-07 16:55:43 -060093struct device *pci_probe_dev(struct device *dev, struct bus *bus,
94 unsigned int devfn);
Kyösti Mälkkide271a82015-03-18 13:09:47 +020095
Patrick Rudolphaa6971e2018-05-03 12:54:47 +020096void do_pci_scan_bridge(struct device *dev,
Kyösti Mälkkide271a82015-03-18 13:09:47 +020097 void (*do_scan_bus)(struct bus *bus,
Lee Leahy0ca2a062017-03-06 18:01:04 -080098 unsigned int min_devfn, unsigned int max_devfn));
Kyösti Mälkkide271a82015-03-18 13:09:47 +020099
Aaron Durbinc30d9132017-08-07 16:55:43 -0600100void pci_scan_bridge(struct device *bus);
Lee Leahy0ca2a062017-03-06 18:01:04 -0800101void pci_scan_bus(struct bus *bus, unsigned int min_devfn,
102 unsigned int max_devfn);
Kyösti Mälkkide271a82015-03-18 13:09:47 +0200103
Lee Leahy0ca2a062017-03-06 18:01:04 -0800104uint8_t pci_moving_config8(struct device *dev, unsigned int reg);
105uint16_t pci_moving_config16(struct device *dev, unsigned int reg);
106uint32_t pci_moving_config32(struct device *dev, unsigned int reg);
Eric Biedermanb78c1972004-10-14 20:54:17 +0000107struct resource *pci_get_resource(struct device *dev, unsigned long index);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600108void pci_dev_set_subsystem(struct device *dev, unsigned int vendor,
Lee Leahy0ca2a062017-03-06 18:01:04 -0800109 unsigned int device);
Myles Watson43bb9cd2008-12-18 18:24:11 +0000110void pci_dev_init(struct device *dev);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600111unsigned int pci_match_simple_dev(struct device *dev, pci_devfn_t sdev);
Stefan Reinauer4d933dd2009-07-21 21:36:41 +0000112
Lee Leahy6d71a432017-03-07 15:24:16 -0800113const char *pin_to_str(int pin);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600114int get_pci_irq_pins(struct device *dev, struct device **parent_bdg);
Lee Leahy0ca2a062017-03-06 18:01:04 -0800115void pci_assign_irqs(unsigned int bus, unsigned int slot,
Myles Watson43bb9cd2008-12-18 18:24:11 +0000116 const unsigned char pIntAtoD[4]);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600117const char *get_pci_class_name(struct device *dev);
118const char *get_pci_subclass_name(struct device *dev);
Eric Biederman5899fd82003-04-24 06:25:08 +0000119
Patrick Rudolph4e2f95b2018-05-16 14:56:22 +0200120size_t pci_msix_table_size(struct device *dev);
121int pci_msix_table_bar(struct device *dev, u32 *offset, u8 *idx);
122struct msix_entry *pci_msix_get_table(struct device *dev);
123
Eric Biederman5899fd82003-04-24 06:25:08 +0000124#define PCI_IO_BRIDGE_ALIGN 4096
125#define PCI_MEM_BRIDGE_ALIGN (1024*1024)
126
Aaron Durbinc30d9132017-08-07 16:55:43 -0600127static inline const struct pci_operations *ops_pci(struct device *dev)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000128{
Eric Biedermana9e632c2004-11-18 22:38:08 +0000129 const struct pci_operations *pops;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000130 pops = 0;
Lee Leahybfdb8932017-03-07 15:17:04 -0800131 if (dev && dev->ops)
Eric Biedermanb78c1972004-10-14 20:54:17 +0000132 pops = dev->ops->ops_pci;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000133 return pops;
134}
135
Antonello Dettori45b3b822016-08-30 22:18:06 +0200136#ifdef __SIMPLE_DEVICE__
Lee Leahy0ca2a062017-03-06 18:01:04 -0800137unsigned int pci_find_next_capability(pci_devfn_t dev, unsigned int cap,
138 unsigned int last);
139unsigned int pci_find_capability(pci_devfn_t dev, unsigned int cap);
Antonello Dettori45b3b822016-08-30 22:18:06 +0200140#else /* !__SIMPLE_DEVICE__ */
Aaron Durbinc30d9132017-08-07 16:55:43 -0600141unsigned int pci_find_next_capability(struct device *dev, unsigned int cap,
Lee Leahy0ca2a062017-03-06 18:01:04 -0800142 unsigned int last);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600143unsigned int pci_find_capability(struct device *dev, unsigned int cap);
Antonello Dettori45b3b822016-08-30 22:18:06 +0200144#endif /* __SIMPLE_DEVICE__ */
Edward O'Callaghanc2956e72014-07-09 04:55:16 +1000145
Kyösti Mälkki3521e262018-12-26 19:33:28 +0200146void pci_early_mmio_window(pci_devfn_t p2p_bridge, u32 mmio_base,
147 u32 mmio_size);
Kyösti Mälkki4c686f22014-02-14 12:45:09 +0200148int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base);
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +0200149
Alexandru Gagniuc420caaf2016-01-05 17:00:27 -0800150#ifndef __ROMCC__
151static inline int pci_base_address_is_memory_space(unsigned int attr)
152{
153 return (attr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY;
154}
155#endif
156
Kyösti Mälkki318066f2014-02-12 14:18:50 +0200157#endif /* CONFIG_PCI */
158
Kyösti Mälkki5b141162019-01-23 16:02:28 +0200159void pci_early_bridge_init(void);
160
Eric Biederman5899fd82003-04-24 06:25:08 +0000161#endif /* PCI_H */