1/*-
2 * This file is provided under a dual BSD/GPLv2 license.  When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright (C) 2019 Advanced Micro Devices, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * BSD LICENSE
14 *
15 * Copyright (C) 2019 Advanced Micro Devices, Inc.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copy
23 *    notice, this list of conditions and the following disclaimer in
24 *    the documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of AMD corporation nor the names of its
26 *    contributors may be used to endorse or promote products derived
27 *    from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Contact Information :
42 * Rajesh Kumar <rajesh1.kumar@amd.com>
43 *
44 * $FreeBSD$
45 */
46
47#ifndef	NTB_HW_AMD_H
48#define	NTB_HW_AMD_H
49
50#define	NTB_HW_AMD_VENDOR_ID	0x1022
51#define	NTB_HW_AMD_DEVICE_ID1	0x145B
52#define	NTB_HW_AMD_DEVICE_ID2	0x148B
53
54#define	NTB_HW_HYGON_VENDOR_ID	0x19D4
55#define	NTB_HW_HYGON_DEVICE_ID1	0x145B
56
57#define	NTB_DEF_PEER_CNT	1
58#define	NTB_DEF_PEER_IDX	0
59
60#define	BIT(n)			(1 << n)
61#define	AMD_LINK_HB_TIMEOUT	(1 * hz)
62
63#define	NTB_LIN_STA_ACTIVE_BIT	0x00000002
64#define	NTB_LNK_STA_SPEED_MASK	0x000F0000
65#define	NTB_LNK_STA_WIDTH_MASK	0x03F00000
66#define	NTB_LNK_STA_ACTIVE(x)	(!!((x) & NTB_LIN_STA_ACTIVE_BIT))
67#define	NTB_LNK_STA_SPEED(x)	(((x) & NTB_LNK_STA_SPEED_MASK) >> 16)
68#define	NTB_LNK_STA_WIDTH(x)	(((x) & NTB_LNK_STA_WIDTH_MASK) >> 20)
69
70#define	amd_ntb_bar_read(SIZE, bar, offset) \
71	    bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
72	    ntb->bar_info[(bar)].pci_bus_handle, (offset))
73#define	amd_ntb_bar_write(SIZE, bar, offset, val) \
74	    bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \
75	    ntb->bar_info[(bar)].pci_bus_handle, (offset), (val))
76#define	amd_ntb_reg_read(SIZE, offset) \
77	    amd_ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset)
78#define	amd_ntb_reg_write(SIZE, offset, val) \
79	    amd_ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val)
80#define	amd_ntb_peer_reg_read(SIZE, offset) \
81	    amd_ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset + AMD_PEER_OFFSET)
82#define	amd_ntb_peer_reg_write(SIZE, offset, val) \
83	    amd_ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset + AMD_PEER_OFFSET, val)
84
85#define	DB_MASK_LOCK(sc)	mtx_lock_spin(&(sc)->db_mask_lock)
86#define	DB_MASK_UNLOCK(sc)	mtx_unlock_spin(&(sc)->db_mask_lock)
87#define	DB_MASK_ASSERT(sc, f)	mtx_assert(&(sc)->db_mask_lock, (f))
88
89#define QUIRK_MW0_32BIT	0x01
90
91/* amd_ntb_conn_type are hardware numbers, cannot change. */
92enum amd_ntb_conn_type {
93	NTB_CONN_NONE = -1,
94	NTB_CONN_PRI,
95	NTB_CONN_SEC,
96};
97
98enum ntb_default_port {
99	NTB_PORT_PRI_USD,
100	NTB_PORT_SEC_DSD
101};
102
103enum amd_ntb_bar {
104	NTB_CONFIG_BAR = 0,
105	NTB_BAR_1,
106	NTB_BAR_2,
107	NTB_BAR_3,
108	NTB_MAX_BARS
109};
110
111struct amd_ntb_hw_info {
112	uint16_t vendor_id;
113	uint16_t device_id;
114	uint8_t	 mw_count;
115	uint8_t	 bar_start_idx;
116	uint8_t	 spad_count;
117	uint8_t	 db_count;
118	uint8_t	 msix_vector_count;
119	uint8_t	 quirks;
120	char	 *desc;
121};
122
123struct amd_ntb_pci_bar_info {
124	bus_space_tag_t		pci_bus_tag;
125	bus_space_handle_t	pci_bus_handle;
126	struct resource		*pci_resource;
127	vm_paddr_t		pbase;
128	caddr_t			vbase;
129	vm_size_t		size;
130	vm_memattr_t		map_mode;
131	int			pci_resource_id;
132
133	/* Configuration register offsets */
134	uint32_t		xlat_off;
135	uint32_t		limit_off;
136};
137
138struct amd_ntb_int_info {
139	struct resource	*res;
140	void		*tag;
141	int		rid;
142};
143
144struct amd_ntb_vec {
145	struct amd_ntb_softc	*ntb;
146	uint32_t		num;
147	unsigned		masked;
148};
149
150enum {
151	/* AMD NTB Link Status Offset */
152	AMD_LINK_STATUS_OFFSET	= 0x68,
153
154	/*  AMD NTB register offset */
155	AMD_CNTL_OFFSET		= 0x200,
156
157	/* NTB control register bits */
158	PMM_REG_CTL		= BIT(21),
159	SMM_REG_CTL		= BIT(20),
160	SMM_REG_ACC_PATH	= BIT(18),
161	PMM_REG_ACC_PATH	= BIT(17),
162	NTB_CLK_EN		= BIT(16),
163
164	AMD_STA_OFFSET		= 0x204,
165	AMD_PGSLV_OFFSET	= 0x208,
166	AMD_SPAD_MUX_OFFSET	= 0x20C,
167	AMD_SPAD_OFFSET		= 0x210,
168	AMD_RSMU_HCID		= 0x250,
169	AMD_RSMU_SIID		= 0x254,
170	AMD_PSION_OFFSET	= 0x300,
171	AMD_SSION_OFFSET	= 0x330,
172	AMD_MMINDEX_OFFSET	= 0x400,
173	AMD_MMDATA_OFFSET	= 0x404,
174	AMD_SIDEINFO_OFFSET	= 0x408,
175
176	AMD_SIDE_MASK		= BIT(0),
177	AMD_SIDE_READY		= BIT(1),
178
179	/* limit register */
180	AMD_ROMBARLMT_OFFSET	= 0x410,
181	AMD_BAR1LMT_OFFSET	= 0x414,
182	AMD_BAR23LMT_OFFSET	= 0x418,
183	AMD_BAR45LMT_OFFSET	= 0x420,
184
185	/* xlat address */
186	AMD_ROMBARXLAT_OFFSET	= 0x428,
187	AMD_BAR1XLAT_OFFSET	= 0x430,
188	AMD_BAR23XLAT_OFFSET	= 0x438,
189	AMD_BAR45XLAT_OFFSET	= 0x440,
190
191	/* doorbell and interrupt */
192	AMD_DBFM_OFFSET		= 0x450,
193	AMD_DBREQ_OFFSET	= 0x454,
194	AMD_MIRRDBSTAT_OFFSET	= 0x458,
195	AMD_DBMASK_OFFSET	= 0x45C,
196	AMD_DBSTAT_OFFSET	= 0x460,
197	AMD_INTMASK_OFFSET	= 0x470,
198	AMD_INTSTAT_OFFSET	= 0x474,
199
200	/* event type */
201	AMD_PEER_FLUSH_EVENT	= BIT(0),
202	AMD_PEER_RESET_EVENT	= BIT(1),
203	AMD_PEER_D3_EVENT	= BIT(2),
204	AMD_PEER_PMETO_EVENT	= BIT(3),
205	AMD_PEER_D0_EVENT	= BIT(4),
206	AMD_LINK_UP_EVENT	= BIT(5),
207	AMD_LINK_DOWN_EVENT	= BIT(6),
208	AMD_EVENT_INTMASK	= (AMD_PEER_FLUSH_EVENT |
209				AMD_PEER_RESET_EVENT | AMD_PEER_D3_EVENT |
210				AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT |
211				AMD_LINK_UP_EVENT | AMD_LINK_DOWN_EVENT),
212
213	AMD_PMESTAT_OFFSET	= 0x480,
214	AMD_PMSGTRIG_OFFSET	= 0x490,
215	AMD_LTRLATENCY_OFFSET	= 0x494,
216	AMD_FLUSHTRIG_OFFSET	= 0x498,
217
218	/* SMU register*/
219	AMD_SMUACK_OFFSET	= 0x4A0,
220	AMD_SINRST_OFFSET	= 0x4A4,
221	AMD_RSPNUM_OFFSET	= 0x4A8,
222	AMD_SMU_SPADMUTEX	= 0x4B0,
223	AMD_SMU_SPADOFFSET	= 0x4B4,
224
225	AMD_PEER_OFFSET		= 0x400,
226};
227
228struct amd_ntb_softc {
229	/* ntb.c context. Do not move! Must go first! */
230	void			*ntb_store;
231
232	device_t		device;
233	enum amd_ntb_conn_type	conn_type;
234
235	struct amd_ntb_pci_bar_info	bar_info[NTB_MAX_BARS];
236	struct amd_ntb_int_info	int_info[16];
237	struct amd_ntb_vec	*msix_vec;
238	uint16_t		allocated_interrupts;
239
240	struct callout		hb_timer;
241
242	struct amd_ntb_hw_info	*hw_info;
243	uint8_t			spad_count;
244	uint8_t			msix_vec_count;
245
246	struct mtx		db_mask_lock;
247
248	volatile uint32_t	ntb_ctl;
249	volatile uint32_t	lnk_sta;
250	volatile uint32_t	peer_sta;
251	volatile uint32_t	cntl_sta;
252
253	uint16_t		db_valid_mask;
254	uint16_t		db_mask;
255	uint32_t		int_mask;
256
257	unsigned int		self_spad;
258	unsigned int		peer_spad;
259};
260
261static void amd_init_side_info(struct amd_ntb_softc *ntb);
262static void amd_deinit_side_info(struct amd_ntb_softc *ntb);
263static int amd_ntb_detach(device_t device);
264
265#endif
266