forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
....@@ -1,25 +1,17 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Microsemi Switchtec(tm) PCIe Management Driver
34 * 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
- *
145 */
156
16
-#include <linux/switchtec.h>
17
-#include <linux/module.h>
7
+#include <linux/interrupt.h>
8
+#include <linux/io-64-nonatomic-lo-hi.h>
189 #include <linux/delay.h>
1910 #include <linux/kthread.h>
20
-#include <linux/interrupt.h>
11
+#include <linux/module.h>
2112 #include <linux/ntb.h>
2213 #include <linux/pci.h>
14
+#include <linux/switchtec.h>
2315
2416 MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver");
2517 MODULE_VERSION("0.1");
....@@ -35,35 +27,6 @@
3527 module_param(use_lut_mws, bool, 0644);
3628 MODULE_PARM_DESC(use_lut_mws,
3729 "Enable the use of the LUT based memory windows");
38
-
39
-#ifndef ioread64
40
-#ifdef readq
41
-#define ioread64 readq
42
-#else
43
-#define ioread64 _ioread64
44
-static inline u64 _ioread64(void __iomem *mmio)
45
-{
46
- u64 low, high;
47
-
48
- low = ioread32(mmio);
49
- high = ioread32(mmio + sizeof(u32));
50
- return low | (high << 32);
51
-}
52
-#endif
53
-#endif
54
-
55
-#ifndef iowrite64
56
-#ifdef writeq
57
-#define iowrite64 writeq
58
-#else
59
-#define iowrite64 _iowrite64
60
-static inline void _iowrite64(u64 val, void __iomem *mmio)
61
-{
62
- iowrite32(val, mmio);
63
- iowrite32(val >> 32, mmio + sizeof(u32));
64
-}
65
-#endif
66
-#endif
6730
6831 #define SWITCHTEC_NTB_MAGIC 0x45CC0001
6932 #define MAX_MWS 128
....@@ -123,7 +86,8 @@
12386 bool link_is_up;
12487 enum ntb_speed link_speed;
12588 enum ntb_width link_width;
126
- struct work_struct link_reinit_work;
89
+ struct work_struct check_link_status_work;
90
+ bool link_force_down;
12791 };
12892
12993 static struct switchtec_ntb *ntb_sndev(struct ntb_dev *ntb)
....@@ -264,6 +228,7 @@
264228 ctl_val &= ~NTB_CTRL_BAR_DIR_WIN_EN;
265229 iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
266230 iowrite32(0, &ctl->bar_entry[bar].win_size);
231
+ iowrite32(0, &ctl->bar_ext_entry[bar].win_size);
267232 iowrite64(sndev->self_partition, &ctl->bar_entry[bar].xlate_addr);
268233 }
269234
....@@ -286,7 +251,9 @@
286251 ctl_val |= NTB_CTRL_BAR_DIR_WIN_EN;
287252
288253 iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
289
- iowrite32(xlate_pos | size, &ctl->bar_entry[bar].win_size);
254
+ iowrite32(xlate_pos | (lower_32_bits(size) & 0xFFFFF000),
255
+ &ctl->bar_entry[bar].win_size);
256
+ iowrite32(upper_32_bits(size), &ctl->bar_ext_entry[bar].win_size);
290257 iowrite64(sndev->self_partition | addr,
291258 &ctl->bar_entry[bar].xlate_addr);
292259 }
....@@ -318,7 +285,7 @@
318285 if (widx >= switchtec_ntb_mw_count(ntb, pidx))
319286 return -EINVAL;
320287
321
- if (xlate_pos < 12)
288
+ if (size != 0 && xlate_pos < 12)
322289 return -EINVAL;
323290
324291 if (!IS_ALIGNED(addr, BIT_ULL(xlate_pos))) {
....@@ -339,7 +306,7 @@
339306 if (rc)
340307 return rc;
341308
342
- if (addr == 0 || size == 0) {
309
+ if (size == 0) {
343310 if (widx < nr_direct_mw)
344311 switchtec_ntb_mw_clr_direct(sndev, widx);
345312 else
....@@ -519,32 +486,10 @@
519486
520487 static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev);
521488
522
-static void link_reinit_work(struct work_struct *work)
523
-{
524
- struct switchtec_ntb *sndev;
525
-
526
- sndev = container_of(work, struct switchtec_ntb, link_reinit_work);
527
-
528
- switchtec_ntb_reinit_peer(sndev);
529
-}
530
-
531
-static void switchtec_ntb_check_link(struct switchtec_ntb *sndev,
532
- enum switchtec_msg msg)
489
+static void switchtec_ntb_link_status_update(struct switchtec_ntb *sndev)
533490 {
534491 int link_sta;
535492 int old = sndev->link_is_up;
536
-
537
- if (msg == MSG_LINK_FORCE_DOWN) {
538
- schedule_work(&sndev->link_reinit_work);
539
-
540
- if (sndev->link_is_up) {
541
- sndev->link_is_up = 0;
542
- ntb_link_event(&sndev->ntb);
543
- dev_info(&sndev->stdev->dev, "ntb link forced down\n");
544
- }
545
-
546
- return;
547
- }
548493
549494 link_sta = sndev->self_shared->link_sta;
550495 if (link_sta) {
....@@ -568,6 +513,38 @@
568513 if (link_sta)
569514 crosslink_init_dbmsgs(sndev);
570515 }
516
+}
517
+
518
+static void check_link_status_work(struct work_struct *work)
519
+{
520
+ struct switchtec_ntb *sndev;
521
+
522
+ sndev = container_of(work, struct switchtec_ntb,
523
+ check_link_status_work);
524
+
525
+ if (sndev->link_force_down) {
526
+ sndev->link_force_down = false;
527
+ switchtec_ntb_reinit_peer(sndev);
528
+
529
+ if (sndev->link_is_up) {
530
+ sndev->link_is_up = 0;
531
+ ntb_link_event(&sndev->ntb);
532
+ dev_info(&sndev->stdev->dev, "ntb link forced down\n");
533
+ }
534
+
535
+ return;
536
+ }
537
+
538
+ switchtec_ntb_link_status_update(sndev);
539
+}
540
+
541
+static void switchtec_ntb_check_link(struct switchtec_ntb *sndev,
542
+ enum switchtec_msg msg)
543
+{
544
+ if (msg == MSG_LINK_FORCE_DOWN)
545
+ sndev->link_force_down = true;
546
+
547
+ schedule_work(&sndev->check_link_status_work);
571548 }
572549
573550 static void switchtec_ntb_link_notification(struct switchtec_dev *stdev)
....@@ -602,7 +579,7 @@
602579 sndev->self_shared->link_sta = 1;
603580 switchtec_ntb_send_msg(sndev, LINK_MESSAGE, MSG_LINK_UP);
604581
605
- switchtec_ntb_check_link(sndev, MSG_CHECK_LINK);
582
+ switchtec_ntb_link_status_update(sndev);
606583
607584 return 0;
608585 }
....@@ -616,7 +593,7 @@
616593 sndev->self_shared->link_sta = 0;
617594 switchtec_ntb_send_msg(sndev, LINK_MESSAGE, MSG_LINK_DOWN);
618595
619
- switchtec_ntb_check_link(sndev, MSG_CHECK_LINK);
596
+ switchtec_ntb_link_status_update(sndev);
620597
621598 return 0;
622599 }
....@@ -707,10 +684,15 @@
707684
708685 static int switchtec_ntb_peer_db_addr(struct ntb_dev *ntb,
709686 phys_addr_t *db_addr,
710
- resource_size_t *db_size)
687
+ resource_size_t *db_size,
688
+ u64 *db_data,
689
+ int db_bit)
711690 {
712691 struct switchtec_ntb *sndev = ntb_sndev(ntb);
713692 unsigned long offset;
693
+
694
+ if (unlikely(db_bit >= BITS_PER_LONG_LONG))
695
+ return -EINVAL;
714696
715697 offset = (unsigned long)sndev->mmio_peer_dbmsg->odb -
716698 (unsigned long)sndev->stdev->mmio;
....@@ -721,6 +703,8 @@
721703 *db_addr = pci_resource_start(ntb->pdev, 0) + offset;
722704 if (db_size)
723705 *db_size = sizeof(u32);
706
+ if (db_data)
707
+ *db_data = BIT_ULL(db_bit) << sndev->db_peer_shift;
724708
725709 return 0;
726710 }
....@@ -862,7 +846,8 @@
862846 sndev->ntb.topo = NTB_TOPO_SWITCH;
863847 sndev->ntb.ops = &switchtec_ntb_ops;
864848
865
- INIT_WORK(&sndev->link_reinit_work, link_reinit_work);
849
+ INIT_WORK(&sndev->check_link_status_work, check_link_status_work);
850
+ sndev->link_force_down = false;
866851
867852 sndev->self_partition = sndev->stdev->partition;
868853
....@@ -1053,7 +1038,9 @@
10531038 ctl_val |= NTB_CTRL_BAR_DIR_WIN_EN;
10541039
10551040 iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
1056
- iowrite32(xlate_pos | size, &ctl->bar_entry[bar].win_size);
1041
+ iowrite32(xlate_pos | (lower_32_bits(size) & 0xFFFFF000),
1042
+ &ctl->bar_entry[bar].win_size);
1043
+ iowrite32(upper_32_bits(size), &ctl->bar_ext_entry[bar].win_size);
10571044 iowrite64(sndev->peer_partition | addr,
10581045 &ctl->bar_entry[bar].xlate_addr);
10591046 }
....@@ -1339,10 +1326,10 @@
13391326 int rc;
13401327
13411328 sndev->nr_rsvd_luts++;
1342
- sndev->self_shared = dma_zalloc_coherent(&sndev->stdev->pdev->dev,
1343
- LUT_SIZE,
1344
- &sndev->self_shared_dma,
1345
- GFP_KERNEL);
1329
+ sndev->self_shared = dma_alloc_coherent(&sndev->stdev->pdev->dev,
1330
+ LUT_SIZE,
1331
+ &sndev->self_shared_dma,
1332
+ GFP_KERNEL);
13461333 if (!sndev->self_shared) {
13471334 dev_err(&sndev->stdev->dev,
13481335 "unable to allocate memory for shared mw\n");
....@@ -1473,10 +1460,16 @@
14731460
14741461 static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev)
14751462 {
1476
- dev_info(&sndev->stdev->dev, "peer reinitialized\n");
1477
- switchtec_ntb_deinit_shared_mw(sndev);
1478
- switchtec_ntb_init_mw(sndev);
1479
- return switchtec_ntb_init_shared_mw(sndev);
1463
+ int rc;
1464
+
1465
+ if (crosslink_is_enabled(sndev))
1466
+ return 0;
1467
+
1468
+ dev_info(&sndev->stdev->dev, "reinitialize shared memory window\n");
1469
+ rc = config_rsvd_lut_win(sndev, sndev->mmio_peer_ctrl, 0,
1470
+ sndev->self_partition,
1471
+ sndev->self_shared_dma);
1472
+ return rc;
14801473 }
14811474
14821475 static int switchtec_ntb_add(struct device *dev,