xref: /openbmc/linux/drivers/pci/pci-bridge-emul.h (revision 658aea35)
123a5fba4SThomas Petazzoni /* SPDX-License-Identifier: GPL-2.0 */
223a5fba4SThomas Petazzoni #ifndef __PCI_BRIDGE_EMUL_H__
323a5fba4SThomas Petazzoni #define __PCI_BRIDGE_EMUL_H__
423a5fba4SThomas Petazzoni 
523a5fba4SThomas Petazzoni #include <linux/kernel.h>
623a5fba4SThomas Petazzoni 
723a5fba4SThomas Petazzoni /* PCI configuration space of a PCI-to-PCI bridge. */
823a5fba4SThomas Petazzoni struct pci_bridge_emul_conf {
9e0d9d30bSGrzegorz Jaszczyk 	__le16 vendor;
10e0d9d30bSGrzegorz Jaszczyk 	__le16 device;
11e0d9d30bSGrzegorz Jaszczyk 	__le16 command;
12e0d9d30bSGrzegorz Jaszczyk 	__le16 status;
13e0d9d30bSGrzegorz Jaszczyk 	__le32 class_revision;
1423a5fba4SThomas Petazzoni 	u8 cache_line_size;
1523a5fba4SThomas Petazzoni 	u8 latency_timer;
1623a5fba4SThomas Petazzoni 	u8 header_type;
1723a5fba4SThomas Petazzoni 	u8 bist;
18e0d9d30bSGrzegorz Jaszczyk 	__le32 bar[2];
1923a5fba4SThomas Petazzoni 	u8 primary_bus;
2023a5fba4SThomas Petazzoni 	u8 secondary_bus;
2123a5fba4SThomas Petazzoni 	u8 subordinate_bus;
2223a5fba4SThomas Petazzoni 	u8 secondary_latency_timer;
2323a5fba4SThomas Petazzoni 	u8 iobase;
2423a5fba4SThomas Petazzoni 	u8 iolimit;
25e0d9d30bSGrzegorz Jaszczyk 	__le16 secondary_status;
26e0d9d30bSGrzegorz Jaszczyk 	__le16 membase;
27e0d9d30bSGrzegorz Jaszczyk 	__le16 memlimit;
28e0d9d30bSGrzegorz Jaszczyk 	__le16 pref_mem_base;
29e0d9d30bSGrzegorz Jaszczyk 	__le16 pref_mem_limit;
30e0d9d30bSGrzegorz Jaszczyk 	__le32 prefbaseupper;
31e0d9d30bSGrzegorz Jaszczyk 	__le32 preflimitupper;
32e0d9d30bSGrzegorz Jaszczyk 	__le16 iobaseupper;
33e0d9d30bSGrzegorz Jaszczyk 	__le16 iolimitupper;
3423a5fba4SThomas Petazzoni 	u8 capabilities_pointer;
3523a5fba4SThomas Petazzoni 	u8 reserve[3];
36e0d9d30bSGrzegorz Jaszczyk 	__le32 romaddr;
3723a5fba4SThomas Petazzoni 	u8 intline;
3823a5fba4SThomas Petazzoni 	u8 intpin;
39e0d9d30bSGrzegorz Jaszczyk 	__le16 bridgectrl;
4023a5fba4SThomas Petazzoni };
4123a5fba4SThomas Petazzoni 
4223a5fba4SThomas Petazzoni /* PCI configuration space of the PCIe capabilities */
4323a5fba4SThomas Petazzoni struct pci_bridge_emul_pcie_conf {
4423a5fba4SThomas Petazzoni 	u8 cap_id;
4523a5fba4SThomas Petazzoni 	u8 next;
46e0d9d30bSGrzegorz Jaszczyk 	__le16 cap;
47e0d9d30bSGrzegorz Jaszczyk 	__le32 devcap;
48e0d9d30bSGrzegorz Jaszczyk 	__le16 devctl;
49e0d9d30bSGrzegorz Jaszczyk 	__le16 devsta;
50e0d9d30bSGrzegorz Jaszczyk 	__le32 lnkcap;
51e0d9d30bSGrzegorz Jaszczyk 	__le16 lnkctl;
52e0d9d30bSGrzegorz Jaszczyk 	__le16 lnksta;
53e0d9d30bSGrzegorz Jaszczyk 	__le32 slotcap;
54e0d9d30bSGrzegorz Jaszczyk 	__le16 slotctl;
55e0d9d30bSGrzegorz Jaszczyk 	__le16 slotsta;
56e0d9d30bSGrzegorz Jaszczyk 	__le16 rootctl;
57e902bb7cSPali Rohár 	__le16 rootcap;
58e0d9d30bSGrzegorz Jaszczyk 	__le32 rootsta;
59e0d9d30bSGrzegorz Jaszczyk 	__le32 devcap2;
60e0d9d30bSGrzegorz Jaszczyk 	__le16 devctl2;
61e0d9d30bSGrzegorz Jaszczyk 	__le16 devsta2;
62e0d9d30bSGrzegorz Jaszczyk 	__le32 lnkcap2;
63e0d9d30bSGrzegorz Jaszczyk 	__le16 lnkctl2;
64e0d9d30bSGrzegorz Jaszczyk 	__le16 lnksta2;
65e0d9d30bSGrzegorz Jaszczyk 	__le32 slotcap2;
66e0d9d30bSGrzegorz Jaszczyk 	__le16 slotctl2;
67e0d9d30bSGrzegorz Jaszczyk 	__le16 slotsta2;
6823a5fba4SThomas Petazzoni };
6923a5fba4SThomas Petazzoni 
7023a5fba4SThomas Petazzoni struct pci_bridge_emul;
7123a5fba4SThomas Petazzoni 
7223a5fba4SThomas Petazzoni typedef enum { PCI_BRIDGE_EMUL_HANDLED,
7323a5fba4SThomas Petazzoni 	       PCI_BRIDGE_EMUL_NOT_HANDLED } pci_bridge_emul_read_status_t;
7423a5fba4SThomas Petazzoni 
7523a5fba4SThomas Petazzoni struct pci_bridge_emul_ops {
7623a5fba4SThomas Petazzoni 	/*
7723a5fba4SThomas Petazzoni 	 * Called when reading from the regular PCI bridge
7823a5fba4SThomas Petazzoni 	 * configuration space. Return PCI_BRIDGE_EMUL_HANDLED when the
7923a5fba4SThomas Petazzoni 	 * operation has handled the read operation and filled in the
8023a5fba4SThomas Petazzoni 	 * *value, or PCI_BRIDGE_EMUL_NOT_HANDLED when the read should
8123a5fba4SThomas Petazzoni 	 * be emulated by the common code by reading from the
8223a5fba4SThomas Petazzoni 	 * in-memory copy of the configuration space.
8323a5fba4SThomas Petazzoni 	 */
8423a5fba4SThomas Petazzoni 	pci_bridge_emul_read_status_t (*read_base)(struct pci_bridge_emul *bridge,
8523a5fba4SThomas Petazzoni 						   int reg, u32 *value);
8623a5fba4SThomas Petazzoni 
8723a5fba4SThomas Petazzoni 	/*
8823a5fba4SThomas Petazzoni 	 * Same as ->read_base(), except it is for reading from the
8923a5fba4SThomas Petazzoni 	 * PCIe capability configuration space.
9023a5fba4SThomas Petazzoni 	 */
9123a5fba4SThomas Petazzoni 	pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge,
9223a5fba4SThomas Petazzoni 						   int reg, u32 *value);
93c0bd4197SRussell King 
94c0bd4197SRussell King 	/*
95c0bd4197SRussell King 	 * Same as ->read_base(), except it is for reading from the
96c0bd4197SRussell King 	 * PCIe extended capability configuration space.
97c0bd4197SRussell King 	 */
98c0bd4197SRussell King 	pci_bridge_emul_read_status_t (*read_ext)(struct pci_bridge_emul *bridge,
99c0bd4197SRussell King 						  int reg, u32 *value);
100c0bd4197SRussell King 
10123a5fba4SThomas Petazzoni 	/*
10223a5fba4SThomas Petazzoni 	 * Called when writing to the regular PCI bridge configuration
10323a5fba4SThomas Petazzoni 	 * space. old is the current value, new is the new value being
10423a5fba4SThomas Petazzoni 	 * written, and mask indicates which parts of the value are
10523a5fba4SThomas Petazzoni 	 * being changed.
10623a5fba4SThomas Petazzoni 	 */
10723a5fba4SThomas Petazzoni 	void (*write_base)(struct pci_bridge_emul *bridge, int reg,
10823a5fba4SThomas Petazzoni 			   u32 old, u32 new, u32 mask);
10923a5fba4SThomas Petazzoni 
11023a5fba4SThomas Petazzoni 	/*
11123a5fba4SThomas Petazzoni 	 * Same as ->write_base(), except it is for writing from the
11223a5fba4SThomas Petazzoni 	 * PCIe capability configuration space.
11323a5fba4SThomas Petazzoni 	 */
11423a5fba4SThomas Petazzoni 	void (*write_pcie)(struct pci_bridge_emul *bridge, int reg,
11523a5fba4SThomas Petazzoni 			   u32 old, u32 new, u32 mask);
116c0bd4197SRussell King 
117c0bd4197SRussell King 	/*
118c0bd4197SRussell King 	 * Same as ->write_base(), except it is for writing from the
119c0bd4197SRussell King 	 * PCIe extended capability configuration space.
120c0bd4197SRussell King 	 */
121c0bd4197SRussell King 	void (*write_ext)(struct pci_bridge_emul *bridge, int reg,
122c0bd4197SRussell King 			  u32 old, u32 new, u32 mask);
12323a5fba4SThomas Petazzoni };
12423a5fba4SThomas Petazzoni 
12559f81c35SThomas Petazzoni struct pci_bridge_reg_behavior;
12659f81c35SThomas Petazzoni 
12723a5fba4SThomas Petazzoni struct pci_bridge_emul {
12823a5fba4SThomas Petazzoni 	struct pci_bridge_emul_conf conf;
12923a5fba4SThomas Petazzoni 	struct pci_bridge_emul_pcie_conf pcie_conf;
13064a70f52SPali Rohár 	const struct pci_bridge_emul_ops *ops;
13159f81c35SThomas Petazzoni 	struct pci_bridge_reg_behavior *pci_regs_behavior;
13259f81c35SThomas Petazzoni 	struct pci_bridge_reg_behavior *pcie_cap_regs_behavior;
13323a5fba4SThomas Petazzoni 	void *data;
134*658aea35SPali Rohár 	u8 pcie_start;
135*658aea35SPali Rohár 	u8 ssid_start;
13623a5fba4SThomas Petazzoni 	bool has_pcie;
1373767a902SPali Rohár 	u16 subsystem_vendor_id;
1383767a902SPali Rohár 	u16 subsystem_id;
13923a5fba4SThomas Petazzoni };
14023a5fba4SThomas Petazzoni 
14133776d05SThomas Petazzoni enum {
142d3f332b5SPali Rohár 	/*
143d3f332b5SPali Rohár 	 * PCI bridge does not support forwarding of prefetchable memory
144d3f332b5SPali Rohár 	 * requests between primary and secondary buses.
145d3f332b5SPali Rohár 	 */
146d3f332b5SPali Rohár 	PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD = BIT(0),
14705241c13SPali Rohár 
14805241c13SPali Rohár 	/*
14905241c13SPali Rohár 	 * PCI bridge does not support forwarding of IO requests between
15005241c13SPali Rohár 	 * primary and secondary buses.
15105241c13SPali Rohár 	 */
15205241c13SPali Rohár 	PCI_BRIDGE_EMUL_NO_IO_FORWARD = BIT(1),
15333776d05SThomas Petazzoni };
15433776d05SThomas Petazzoni 
15533776d05SThomas Petazzoni int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
15633776d05SThomas Petazzoni 			 unsigned int flags);
15759f81c35SThomas Petazzoni void pci_bridge_emul_cleanup(struct pci_bridge_emul *bridge);
15859f81c35SThomas Petazzoni 
15923a5fba4SThomas Petazzoni int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
16023a5fba4SThomas Petazzoni 			      int size, u32 *value);
16123a5fba4SThomas Petazzoni int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
16223a5fba4SThomas Petazzoni 			       int size, u32 value);
16323a5fba4SThomas Petazzoni 
16423a5fba4SThomas Petazzoni #endif /* __PCI_BRIDGE_EMUL_H__ */
165