summaryrefslogtreecommitdiffstats
path: root/src/soc/qualcomm/common/include/soc/pcie.h
blob: 09ea6712dc760cda14f5b956d57c45e7faf4bffc (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
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _PCIE_H_
#define _PCIE_H_

#include <types.h>
#include <device/device.h>
#include <soc/gpio.h>

/*
 * Config, IO and MMIO space offsets relative to controller base and sizes.
 *
 * EP config space starts at 1MB offset from controller base.
 * EP config space size would be 4KB for each endpoint.
 * IO space starts at 2MB offset from controller base and its of 1MB size.
 * MMIO space starts from 3MB offset from controller base and it can be up to
 * end of space reserved for PCIe.
 */
#define PCIE_EP_CONF_OFFSET		0x100000
#define PCIE_EP_CONF_SIZE		0x1000
#define PCIE_IO_SPACE_OFFSET		0x200000
#define PCIE_IO_SPACE_SIZE		0x100000
#define PCIE_MMIO_SPACE_OFFSET		0x300000

/* Parf Registers */
#define PCIE_PARF_SYS_CTRL		0x00
#define MAC_PHY_PWRDOWN_MUX_EN		BIT(29)
#define PCIE_PARF_PHY_CTRL		0x40
#define PHY_PWR_DOWN			BIT(0)
#define PCIE_PARF_MHI_CLOCK_RESET_CTRL	0x174
#define MHI_BYPASS			BIT(4)
#define PCIE_PARF_LTSSM			0x1B0
#define LTSSM_EN			BIT(8)
#define PCIE_PARF_DBI_BASE_ADDR		0x350
#define PCIE_PARF_DEVICE_TYPE		0x1000
#define DEVICE_TYPE_RC			0x4
#define PCIE_PARF_BDF_TO_SID_CFG	0x2C00
#define BDF_TO_SID_BYPASS		BIT(0)

/* ELBI */
#define PCIE3X2_ELBI_SYS_STTS		0x08
#define XMLH_LINK_UP			0x400

/* DBI Registers */
#define PCIE_LINK_CAPABILITY		0x7c
#define PCIE_LINK_CTL_2			0xa0
#define TARGET_LINK_SPEED_MASK		0xf
#define LINK_SPEED_GEN_1		0x1
#define LINK_SPEED_GEN_2		0x2
#define LINK_SPEED_GEN_3		0x3
#define PCIE_LINK_UP_MS			100
#define LINK_WAIT_MAX_RETRIES		10

#define COMMAND_MASK			0xffff

#define TYPE1_HDR_BUS_NUM_MASK		0xffffff
#define RC_PRI_BUS_NUM			0x0
#define RC_SEC_BUS_NUM			0x1
#define RC_SUB_BUS_NUM			0xff
#define ROOT_PORT_BUS_NUM		((RC_SUB_BUS_NUM << 16) | \
					(RC_SEC_BUS_NUM << 8)  | \
					RC_PRI_BUS_NUM)

/* Synopsys-specific PCIe configuration registers */
#define PCIE_DBI_MISC_CONTROL_1_OFF	0x8BC
#define PCIE_DBI_RO_WR_EN		BIT(0)

#define PCIE_3x2_NUM_LANES		2
#define PCIE_LINK_WIDTH_SPEED_CONTROL	0x80C
#define PORT_LOGIC_LINK_WIDTH_MASK	(0x1f << 8)
#define PORT_LOGIC_LINK_WIDTH_1_LANES	(0x1 << 8)
#define PORT_LOGIC_LINK_WIDTH_2_LANES	(0x2 << 8)
#define PORT_LOGIC_LINK_WIDTH_4_LANES	(0x4 << 8)
#define PORT_LOGIC_LINK_WIDTH_8_LANES	(0x8 << 8)

#define PCIE_PORT_LINK_CONTROL		0x710
#define PORT_LINK_MODE_MASK		(0x3f << 16)
#define PORT_LINK_MODE_1_LANES		(0x1 << 16)
#define PORT_LINK_MODE_2_LANES		(0x3 << 16)
#define PORT_LINK_MODE_4_LANES		(0x7 << 16)
#define PORT_LINK_MODE_8_LANES		(0xf << 16)

/*
 * iATU Unroll-specific register definitions
 * From DesignWare PCIe core v4.80, the address translation
 * will be made by unroll
 */
#define PCIE_ATU_REGION_INDEX1		0x1
#define PCIE_ATU_REGION_INDEX0		0x0
#define PCIE_ATU_TYPE_MEM		0x0
#define PCIE_ATU_TYPE_CFG0		0x4
#define PCIE_ATU_TYPE_CFG1		0x5
#define PCIE_ATU_ENABLE			BIT(31)
#define PCIE_ATU_BUS(x)			(((x) & 0xff) << 24)
#define PCIE_ATU_DEV(x)			(((x) & 0x1f) << 19)
#define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)

#define PCIE_ATU_UNR_REGION_CTRL1	0x00
#define PCIE_ATU_UNR_REGION_CTRL2	0x04
#define PCIE_ATU_UNR_LOWER_BASE		0x08
#define PCIE_ATU_UNR_UPPER_BASE		0x0C
#define PCIE_ATU_UNR_LIMIT		0x10
#define PCIE_ATU_UNR_LOWER_TARGET	0x14
#define PCIE_ATU_UNR_UPPER_TARGET	0x18

#define LINK_WAIT_MAX_IATU_RETRIES	5
#define LINK_WAIT_IATU			1000

/* PHY Specific fields */
#define QPHY_SW_RESET			0x00
#define SW_RESET			BIT(0)
#define QPHY_PCS_STATUS			0x14
#define PHY_STATUS			BIT(6)
#define QPHY_PCS_PWR_DWN_CNTRL		0x40
#define SW_PWRDN			BIT(0)
#define REFCLK_DRV_DSBL			BIT(1)
#define QPHY_START_CTRL			0x44
#define SERDES_START			BIT(0)
#define PCS_START			BIT(1)

/* Register address builder */
#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((region) << 9)
#define lower_32_bits(n)		((u32)(n))
#define upper_32_bits(n)		((u32)(((n) >> 16) >> 16))

#define QMP_PHY_INIT_CFG(o, v)		\
	{				\
		.offset = o,		\
		.val = v,		\
		.lane_mask = 0xff,	\
	}

typedef uint64_t pci_addr_t;
typedef uint64_t pci_size_t;

struct qcom_qmp_phy_init_tbl {
	unsigned int offset;
	uint32_t val;
	unsigned short lane_mask;
};

struct pcie_region {
	pci_addr_t	bus_start;	/* BDF */
	uint64_t	phys_start;	/* Start in physical address space */
	pci_size_t	size;		/* Size */
};

/**
 * struct pcie_cntlr_cfg_t - QCOM DW PCIe Controller state
 *
 * @lanes : Number of lanes
 * @cfg_size : The size of the configuration space
 * @cfg_base : The base address of config space
 * @dbi_base : The base address of dbi register space
 * @atu_base : The base address of address translation unit
 * @parf : The base address of PARF register space
 * @elbi : The base address of ELBI space
 * @phy  : Base address of the PHY controller
 * @pcie_bcr : address of the block controller register
 * @reset : PERST gpio
 * @io : Base address of the IO region
 * @mem : Base address of memory region
 */
typedef struct {
	unsigned int lanes;
	unsigned int cfg_size;
	void	*cfg_base;
	void	*dbi_base;
	void	*atu_base;
	void	*parf;
	void	*elbi;
	void	*pcie_bcr;
	void	*qmp_phy_bcr;
	gpio_t	perst;
	/* IO and MEM PCI regions */
	struct	pcie_region io;
	struct	pcie_region mem;
} pcie_cntlr_cfg_t;

typedef struct {
	void *qmp_phy_base;
	void *serdes;
	void *tx0;
	void *rx0;
	void *pcs;
	void *tx1;
	void *rx1;
	void *pcs_misc;

	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
	const struct qcom_qmp_phy_init_tbl *serdes_tbl;
	unsigned int serdes_tbl_num;
	const struct qcom_qmp_phy_init_tbl *serdes_tbl_sec;
	unsigned int serdes_tbl_num_sec;
	const struct qcom_qmp_phy_init_tbl *tx_tbl;
	unsigned int tx_tbl_num;
	const struct qcom_qmp_phy_init_tbl *tx_tbl_sec;
	unsigned int tx_tbl_num_sec;
	const struct qcom_qmp_phy_init_tbl *rx_tbl;
	unsigned int rx_tbl_num;
	const struct qcom_qmp_phy_init_tbl *rx_tbl_sec;
	unsigned int rx_tbl_num_sec;
	const struct qcom_qmp_phy_init_tbl *pcs_tbl;
	unsigned int pcs_tbl_num;
	const struct qcom_qmp_phy_init_tbl *pcs_tbl_sec;
	unsigned int pcs_tbl_num_sec;
	const struct qcom_qmp_phy_init_tbl *pcs_misc_tbl;
	unsigned int pcs_misc_tbl_num;
	const struct qcom_qmp_phy_init_tbl *pcs_misc_tbl_sec;
	unsigned int pcs_misc_tbl_num_sec;
} pcie_qmp_phy_cfg_t;

struct qcom_pcie_cntlr_t {
	pcie_cntlr_cfg_t	*cntlr_cfg;
	pcie_qmp_phy_cfg_t	*qmp_phy_cfg;
};

int qcom_dw_pcie_enable_clock(void);
int qcom_dw_pcie_enable_pipe_clock(void);
void gcom_pcie_power_on_ep(void);
void gcom_pcie_get_config(struct qcom_pcie_cntlr_t *host_cfg);
void qcom_pci_domain_read_resources(struct device *dev);
void qcom_setup_pcie_host(struct device *dev);

#endif