aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/include/asm/pci.h
blob: 553b7ff018c4435e08039075c2b8324975239172 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
 * Copyright 2010 Tilera Corporation. All Rights Reserved.
 *
 *   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, version 2.
 *
 *   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, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

#ifndef _ASM_TILE_PCI_H
#define _ASM_TILE_PCI_H

#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/numa.h>
#include <asm-generic/pci_iomap.h>

#ifndef __tilegx__

/*
 * Structure of a PCI controller (host bridge)
 */
struct pci_controller {
	int index;		/* PCI domain number */
	struct pci_bus *root_bus;

	int first_busno;
	int last_busno;

	int hv_cfg_fd[2];	/* config{0,1} fds for this PCIe controller */
	int hv_mem_fd;		/* fd to Hypervisor for MMIO operations */

	struct pci_ops *ops;

	int irq_base;		/* Base IRQ from the Hypervisor	*/
	int plx_gen1;		/* flag for PLX Gen 1 configuration */

	/* Address ranges that are routed to this controller/bridge. */
	struct resource mem_resources[3];
};

/*
 * This flag tells if the platform is TILEmpower that needs
 * special configuration for the PLX switch chip.
 */
extern int tile_plx_gen1;

static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}

#define	TILE_NUM_PCIE	2

/*
 * The hypervisor maps the entirety of CPA-space as bus addresses, so
 * bus addresses are physical addresses.  The networking and block
 * device layers use this boolean for bounce buffer decisions.
 */
#define PCI_DMA_BUS_IS_PHYS     1

/* generic pci stuff */
#include <asm-generic/pci.h>

#else

#include <asm/page.h>
#include <gxio/trio.h>

/**
 * We reserve the hugepage-size address range at the top of the 64-bit address
 * space to serve as the PCI window, emulating the BAR0 space of an endpoint
 * device. This window is used by the chip-to-chip applications running on
 * the RC node. The reason for carving out this window is that Mem-Maps that
 * back up this window will not overlap with those that map the real physical
 * memory.
 */
#define PCIE_HOST_BAR0_SIZE		HPAGE_SIZE
#define PCIE_HOST_BAR0_START		HPAGE_MASK

/**
 * The first PAGE_SIZE of the above "BAR" window is mapped to the
 * gxpci_host_regs structure.
 */
#define PCIE_HOST_REGS_SIZE		PAGE_SIZE

/*
 * This is the PCI address where the Mem-Map interrupt regions start.
 * We use the 2nd to the last huge page of the 64-bit address space.
 * The last huge page is used for the rootcomplex "bar", for C2C purpose.
 */
#define	MEM_MAP_INTR_REGIONS_BASE	(HPAGE_MASK - HPAGE_SIZE)

/*
 * Each Mem-Map interrupt region occupies 4KB.
 */
#define	MEM_MAP_INTR_REGION_SIZE	(1 << TRIO_MAP_MEM_LIM__ADDR_SHIFT)

/*
 * Allocate the PCI BAR window right below 4GB.
 */
#define	TILE_PCI_BAR_WINDOW_TOP		(1ULL << 32)

/*
 * Allocate 1GB for the PCI BAR window.
 */
#define	TILE_PCI_BAR_WINDOW_SIZE	(1 << 30)

/*
 * This is the highest bus address targeting the host memory that
 * can be generated by legacy PCI devices with 32-bit or less
 * DMA capability, dictated by the BAR window size and location.
 */
#define	TILE_PCI_MAX_DIRECT_DMA_ADDRESS \
	(TILE_PCI_BAR_WINDOW_TOP - TILE_PCI_BAR_WINDOW_SIZE - 1)

/*
 * We shift the PCI bus range for all the physical memory up by the whole PA
 * range. The corresponding CPA of an incoming PCI request will be the PCI
 * address minus TILE_PCI_MEM_MAP_BASE_OFFSET. This also implies
 * that the 64-bit capable devices will be given DMA addresses as
 * the CPA plus TILE_PCI_MEM_MAP_BASE_OFFSET. To support 32-bit
 * devices, we create a separate map region that handles the low
 * 4GB.
 */
#define	TILE_PCI_MEM_MAP_BASE_OFFSET	(1ULL << CHIP_PA_WIDTH())

/*
 * End of the PCI memory resource.
 */
#define	TILE_PCI_MEM_END	\
		((1ULL << CHIP_PA_WIDTH()) + TILE_PCI_BAR_WINDOW_TOP)

/*
 * Start of the PCI memory resource.
 */
#define	TILE_PCI_MEM_START	(TILE_PCI_MEM_END - TILE_PCI_BAR_WINDOW_SIZE)

/*
 * Structure of a PCI controller (host bridge) on Gx.
 */
struct pci_controller {

	/* Pointer back to the TRIO that this PCIe port is connected to. */
	gxio_trio_context_t *trio;
	int mac;		/* PCIe mac index on the TRIO shim */
	int trio_index;		/* Index of TRIO shim that contains the MAC. */

	int pio_mem_index;	/* PIO region index for memory access */

	/*
	 * Mem-Map regions for all the memory controllers so that Linux can
	 * map all of its physical memory space to the PCI bus.
	 */
	int mem_maps[MAX_NUMNODES];

	int index;		/* PCI domain number */
	struct pci_bus *root_bus;

	uint64_t mem_offset;	/* cpu->bus memory mapping offset. */

	int last_busno;

	struct pci_ops *ops;

	/* Table that maps the INTx numbers to Linux irq numbers. */
	int irq_intx_table[4];

	struct resource mem_space;

	/* Address ranges that are routed to this controller/bridge. */
	struct resource mem_resources[3];
};

extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];

extern void pci_iounmap(struct pci_dev *dev, void __iomem *);

extern void
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
			struct resource *res);

extern void
pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
			struct pci_bus_region *region);

/*
 * The PCI address space does not equal the physical memory address
 * space (we have an IOMMU). The IDE and SCSI device layers use this
 * boolean for bounce buffer decisions.
 */
#define PCI_DMA_BUS_IS_PHYS     0

#endif /* __tilegx__ */

int __init tile_pci_init(void);
int __init pcibios_init(void);

void __devinit pcibios_fixup_bus(struct pci_bus *bus);

#define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index)

/*
 * This decides whether to display the domain number in /proc.
 */
static inline int pci_proc_domain(struct pci_bus *bus)
{
	return 1;
}

/*
 * pcibios_assign_all_busses() tells whether or not the bus numbers
 * should be reassigned, in case the BIOS didn't do it correctly, or
 * in case we don't have a BIOS and we want to let Linux do it.
 */
static inline int pcibios_assign_all_busses(void)
{
	return 1;
}

#define PCIBIOS_MIN_MEM		0
#define PCIBIOS_MIN_IO		0

/* Use any cpu for PCI. */
#define cpumask_of_pcibus(bus) cpu_online_mask

/* implement the pci_ DMA API in terms of the generic device dma_ one */
#include <asm-generic/pci-dma-compat.h>

#endif /* _ASM_TILE_PCI_H */