blob: 2e7519554b48d3eb8fe0e97a7df84d097030a57d [file] [log] [blame]
Martin Roth239b5df2022-07-26 22:18:26 -06001/* SPDX-License-Identifier: GPL-2.0-only */
2
Eric Biederman5899fd82003-04-24 06:25:08 +00003/*
Eric Biederman5899fd82003-04-24 06:25:08 +00004 * PCI defines and function prototypes
5 * Copyright 1994, Drew Eckhardt
6 * Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
7 *
8 * For more information, please consult the following manuals (look at
9 * http://www.pcisig.com/ for how to get them):
10 *
11 * PCI BIOS Specification
12 * PCI Local Bus Specification
13 * PCI to PCI Bridge Specification
14 * PCI System Design Guide
15 */
16
17#ifndef PCI_H
18#define PCI_H
19
Julius Wernercd49cce2019-03-05 16:53:33 -080020#if CONFIG(PCI)
Kyösti Mälkki318066f2014-02-12 14:18:50 +020021
Elyes Haouas35c3ae3b2022-10-27 12:25:12 +020022/* When <device/pci.h> is needed, it supposed to provide <device/pci_{def,type}.h> */
Eric Biederman5899fd82003-04-24 06:25:08 +000023#include <device/device.h>
Elyes Haouas35c3ae3b2022-10-27 12:25:12 +020024#include <device/pci_def.h> /* IWYU pragma: export */
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>
Elyes Haouas35c3ae3b2022-10-27 12:25:12 +020027#include <device/pci_type.h> /* IWYU pragma: export */
Elyes Haouas35c3ae3b2022-10-27 12:25:12 +020028#include <stddef.h>
29#include <stdint.h>
Kyösti Mälkkief844012013-06-25 23:17:43 +030030
Eric Biedermanb78c1972004-10-14 20:54:17 +000031/* Common pci operations without a standard interface */
32struct pci_operations {
Li-Ta Lo04930692004-11-25 17:37:19 +000033 /* set the Subsystem IDs for the PCI device */
Aaron Durbinc30d9132017-08-07 16:55:43 -060034 void (*set_subsystem)(struct device *dev, unsigned int vendor,
Lee Leahy0ca2a062017-03-06 18:01:04 -080035 unsigned int device);
Nico Huber968ef752021-03-07 01:39:18 +010036 void (*get_ltr_max_latencies)(u16 *max_snoop, u16 *max_nosnoop);
Eric Biedermanb78c1972004-10-14 20:54:17 +000037};
38
Eric Biederman5899fd82003-04-24 06:25:08 +000039struct pci_driver {
Uwe Hermann312673c2009-10-27 21:49:33 +000040 const struct device_operations *ops;
Eric Biederman5899fd82003-04-24 06:25:08 +000041 unsigned short vendor;
42 unsigned short device;
Vadim Bendebury8049fc92012-04-24 12:53:19 -070043 const unsigned short *devices;
Eric Biederman5899fd82003-04-24 06:25:08 +000044};
45
Patrick Rudolph4e2f95b2018-05-16 14:56:22 +020046struct msix_entry {
47 union {
48 struct {
49 u32 lower_addr;
50 u32 upper_addr;
51 };
52 struct {
53 u64 addr;
54 };
55 };
56 u32 data;
57 u32 vec_control;
58};
59
Kyösti Mälkki44da9e22019-09-27 15:02:32 +030060#if ENV_RAMSTAGE
Stefan Reinauer6a001132017-07-13 02:20:27 +020061#define __pci_driver __attribute__((used, __section__(".rodata.pci_driver")))
Kyösti Mälkki44da9e22019-09-27 15:02:32 +030062#else
63#define __pci_driver __attribute__((unused))
Aaron Durbinc30d9132017-08-07 16:55:43 -060064#endif
Kyösti Mälkki44da9e22019-09-27 15:02:32 +030065
Li-Ta Loe5266692004-03-23 21:28:05 +000066/** start of compile time generated pci driver array */
Aaron Durbin03758152015-09-03 17:23:08 -050067extern struct pci_driver _pci_drivers[];
Li-Ta Loe5266692004-03-23 21:28:05 +000068/** end of compile time generated pci driver array */
Aaron Durbin03758152015-09-03 17:23:08 -050069extern struct pci_driver _epci_drivers[];
Eric Biederman5899fd82003-04-24 06:25:08 +000070
Subrata Banikffc790b2017-12-11 10:29:49 +053071/* Set Subsystem ID operation for PCI devices */
72extern struct pci_operations pci_dev_ops_pci;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000073extern struct device_operations default_pci_ops_dev;
74extern struct device_operations default_pci_ops_bus;
Eric Biederman5899fd82003-04-24 06:25:08 +000075
Aaron Durbinc30d9132017-08-07 16:55:43 -060076void pci_dev_read_resources(struct device *dev);
77void pci_bus_read_resources(struct device *dev);
78void pci_dev_set_resources(struct device *dev);
79void pci_dev_enable_resources(struct device *dev);
80void pci_bus_enable_resources(struct device *dev);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000081void pci_bus_reset(struct bus *bus);
Aaron Durbinc30d9132017-08-07 16:55:43 -060082struct device *pci_probe_dev(struct device *dev, struct bus *bus,
83 unsigned int devfn);
Patrick Rudolphaa6971e2018-05-03 12:54:47 +020084void do_pci_scan_bridge(struct device *dev,
Kyösti Mälkkide271a82015-03-18 13:09:47 +020085 void (*do_scan_bus)(struct bus *bus,
Lee Leahy0ca2a062017-03-06 18:01:04 -080086 unsigned int min_devfn, unsigned int max_devfn));
Kyösti Mälkkide271a82015-03-18 13:09:47 +020087
Aaron Durbinc30d9132017-08-07 16:55:43 -060088void pci_scan_bridge(struct device *bus);
Lee Leahy0ca2a062017-03-06 18:01:04 -080089void pci_scan_bus(struct bus *bus, unsigned int min_devfn,
90 unsigned int max_devfn);
Kyösti Mälkkide271a82015-03-18 13:09:47 +020091
Lee Leahy0ca2a062017-03-06 18:01:04 -080092uint8_t pci_moving_config8(struct device *dev, unsigned int reg);
93uint16_t pci_moving_config16(struct device *dev, unsigned int reg);
94uint32_t pci_moving_config32(struct device *dev, unsigned int reg);
Eric Biedermanb78c1972004-10-14 20:54:17 +000095struct resource *pci_get_resource(struct device *dev, unsigned long index);
Aaron Durbinc30d9132017-08-07 16:55:43 -060096void pci_dev_set_subsystem(struct device *dev, unsigned int vendor,
Lee Leahy0ca2a062017-03-06 18:01:04 -080097 unsigned int device);
Myles Watson43bb9cd2008-12-18 18:24:11 +000098void pci_dev_init(struct device *dev);
Aaron Durbinc30d9132017-08-07 16:55:43 -060099unsigned int pci_match_simple_dev(struct device *dev, pci_devfn_t sdev);
Bill XIE513d3592022-08-02 22:55:51 +0800100uint16_t pci_find_cap_recursive(const struct device *dev, uint16_t cap);
Stefan Reinauer4d933dd2009-07-21 21:36:41 +0000101
Lee Leahy6d71a432017-03-07 15:24:16 -0800102const char *pin_to_str(int pin);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600103int get_pci_irq_pins(struct device *dev, struct device **parent_bdg);
Kyösti Mälkkic19d6a62019-07-04 21:39:28 +0300104void pci_assign_irqs(struct device *dev, const unsigned char pIntAtoD[4]);
Aaron Durbinc30d9132017-08-07 16:55:43 -0600105const char *get_pci_class_name(struct device *dev);
106const char *get_pci_subclass_name(struct device *dev);
Eric Biederman5899fd82003-04-24 06:25:08 +0000107
Patrick Rudolph4e2f95b2018-05-16 14:56:22 +0200108size_t pci_msix_table_size(struct device *dev);
109int pci_msix_table_bar(struct device *dev, u32 *offset, u8 *idx);
110struct msix_entry *pci_msix_get_table(struct device *dev);
111
Eric Biederman5899fd82003-04-24 06:25:08 +0000112#define PCI_IO_BRIDGE_ALIGN 4096
113#define PCI_MEM_BRIDGE_ALIGN (1024*1024)
114
Kyösti Mälkki8a41f4b2019-02-08 18:14:34 +0200115#define PCI_ID(VENDOR_ID, DEVICE_ID) \
116 ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
117
118pci_devfn_t pci_locate_device(unsigned int pci_id, pci_devfn_t dev);
119pci_devfn_t pci_locate_device_on_bus(unsigned int pci_id, unsigned int bus);
120
Kyösti Mälkkia0b366d2019-09-26 22:33:51 +0300121void pci_s_assert_secondary_reset(pci_devfn_t p2p_bridge);
122void pci_s_deassert_secondary_reset(pci_devfn_t p2p_bridge);
123void pci_s_bridge_set_secondary(pci_devfn_t p2p_bridge, u8 secondary);
124
Kyösti Mälkki4c686f22014-02-14 12:45:09 +0200125int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base);
Kyösti Mälkki2161c1d2014-02-11 19:56:57 +0200126
Alexandru Gagniuc420caaf2016-01-05 17:00:27 -0800127static inline int pci_base_address_is_memory_space(unsigned int attr)
128{
129 return (attr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY;
130}
Alexandru Gagniuc420caaf2016-01-05 17:00:27 -0800131
John Zhao95b4ece02020-05-04 15:58:48 -0700132void pci_dev_disable_bus_master(const struct device *dev);
Felix Singere4a7d9f2020-06-15 15:00:56 +0200133
134static __always_inline
135#if ENV_PCI_SIMPLE_DEVICE
136void pci_dev_request_bus_master(pci_devfn_t dev)
137#else
Subrata Banik86e53262020-09-05 14:03:31 +0530138void pci_dev_request_bus_master(struct device *dev)
Felix Singere4a7d9f2020-06-15 15:00:56 +0200139#endif /* ENV_PCI_SIMPLE_DEVICE */
140{
Felix Singer3d9fa082020-09-07 13:57:49 +0200141 if (CONFIG(PCI_ALLOW_BUS_MASTER_ANY_DEVICE))
Felix Singere4a7d9f2020-06-15 15:00:56 +0200142 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
143}
144
Kyösti Mälkki318066f2014-02-12 14:18:50 +0200145#endif /* CONFIG_PCI */
146
Kyösti Mälkki5b141162019-01-23 16:02:28 +0200147void pci_early_bridge_init(void);
148
Eric Biederman5899fd82003-04-24 06:25:08 +0000149#endif /* PCI_H */