blob: db7cc69c8d0c196c0111064305654dc352243327 [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
Julius Wernercd49cce2019-03-05 16:53:33 -080018#if 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>
Eric Biederman52685572003-05-19 19:16:21 +000022#include <device/pci_def.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000023#include <device/resource.h>
24#include <device/device.h>
Kyösti Mälkki4663f452019-03-07 14:18:28 +020025#include <device/pci_ops.h>
Li-Ta Lo883b8792005-01-10 23:16:22 +000026#include <device/pci_rom.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020027#include <device/pci_type.h>
Kyösti Mälkkief844012013-06-25 23:17:43 +030028
Eric Biedermanb78c1972004-10-14 20:54:17 +000029/* Common pci operations without a standard interface */
30struct pci_operations {
Li-Ta Lo04930692004-11-25 17:37:19 +000031 /* set the Subsystem IDs for the PCI device */
Aaron Durbinc30d9132017-08-07 16:55:43 -060032 void (*set_subsystem)(struct device *dev, unsigned int vendor,
Lee Leahy0ca2a062017-03-06 18:01:04 -080033 unsigned int device);
Nico Huber968ef752021-03-07 01:39:18 +010034 void (*get_ltr_max_latencies)(u16 *max_snoop, u16 *max_nosnoop);
Eric Biedermanb78c1972004-10-14 20:54:17 +000035};
36
Eric Biederman5899fd82003-04-24 06:25:08 +000037struct pci_driver {
Uwe Hermann312673c2009-10-27 21:49:33 +000038 const struct device_operations *ops;
Eric Biederman5899fd82003-04-24 06:25:08 +000039 unsigned short vendor;
40 unsigned short device;
Vadim Bendebury8049fc92012-04-24 12:53:19 -070041 const unsigned short *devices;
Eric Biederman5899fd82003-04-24 06:25:08 +000042};
43
Patrick Rudolph4e2f95b2018-05-16 14:56:22 +020044struct msix_entry {
45 union {
46 struct {
47 u32 lower_addr;
48 u32 upper_addr;
49 };
50 struct {
51 u64 addr;
52 };
53 };
54 u32 data;
55 u32 vec_control;
56};
57
Kyösti Mälkki44da9e22019-09-27 15:02:32 +030058#if ENV_RAMSTAGE
Stefan Reinauer6a001132017-07-13 02:20:27 +020059#define __pci_driver __attribute__((used, __section__(".rodata.pci_driver")))
Kyösti Mälkki44da9e22019-09-27 15:02:32 +030060#else
61#define __pci_driver __attribute__((unused))
Aaron Durbinc30d9132017-08-07 16:55:43 -060062#endif
Kyösti Mälkki44da9e22019-09-27 15:02:32 +030063
Li-Ta Loe5266692004-03-23 21:28:05 +000064/** start of compile time generated pci driver array */
Aaron Durbin03758152015-09-03 17:23:08 -050065extern struct pci_driver _pci_drivers[];
Li-Ta Loe5266692004-03-23 21:28:05 +000066/** end of compile time generated pci driver array */
Aaron Durbin03758152015-09-03 17:23:08 -050067extern struct pci_driver _epci_drivers[];
Eric Biederman5899fd82003-04-24 06:25:08 +000068
Subrata Banikffc790b2017-12-11 10:29:49 +053069/* Set Subsystem ID operation for PCI devices */
70extern struct pci_operations pci_dev_ops_pci;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000071extern struct device_operations default_pci_ops_dev;
72extern struct device_operations default_pci_ops_bus;
Eric Biederman5899fd82003-04-24 06:25:08 +000073
Aaron Durbinc30d9132017-08-07 16:55:43 -060074void pci_dev_read_resources(struct device *dev);
75void pci_bus_read_resources(struct device *dev);
76void pci_dev_set_resources(struct device *dev);
77void pci_dev_enable_resources(struct device *dev);
78void pci_bus_enable_resources(struct device *dev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000079void pci_bus_reset(struct bus *bus);
Aaron Durbinc30d9132017-08-07 16:55:43 -060080struct device *pci_probe_dev(struct device *dev, struct bus *bus,
81 unsigned int devfn);
Patrick Rudolphaa6971e2018-05-03 12:54:47 +020082void do_pci_scan_bridge(struct device *dev,
Kyösti Mälkkide271a82015-03-18 13:09:47 +020083 void (*do_scan_bus)(struct bus *bus,
Lee Leahy0ca2a062017-03-06 18:01:04 -080084 unsigned int min_devfn, unsigned int max_devfn));
Kyösti Mälkkide271a82015-03-18 13:09:47 +020085
Aaron Durbinc30d9132017-08-07 16:55:43 -060086void pci_scan_bridge(struct device *bus);
Lee Leahy0ca2a062017-03-06 18:01:04 -080087void pci_scan_bus(struct bus *bus, unsigned int min_devfn,
88 unsigned int max_devfn);
Kyösti Mälkkide271a82015-03-18 13:09:47 +020089
Lee Leahy0ca2a062017-03-06 18:01:04 -080090uint8_t pci_moving_config8(struct device *dev, unsigned int reg);
91uint16_t pci_moving_config16(struct device *dev, unsigned int reg);
92uint32_t pci_moving_config32(struct device *dev, unsigned int reg);
Eric Biedermanb78c1972004-10-14 20:54:17 +000093struct resource *pci_get_resource(struct device *dev, unsigned long index);
Aaron Durbinc30d9132017-08-07 16:55:43 -060094void pci_dev_set_subsystem(struct device *dev, unsigned int vendor,
Lee Leahy0ca2a062017-03-06 18:01:04 -080095 unsigned int device);
Myles Watson43bb9cd2008-12-18 18:24:11 +000096void pci_dev_init(struct device *dev);
Aaron Durbinc30d9132017-08-07 16:55:43 -060097unsigned int pci_match_simple_dev(struct device *dev, pci_devfn_t sdev);
Stefan Reinauer4d933dd2009-07-21 21:36:41 +000098
Lee Leahy6d71a432017-03-07 15:24:16 -080099const char *pin_to_str(int pin);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600100int get_pci_irq_pins(struct device *dev, struct device **parent_bdg);
Kyösti Mälkkic19d6a62019-07-04 21:39:28 +0300101void pci_assign_irqs(struct device *dev, const unsigned char pIntAtoD[4]);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600102const char *get_pci_class_name(struct device *dev);
103const char *get_pci_subclass_name(struct device *dev);
Eric Biederman5899fd82003-04-24 06:25:08 +0000104
Patrick Rudolph4e2f95b2018-05-16 14:56:22 +0200105size_t pci_msix_table_size(struct device *dev);
106int pci_msix_table_bar(struct device *dev, u32 *offset, u8 *idx);
107struct msix_entry *pci_msix_get_table(struct device *dev);
108
Eric Biederman5899fd82003-04-24 06:25:08 +0000109#define PCI_IO_BRIDGE_ALIGN 4096
110#define PCI_MEM_BRIDGE_ALIGN (1024*1024)
111
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200112#define PCI_ID(VENDOR_ID, DEVICE_ID) \
113 ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
114
115pci_devfn_t pci_locate_device(unsigned int pci_id, pci_devfn_t dev);
116pci_devfn_t pci_locate_device_on_bus(unsigned int pci_id, unsigned int bus);
117
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300118void pci_s_assert_secondary_reset(pci_devfn_t p2p_bridge);
119void pci_s_deassert_secondary_reset(pci_devfn_t p2p_bridge);
120void pci_s_bridge_set_secondary(pci_devfn_t p2p_bridge, u8 secondary);
121
Kyösti Mälkki4c686f22014-02-14 12:45:09 +0200122int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base);
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +0200123
Alexandru Gagniuc420caaf2016-01-05 17:00:27 -0800124static inline int pci_base_address_is_memory_space(unsigned int attr)
125{
126 return (attr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY;
127}
Alexandru Gagniuc420caaf2016-01-05 17:00:27 -0800128
John Zhao95b4ece02020-05-04 15:58:48 -0700129void pci_dev_disable_bus_master(const struct device *dev);
Felix Singere4a7d9f2020-06-15 15:00:56 +0200130
131static __always_inline
132#if ENV_PCI_SIMPLE_DEVICE
133void pci_dev_request_bus_master(pci_devfn_t dev)
134#else
Subrata Banik86e53262020-09-05 14:03:31 +0530135void pci_dev_request_bus_master(struct device *dev)
Felix Singere4a7d9f2020-06-15 15:00:56 +0200136#endif /* ENV_PCI_SIMPLE_DEVICE */
137{
Felix Singer3d9fa082020-09-07 13:57:49 +0200138 if (CONFIG(PCI_ALLOW_BUS_MASTER_ANY_DEVICE))
Felix Singere4a7d9f2020-06-15 15:00:56 +0200139 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
140}
141
Kyösti Mälkki318066f2014-02-12 14:18:50 +0200142#endif /* CONFIG_PCI */
143
Kyösti Mälkki5b141162019-01-23 16:02:28 +0200144void pci_early_bridge_init(void);
145
Eric Biederman5899fd82003-04-24 06:25:08 +0000146#endif /* PCI_H */