xref: /linux/drivers/ntb/hw/mscc/ntb_hw_switchtec.c (revision ec0467ccbdeb69a86c8729073057bda7bce00eec)
1 /*
2  * Microsemi Switchtec(tm) PCIe Management Driver
3  * Copyright (c) 2017, Microsemi Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  */
15 
16 #include <linux/switchtec.h>
17 #include <linux/module.h>
18 #include <linux/delay.h>
19 #include <linux/kthread.h>
20 
21 MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver");
22 MODULE_VERSION("0.1");
23 MODULE_LICENSE("GPL");
24 MODULE_AUTHOR("Microsemi Corporation");
25 
26 static bool use_lut_mws;
27 module_param(use_lut_mws, bool, 0644);
28 MODULE_PARM_DESC(use_lut_mws,
29 		 "Enable the use of the LUT based memory windows");
30 
31 #ifndef ioread64
32 #ifdef readq
33 #define ioread64 readq
34 #else
35 #define ioread64 _ioread64
36 static inline u64 _ioread64(void __iomem *mmio)
37 {
38 	u64 low, high;
39 
40 	low = ioread32(mmio);
41 	high = ioread32(mmio + sizeof(u32));
42 	return low | (high << 32);
43 }
44 #endif
45 #endif
46 
47 #ifndef iowrite64
48 #ifdef writeq
49 #define iowrite64 writeq
50 #else
51 #define iowrite64 _iowrite64
52 static inline void _iowrite64(u64 val, void __iomem *mmio)
53 {
54 	iowrite32(val, mmio);
55 	iowrite32(val >> 32, mmio + sizeof(u32));
56 }
57 #endif
58 #endif
59 
60 #define SWITCHTEC_NTB_MAGIC 0x45CC0001
61 #define MAX_MWS     128
62 
63 struct shared_mw {
64 	u32 magic;
65 	u32 partition_id;
66 	u64 mw_sizes[MAX_MWS];
67 };
68 
69 #define MAX_DIRECT_MW ARRAY_SIZE(((struct ntb_ctrl_regs *)(0))->bar_entry)
70 #define LUT_SIZE SZ_64K
71 
72 struct switchtec_ntb {
73 	struct switchtec_dev *stdev;
74 
75 	int self_partition;
76 	int peer_partition;
77 
78 	struct ntb_info_regs __iomem *mmio_ntb;
79 	struct ntb_ctrl_regs __iomem *mmio_ctrl;
80 	struct ntb_dbmsg_regs __iomem *mmio_dbmsg;
81 	struct ntb_ctrl_regs __iomem *mmio_self_ctrl;
82 	struct ntb_ctrl_regs __iomem *mmio_peer_ctrl;
83 	struct ntb_dbmsg_regs __iomem *mmio_self_dbmsg;
84 
85 	struct shared_mw *self_shared;
86 	struct shared_mw __iomem *peer_shared;
87 	dma_addr_t self_shared_dma;
88 
89 	int nr_direct_mw;
90 	int nr_lut_mw;
91 	int direct_mw_to_bar[MAX_DIRECT_MW];
92 
93 	int peer_nr_direct_mw;
94 	int peer_nr_lut_mw;
95 	int peer_direct_mw_to_bar[MAX_DIRECT_MW];
96 };
97 
98 static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
99 				 struct ntb_ctrl_regs __iomem *ctl,
100 				 u32 op, int wait_status)
101 {
102 	static const char * const op_text[] = {
103 		[NTB_CTRL_PART_OP_LOCK] = "lock",
104 		[NTB_CTRL_PART_OP_CFG] = "configure",
105 		[NTB_CTRL_PART_OP_RESET] = "reset",
106 	};
107 
108 	int i;
109 	u32 ps;
110 	int status;
111 
112 	switch (op) {
113 	case NTB_CTRL_PART_OP_LOCK:
114 		status = NTB_CTRL_PART_STATUS_LOCKING;
115 		break;
116 	case NTB_CTRL_PART_OP_CFG:
117 		status = NTB_CTRL_PART_STATUS_CONFIGURING;
118 		break;
119 	case NTB_CTRL_PART_OP_RESET:
120 		status = NTB_CTRL_PART_STATUS_RESETTING;
121 		break;
122 	default:
123 		return -EINVAL;
124 	}
125 
126 	iowrite32(op, &ctl->partition_op);
127 
128 	for (i = 0; i < 1000; i++) {
129 		if (msleep_interruptible(50) != 0) {
130 			iowrite32(NTB_CTRL_PART_OP_RESET, &ctl->partition_op);
131 			return -EINTR;
132 		}
133 
134 		ps = ioread32(&ctl->partition_status) & 0xFFFF;
135 
136 		if (ps != status)
137 			break;
138 	}
139 
140 	if (ps == wait_status)
141 		return 0;
142 
143 	if (ps == status) {
144 		dev_err(&sndev->stdev->dev,
145 			"Timed out while peforming %s (%d). (%08x)",
146 			op_text[op], op,
147 			ioread32(&ctl->partition_status));
148 
149 		return -ETIMEDOUT;
150 	}
151 
152 	return -EIO;
153 }
154 
155 static void switchtec_ntb_init_sndev(struct switchtec_ntb *sndev)
156 {
157 	u64 part_map;
158 
159 	sndev->self_partition = sndev->stdev->partition;
160 
161 	sndev->mmio_ntb = sndev->stdev->mmio_ntb;
162 	part_map = ioread64(&sndev->mmio_ntb->ep_map);
163 	part_map &= ~(1 << sndev->self_partition);
164 	sndev->peer_partition = ffs(part_map) - 1;
165 
166 	dev_dbg(&sndev->stdev->dev, "Partition ID %d of %d (%llx)",
167 		sndev->self_partition, sndev->stdev->partition_count,
168 		part_map);
169 
170 	sndev->mmio_ctrl = (void * __iomem)sndev->mmio_ntb +
171 		SWITCHTEC_NTB_REG_CTRL_OFFSET;
172 	sndev->mmio_dbmsg = (void * __iomem)sndev->mmio_ntb +
173 		SWITCHTEC_NTB_REG_DBMSG_OFFSET;
174 
175 	sndev->mmio_self_ctrl = &sndev->mmio_ctrl[sndev->self_partition];
176 	sndev->mmio_peer_ctrl = &sndev->mmio_ctrl[sndev->peer_partition];
177 	sndev->mmio_self_dbmsg = &sndev->mmio_dbmsg[sndev->self_partition];
178 }
179 
180 static int map_bars(int *map, struct ntb_ctrl_regs __iomem *ctrl)
181 {
182 	int i;
183 	int cnt = 0;
184 
185 	for (i = 0; i < ARRAY_SIZE(ctrl->bar_entry); i++) {
186 		u32 r = ioread32(&ctrl->bar_entry[i].ctl);
187 
188 		if (r & NTB_CTRL_BAR_VALID)
189 			map[cnt++] = i;
190 	}
191 
192 	return cnt;
193 }
194 
195 static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev)
196 {
197 	sndev->nr_direct_mw = map_bars(sndev->direct_mw_to_bar,
198 				       sndev->mmio_self_ctrl);
199 
200 	sndev->nr_lut_mw = ioread16(&sndev->mmio_self_ctrl->lut_table_entries);
201 	sndev->nr_lut_mw = rounddown_pow_of_two(sndev->nr_lut_mw);
202 
203 	dev_dbg(&sndev->stdev->dev, "MWs: %d direct, %d lut",
204 		sndev->nr_direct_mw, sndev->nr_lut_mw);
205 
206 	sndev->peer_nr_direct_mw = map_bars(sndev->peer_direct_mw_to_bar,
207 					    sndev->mmio_peer_ctrl);
208 
209 	sndev->peer_nr_lut_mw =
210 		ioread16(&sndev->mmio_peer_ctrl->lut_table_entries);
211 	sndev->peer_nr_lut_mw = rounddown_pow_of_two(sndev->peer_nr_lut_mw);
212 
213 	dev_dbg(&sndev->stdev->dev, "Peer MWs: %d direct, %d lut",
214 		sndev->peer_nr_direct_mw, sndev->peer_nr_lut_mw);
215 
216 }
217 
218 static int switchtec_ntb_init_req_id_table(struct switchtec_ntb *sndev)
219 {
220 	int rc = 0;
221 	u16 req_id;
222 	u32 error;
223 
224 	req_id = ioread16(&sndev->mmio_ntb->requester_id);
225 
226 	if (ioread32(&sndev->mmio_self_ctrl->req_id_table_size) < 2) {
227 		dev_err(&sndev->stdev->dev,
228 			"Not enough requester IDs available.");
229 		return -EFAULT;
230 	}
231 
232 	rc = switchtec_ntb_part_op(sndev, sndev->mmio_self_ctrl,
233 				   NTB_CTRL_PART_OP_LOCK,
234 				   NTB_CTRL_PART_STATUS_LOCKED);
235 	if (rc)
236 		return rc;
237 
238 	iowrite32(NTB_PART_CTRL_ID_PROT_DIS,
239 		  &sndev->mmio_self_ctrl->partition_ctrl);
240 
241 	/*
242 	 * Root Complex Requester ID (which is 0:00.0)
243 	 */
244 	iowrite32(0 << 16 | NTB_CTRL_REQ_ID_EN,
245 		  &sndev->mmio_self_ctrl->req_id_table[0]);
246 
247 	/*
248 	 * Host Bridge Requester ID (as read from the mmap address)
249 	 */
250 	iowrite32(req_id << 16 | NTB_CTRL_REQ_ID_EN,
251 		  &sndev->mmio_self_ctrl->req_id_table[1]);
252 
253 	rc = switchtec_ntb_part_op(sndev, sndev->mmio_self_ctrl,
254 				   NTB_CTRL_PART_OP_CFG,
255 				   NTB_CTRL_PART_STATUS_NORMAL);
256 	if (rc == -EIO) {
257 		error = ioread32(&sndev->mmio_self_ctrl->req_id_error);
258 		dev_err(&sndev->stdev->dev,
259 			"Error setting up the requester ID table: %08x",
260 			error);
261 	}
262 
263 	return rc;
264 }
265 
266 static void switchtec_ntb_init_shared(struct switchtec_ntb *sndev)
267 {
268 	int i;
269 
270 	memset(sndev->self_shared, 0, LUT_SIZE);
271 	sndev->self_shared->magic = SWITCHTEC_NTB_MAGIC;
272 	sndev->self_shared->partition_id = sndev->stdev->partition;
273 
274 	for (i = 0; i < sndev->nr_direct_mw; i++) {
275 		int bar = sndev->direct_mw_to_bar[i];
276 		resource_size_t sz = pci_resource_len(sndev->stdev->pdev, bar);
277 
278 		if (i == 0)
279 			sz = min_t(resource_size_t, sz,
280 				   LUT_SIZE * sndev->nr_lut_mw);
281 
282 		sndev->self_shared->mw_sizes[i] = sz;
283 	}
284 
285 	for (i = 0; i < sndev->nr_lut_mw; i++) {
286 		int idx = sndev->nr_direct_mw + i;
287 
288 		sndev->self_shared->mw_sizes[idx] = LUT_SIZE;
289 	}
290 }
291 
292 static int switchtec_ntb_init_shared_mw(struct switchtec_ntb *sndev)
293 {
294 	struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
295 	int bar = sndev->direct_mw_to_bar[0];
296 	u32 ctl_val;
297 	int rc;
298 
299 	sndev->self_shared = dma_zalloc_coherent(&sndev->stdev->pdev->dev,
300 						 LUT_SIZE,
301 						 &sndev->self_shared_dma,
302 						 GFP_KERNEL);
303 	if (!sndev->self_shared) {
304 		dev_err(&sndev->stdev->dev,
305 			"unable to allocate memory for shared mw");
306 		return -ENOMEM;
307 	}
308 
309 	switchtec_ntb_init_shared(sndev);
310 
311 	rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_LOCK,
312 				   NTB_CTRL_PART_STATUS_LOCKED);
313 	if (rc)
314 		goto unalloc_and_exit;
315 
316 	ctl_val = ioread32(&ctl->bar_entry[bar].ctl);
317 	ctl_val &= 0xFF;
318 	ctl_val |= NTB_CTRL_BAR_LUT_WIN_EN;
319 	ctl_val |= ilog2(LUT_SIZE) << 8;
320 	ctl_val |= (sndev->nr_lut_mw - 1) << 14;
321 	iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
322 
323 	iowrite64((NTB_CTRL_LUT_EN | (sndev->self_partition << 1) |
324 		   sndev->self_shared_dma),
325 		  &ctl->lut_entry[0]);
326 
327 	rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_CFG,
328 				   NTB_CTRL_PART_STATUS_NORMAL);
329 	if (rc) {
330 		u32 bar_error, lut_error;
331 
332 		bar_error = ioread32(&ctl->bar_error);
333 		lut_error = ioread32(&ctl->lut_error);
334 		dev_err(&sndev->stdev->dev,
335 			"Error setting up shared MW: %08x / %08x",
336 			bar_error, lut_error);
337 		goto unalloc_and_exit;
338 	}
339 
340 	sndev->peer_shared = pci_iomap(sndev->stdev->pdev, bar, LUT_SIZE);
341 	if (!sndev->peer_shared) {
342 		rc = -ENOMEM;
343 		goto unalloc_and_exit;
344 	}
345 
346 	dev_dbg(&sndev->stdev->dev, "Shared MW Ready");
347 	return 0;
348 
349 unalloc_and_exit:
350 	dma_free_coherent(&sndev->stdev->pdev->dev, LUT_SIZE,
351 			  sndev->self_shared, sndev->self_shared_dma);
352 
353 	return rc;
354 }
355 
356 static void switchtec_ntb_deinit_shared_mw(struct switchtec_ntb *sndev)
357 {
358 	if (sndev->peer_shared)
359 		pci_iounmap(sndev->stdev->pdev, sndev->peer_shared);
360 
361 	if (sndev->self_shared)
362 		dma_free_coherent(&sndev->stdev->pdev->dev, LUT_SIZE,
363 				  sndev->self_shared,
364 				  sndev->self_shared_dma);
365 }
366 
367 static int switchtec_ntb_add(struct device *dev,
368 			     struct class_interface *class_intf)
369 {
370 	struct switchtec_dev *stdev = to_stdev(dev);
371 	struct switchtec_ntb *sndev;
372 	int rc;
373 
374 	stdev->sndev = NULL;
375 
376 	if (stdev->pdev->class != MICROSEMI_NTB_CLASSCODE)
377 		return -ENODEV;
378 
379 	if (stdev->partition_count != 2)
380 		dev_warn(dev, "ntb driver only supports 2 partitions");
381 
382 	sndev = kzalloc_node(sizeof(*sndev), GFP_KERNEL, dev_to_node(dev));
383 	if (!sndev)
384 		return -ENOMEM;
385 
386 	sndev->stdev = stdev;
387 
388 	switchtec_ntb_init_sndev(sndev);
389 	switchtec_ntb_init_mw(sndev);
390 
391 	rc = switchtec_ntb_init_req_id_table(sndev);
392 	if (rc)
393 		goto free_and_exit;
394 
395 	rc = switchtec_ntb_init_shared_mw(sndev);
396 	if (rc)
397 		goto free_and_exit;
398 
399 	stdev->sndev = sndev;
400 	dev_info(dev, "NTB device registered");
401 
402 	return 0;
403 
404 free_and_exit:
405 	kfree(sndev);
406 	dev_err(dev, "failed to register ntb device: %d", rc);
407 	return rc;
408 }
409 
410 void switchtec_ntb_remove(struct device *dev,
411 			  struct class_interface *class_intf)
412 {
413 	struct switchtec_dev *stdev = to_stdev(dev);
414 	struct switchtec_ntb *sndev = stdev->sndev;
415 
416 	if (!sndev)
417 		return;
418 
419 	stdev->sndev = NULL;
420 	switchtec_ntb_deinit_shared_mw(sndev);
421 	kfree(sndev);
422 	dev_info(dev, "ntb device unregistered");
423 }
424 
425 static struct class_interface switchtec_interface  = {
426 	.add_dev = switchtec_ntb_add,
427 	.remove_dev = switchtec_ntb_remove,
428 };
429 
430 static int __init switchtec_ntb_init(void)
431 {
432 	switchtec_interface.class = switchtec_class;
433 	return class_interface_register(&switchtec_interface);
434 }
435 module_init(switchtec_ntb_init);
436 
437 static void __exit switchtec_ntb_exit(void)
438 {
439 	class_interface_unregister(&switchtec_interface);
440 }
441 module_exit(switchtec_ntb_exit);
442