aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/pcie_layerscape_gen4.h
blob: 805c23a7da0c4fcd76c8e43d9a1d960d93fca592 (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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright 2018-2019 NXP
 *
 * PCIe Gen4 driver for NXP Layerscape SoCs
 * Author: Hou Zhiqiang <Minder.Hou@gmail.com>
 */

#ifndef _PCIE_LAYERSCAPE_GEN4_H_
#define _PCIE_LAYERSCAPE_GEN4_H_
#include <pci.h>
#include <linux/bitops.h>

#ifndef CFG_SYS_PCI_MEMORY_SIZE
#define CFG_SYS_PCI_MEMORY_SIZE		(4 * 1024 * 1024 * 1024ULL)
#endif

#ifndef CFG_SYS_PCI_EP_MEMORY_BASE
#define CFG_SYS_PCI_EP_MEMORY_BASE		CONFIG_SYS_LOAD_ADDR
#endif

#define PCIE_PF_NUM				2
#define PCIE_VF_NUM				32

#define LS_G4_PF0				0
#define LS_G4_PF1				1
#define PF_BAR_NUM				4
#define VF_BAR_NUM				4
#define PCIE_BAR_SIZE				(8 * 1024)		/* 8K */
#define PCIE_BAR0_SIZE				PCIE_BAR_SIZE
#define PCIE_BAR1_SIZE				PCIE_BAR_SIZE
#define PCIE_BAR2_SIZE				PCIE_BAR_SIZE
#define PCIE_BAR4_SIZE				PCIE_BAR_SIZE
#define SIZE_1T					(1024 * 1024 * 1024 * 1024ULL)

/* GPEX CSR */
#define GPEX_CLASSCODE				0x474
#define GPEX_CLASSCODE_SHIFT			16
#define GPEX_CLASSCODE_MASK			0xffff

#define GPEX_CFG_READY				0x4b0
#define PCIE_CONFIG_READY			BIT(0)

#define GPEX_BAR_ENABLE				0x4d4
#define GPEX_BAR_SIZE_LDW			0x4d8
#define GPEX_BAR_SIZE_UDW			0x4dC
#define GPEX_BAR_SELECT				0x4e0

#define BAR_POS(bar, pf, vf_bar)		\
	((bar) + (pf) * PF_BAR_NUM + (vf_bar) * PCIE_PF_NUM * PF_BAR_NUM)

#define GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf)	(0x644 + (pf) * 4)
#define TTL_VF_MASK				0xffff
#define TTL_VF_SHIFT				16
#define INI_VF_MASK				0xffff
#define INI_VF_SHIFT				0
#define GPEX_SRIOV_VF_OFFSET_STRIDE(pf)		(0x704 + (pf) * 4)

/* PAB CSR */
#define PAB_CTRL				0x808
#define PAB_CTRL_APIO_EN			BIT(0)
#define PAB_CTRL_PPIO_EN			BIT(1)
#define PAB_CTRL_MAX_BRST_LEN_SHIFT		4
#define PAB_CTRL_MAX_BRST_LEN_MASK		0x3
#define PAB_CTRL_PAGE_SEL_SHIFT			13
#define PAB_CTRL_PAGE_SEL_MASK			0x3f
#define PAB_CTRL_FUNC_SEL_SHIFT			19
#define PAB_CTRL_FUNC_SEL_MASK			0x1ff

#define PAB_RST_CTRL				0x820
#define PAB_BR_STAT				0x80c

/* AXI PIO Engines */
#define PAB_AXI_PIO_CTRL(idx)			(0x840 + 0x10 * (idx))
#define APIO_EN					BIT(0)
#define MEM_WIN_EN				BIT(1)
#define IO_WIN_EN				BIT(2)
#define CFG_WIN_EN				BIT(3)
#define PAB_AXI_PIO_STAT(idx)			(0x844 + 0x10 * (idx))
#define PAB_AXI_PIO_SL_CMD_STAT(idx)		(0x848 + 0x10 * (idx))
#define PAB_AXI_PIO_SL_ADDR_STAT(idx)		(0x84c + 0x10 * (idx))
#define PAB_AXI_PIO_SL_EXT_ADDR_STAT(idx)	(0xb8a0 + 0x4 * (idx))

/* PEX PIO Engines */
#define PAB_PEX_PIO_CTRL(idx)			(0x8c0 + 0x10 * (idx))
#define PPIO_EN					BIT(0)
#define PAB_PEX_PIO_STAT(idx)			(0x8c4 + 0x10 * (idx))
#define PAB_PEX_PIO_MT_STAT(idx)		(0x8c8 + 0x10 * (idx))

#define INDIRECT_ADDR_BNDRY			0xc00
#define PAGE_IDX_SHIFT				10
#define PAGE_ADDR_MASK				0x3ff

#define OFFSET_TO_PAGE_IDX(off)			\
	(((off) >> PAGE_IDX_SHIFT) & PAB_CTRL_PAGE_SEL_MASK)

#define OFFSET_TO_PAGE_ADDR(off)		\
	(((off) & PAGE_ADDR_MASK) | INDIRECT_ADDR_BNDRY)

/* APIO WINs */
#define PAB_AXI_AMAP_CTRL(idx)			(0xba0 + 0x10 * (idx))
#define PAB_EXT_AXI_AMAP_SIZE(idx)		(0xbaf0 + 0x4 * (idx))
#define PAB_AXI_AMAP_AXI_WIN(idx)		(0xba4 + 0x10 * (idx))
#define PAB_EXT_AXI_AMAP_AXI_WIN(idx)		(0x80a0 + 0x4 * (idx))
#define PAB_AXI_AMAP_PEX_WIN_L(idx)		(0xba8 + 0x10 * (idx))
#define PAB_AXI_AMAP_PEX_WIN_H(idx)		(0xbac + 0x10 * (idx))
#define PAB_AXI_AMAP_PCI_HDR_PARAM(idx)		(0x5ba0 + 0x4 * (idx))
#define FUNC_NUM_PCIE_MASK			GENMASK(7, 0)

#define AXI_AMAP_CTRL_EN			BIT(0)
#define AXI_AMAP_CTRL_TYPE_SHIFT		1
#define AXI_AMAP_CTRL_TYPE_MASK			0x3
#define AXI_AMAP_CTRL_SIZE_SHIFT		10
#define AXI_AMAP_CTRL_SIZE_MASK			0x3fffff

#define PAB_TARGET_BUS(x)			(((x) & 0xff) << 24)
#define PAB_TARGET_DEV(x)			(((x) & 0x1f) << 19)
#define PAB_TARGET_FUNC(x)			(((x) & 0x7) << 16)

#define PAB_AXI_TYPE_CFG			0x00
#define PAB_AXI_TYPE_IO				0x01
#define PAB_AXI_TYPE_MEM			0x02
#define PAB_AXI_TYPE_ATOM			0x03

#define PAB_WINS_NUM				256

/* PPIO WINs RC mode */
#define PAB_PEX_AMAP_CTRL(idx)			(0x4ba0 + 0x10 * (idx))
#define PAB_EXT_PEX_AMAP_SIZE(idx)		(0xbef0 + 0x04 * (idx))
#define PAB_PEX_AMAP_AXI_WIN(idx)		(0x4ba4 + 0x10 * (idx))
#define PAB_EXT_PEX_AMAP_AXI_WIN(idx)		(0xb4a0 + 0x04 * (idx))
#define PAB_PEX_AMAP_PEX_WIN_L(idx)		(0x4ba8 + 0x10 * (idx))
#define PAB_PEX_AMAP_PEX_WIN_H(idx)		(0x4bac + 0x10 * (idx))

#define IB_TYPE_MEM_F				0x2
#define IB_TYPE_MEM_NF				0x3

#define PEX_AMAP_CTRL_TYPE_SHIFT		0x1
#define PEX_AMAP_CTRL_EN_SHIFT			0x0
#define PEX_AMAP_CTRL_TYPE_MASK			0x3
#define PEX_AMAP_CTRL_EN_MASK			0x1

/* PPIO WINs EP mode */
#define PAB_PEX_BAR_AMAP(pf, bar)		\
	(0x1ba0 + 0x20 * (pf) + 4 * (bar))
#define BAR_AMAP_EN				BIT(0)
#define PAB_EXT_PEX_BAR_AMAP(pf, bar)		\
	(0x84a0 + 0x20 * (pf) + 4 * (bar))

/* CCSR registers */
#define PCIE_LINK_CTRL_STA			0x5c
#define PCIE_LINK_SPEED_SHIFT			16
#define PCIE_LINK_SPEED_MASK			0x0f
#define PCIE_LINK_WIDTH_SHIFT			20
#define PCIE_LINK_WIDTH_MASK			0x3f
#define PCIE_SRIOV_CAPABILITY			0x2a0
#define PCIE_SRIOV_VF_OFFSET_STRIDE		0x2b4

/* LUT registers */
#define PCIE_LUT_UDR(n)				(0x800 + (n) * 8)
#define PCIE_LUT_LDR(n)				(0x804 + (n) * 8)
#define PCIE_LUT_ENABLE				BIT(31)
#define PCIE_LUT_ENTRY_COUNT			32

/* PF control registers */
#define PCIE_LTSSM_STA				0x7fc
#define LTSSM_STATE_MASK			0x7f
#define LTSSM_PCIE_L0				0x2d /* L0 state */

#define PCIE_SRDS_PRTCL(idx)			(PCIE1 + (idx))
#define PCIE_SYS_BASE_ADDR			0x3400000
#define PCIE_CCSR_SIZE				0x0100000

struct ls_pcie_g4 {
	int idx;
	struct list_head list;
	struct udevice *bus;
	struct fdt_resource ccsr_res;
	struct fdt_resource cfg_res;
	struct fdt_resource lut_res;
	struct fdt_resource pf_ctrl_res;
	void __iomem *ccsr;
	void __iomem *cfg;
	void __iomem *lut;
	void __iomem *pf_ctrl;
	bool big_endian;
	bool enabled;
	int next_lut_index;
	struct pci_controller hose;
	int stream_id_cur;
	int mode;
	int sriov_support;
};

extern struct list_head ls_pcie_g4_list;

static inline void lut_writel(struct ls_pcie_g4 *pcie, unsigned int value,
			      unsigned int offset)
{
	if (pcie->big_endian)
		out_be32(pcie->lut + offset, value);
	else
		out_le32(pcie->lut + offset, value);
}

static inline u32 lut_readl(struct ls_pcie_g4 *pcie, unsigned int offset)
{
	if (pcie->big_endian)
		return in_be32(pcie->lut + offset);
	else
		return in_le32(pcie->lut + offset);
}

static inline void ccsr_set_page(struct ls_pcie_g4 *pcie, u8 pg_idx)
{
	u32 val;

	val = in_le32(pcie->ccsr + PAB_CTRL);
	val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT);
	val |= (pg_idx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT;

	out_le32(pcie->ccsr + PAB_CTRL, val);
}

static inline unsigned int ccsr_readl(struct ls_pcie_g4 *pcie, u32 offset)
{
	if (offset < INDIRECT_ADDR_BNDRY) {
		ccsr_set_page(pcie, 0);
		return in_le32(pcie->ccsr + offset);
	}

	ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
	return in_le32(pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset));
}

static inline void ccsr_writel(struct ls_pcie_g4 *pcie, u32 offset, u32 value)
{
	if (offset < INDIRECT_ADDR_BNDRY) {
		ccsr_set_page(pcie, 0);
		out_le32(pcie->ccsr + offset, value);
	} else {
		ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset));
		out_le32(pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset), value);
	}
}

static inline unsigned int pf_ctrl_readl(struct ls_pcie_g4 *pcie, u32 offset)
{
	if (pcie->big_endian)
		return in_be32(pcie->pf_ctrl + offset);
	else
		return in_le32(pcie->pf_ctrl + offset);
}

static inline void pf_ctrl_writel(struct ls_pcie_g4 *pcie, u32 offset,
				  u32 value)
{
	if (pcie->big_endian)
		out_be32(pcie->pf_ctrl + offset, value);
	else
		out_le32(pcie->pf_ctrl + offset, value);
}

#endif /* _PCIE_LAYERSCAPE_GEN4_H_ */