hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/can/rockchip/rockchip_canfd.c
....@@ -27,6 +27,7 @@
2727 #include <linux/can/led.h>
2828 #include <linux/reset.h>
2929 #include <linux/pm_runtime.h>
30
+#include <linux/rockchip/cpu.h>
3031
3132 /* registers definition */
3233 enum rockchip_canfd_reg {
....@@ -105,6 +106,7 @@
105106 ROCKCHIP_CANFD_MODE = 0,
106107 ROCKCHIP_CAN_MODE,
107108 ROCKCHIP_RK3568_CAN_MODE,
109
+ ROCKCHIP_RK3568_CAN_MODE_V2,
108110 };
109111
110112 #define DATE_LENGTH_12_BYTE (0x9)
....@@ -212,6 +214,8 @@
212214 #define CAN_RXFRD_OFFSET(n) (CAN_RXFRD + CAN_RF_SIZE * (n))
213215
214216 #define CAN_RX_FILTER_MASK 0x1fffffff
217
+#define NOACK_ERR_FLAG 0xc200800
218
+#define CAN_BUSOFF_FLAG 0x20
215219
216220 #define DRV_NAME "rockchip_canfd"
217221
....@@ -220,6 +224,7 @@
220224 struct rockchip_canfd {
221225 struct can_priv can;
222226 struct device *dev;
227
+ struct napi_struct napi;
223228 struct clk_bulk_data *clks;
224229 int num_clks;
225230 struct reset_control *reset;
....@@ -231,6 +236,7 @@
231236 bool txtorx;
232237 u32 tx_invalid[4];
233238 struct delayed_work tx_err_work;
239
+ u32 delay_time_ms;
234240 };
235241
236242 static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv,
....@@ -292,8 +298,6 @@
292298
293299 val = rockchip_canfd_read(rcan, CAN_MODE);
294300 val |= WORK_MODE;
295
- if (rcan->mode >= ROCKCHIP_CAN_MODE && rcan->txtorx)
296
- val |= MODE_RXSTX;
297301 rockchip_canfd_write(rcan, CAN_MODE, val);
298302
299303 netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,
....@@ -356,6 +360,12 @@
356360
357361 rockchip_canfd_write(rcan, CAN_DBTP, reg_btp);
358362 }
363
+ if (bt->bitrate > 200000)
364
+ rcan->delay_time_ms = 1;
365
+ else if (bt->bitrate > 50000)
366
+ rcan->delay_time_ms = 5;
367
+ else
368
+ rcan->delay_time_ms = 20;
359369
360370 netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__,
361371 rockchip_canfd_read(rcan, CAN_NBTP),
....@@ -427,7 +437,9 @@
427437 if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
428438 val |= MODE_SELF_TEST | MODE_LBACK;
429439
430
- val |= MODE_AUTO_RETX;
440
+ /* Listen-only mode */
441
+ if (rcan->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
442
+ val |= MODE_SILENT;
431443
432444 rockchip_canfd_write(rcan, CAN_MODE, val);
433445
....@@ -488,18 +500,26 @@
488500 {
489501 struct rockchip_canfd *rcan =
490502 container_of(work, struct rockchip_canfd, tx_err_work.work);
491
- u32 mode, err_code, id;
503
+ u32 mode, err_code;
492504
493
- id = rockchip_canfd_read(rcan, CAN_TXID);
505
+ mode = rockchip_canfd_read(rcan, CAN_MODE);
494506 err_code = rockchip_canfd_read(rcan, CAN_ERR_CODE);
495
- if (err_code & 0x1fe0000) {
496
- mode = rockchip_canfd_read(rcan, CAN_MODE);
507
+ if ((err_code & NOACK_ERR_FLAG) == NOACK_ERR_FLAG) {
508
+ rockchip_canfd_write(rcan, CAN_MODE,
509
+ rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX);
510
+ rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
511
+ rockchip_canfd_write(rcan, CAN_MODE,
512
+ rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX));
513
+ schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms));
514
+ } else {
497515 rockchip_canfd_write(rcan, CAN_MODE, 0);
498516 rockchip_canfd_write(rcan, CAN_MODE, mode);
517
+ rockchip_canfd_write(rcan, CAN_MODE,
518
+ rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX);
499519 rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
500
- schedule_delayed_work(&rcan->tx_err_work, 1);
501
- } else if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && id & CAN_EFF_FLAG) {
502
- schedule_delayed_work(&rcan->tx_err_work, 1);
520
+ rockchip_canfd_write(rcan, CAN_MODE,
521
+ rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX));
522
+ schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms));
503523 }
504524 }
505525
....@@ -552,7 +572,14 @@
552572 dlc |= TX_FD_BRS_ENABLE;
553573 }
554574
555
- if (!rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG) {
575
+ if (rcan->txtorx && rcan->mode <= ROCKCHIP_RK3568_CAN_MODE && cf->can_id & CAN_EFF_FLAG)
576
+ rockchip_canfd_write(rcan, CAN_MODE,
577
+ rockchip_canfd_read(rcan, CAN_MODE) | MODE_RXSTX);
578
+ else
579
+ rockchip_canfd_write(rcan, CAN_MODE,
580
+ rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_RXSTX));
581
+
582
+ if (!rcan->txtorx && rcan->mode <= ROCKCHIP_RK3568_CAN_MODE && cf->can_id & CAN_EFF_FLAG) {
556583 /* Two frames are sent consecutively.
557584 * Before the first frame is tx finished,
558585 * the register of the second frame is configured.
....@@ -569,10 +596,9 @@
569596 for (i = 0; i < cf->len; i += 4)
570597 rockchip_canfd_write(rcan, CAN_TXDAT0 + i,
571598 *(u32 *)(cf->data + i));
599
+ can_put_echo_skb(skb, ndev, 0);
572600 rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
573601 local_irq_restore(flags);
574
- can_put_echo_skb(skb, ndev, 0);
575
-
576602 return NETDEV_TX_OK;
577603 }
578604
....@@ -583,13 +609,13 @@
583609 rockchip_canfd_write(rcan, CAN_TXDAT0 + i,
584610 *(u32 *)(cf->data + i));
585611
586
- rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
587
-
588
- if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG)
589
- schedule_delayed_work(&rcan->tx_err_work, 1);
590
-
591612 can_put_echo_skb(skb, ndev, 0);
592
-
613
+ rockchip_canfd_write(rcan, CAN_MODE,
614
+ rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX);
615
+ rockchip_canfd_write(rcan, CAN_CMD, cmd);
616
+ rockchip_canfd_write(rcan, CAN_MODE,
617
+ rockchip_canfd_read(rcan, CAN_MODE) & (~MODE_SPACE_RX));
618
+ schedule_delayed_work(&rcan->tx_err_work, msecs_to_jiffies(rcan->delay_time_ms));
593619 return NETDEV_TX_OK;
594620 }
595621
....@@ -602,15 +628,15 @@
602628 u32 id_rockchip_canfd, dlc;
603629 int i = 0;
604630 u32 __maybe_unused ts, ret;
605
- u32 data[16] = {0};
631
+ u32 data[16];
606632
607633 dlc = rockchip_canfd_read(rcan, CAN_RXFRD);
608634 id_rockchip_canfd = rockchip_canfd_read(rcan, CAN_RXFRD);
609635 ts = rockchip_canfd_read(rcan, CAN_RXFRD);
610
- for (i = 0; i < 16; i++)
636
+ for (i = 0; i < ARRAY_SIZE(data); i++)
611637 data[i] = rockchip_canfd_read(rcan, CAN_RXFRD);
612638
613
- if (rcan->mode >= ROCKCHIP_CAN_MODE) {
639
+ if (rcan->mode <= ROCKCHIP_RK3568_CAN_MODE) {
614640 /* may be an empty frame */
615641 if (!dlc && !id_rockchip_canfd)
616642 return 1;
....@@ -618,11 +644,10 @@
618644 if (rcan->txtorx) {
619645 if (rockchip_canfd_read(rcan, CAN_TX_CHECK_FIC) & FORMAT_MASK) {
620646 ret = rockchip_canfd_read(rcan, CAN_TXID) & CAN_SFF_MASK;
621
- if (id_rockchip_canfd == ret) {
647
+ if ((id_rockchip_canfd == ret) && !(dlc & FORMAT_MASK))
622648 rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC,
623649 ts | CAN_TX0_REQ);
624
- return 1;
625
- }
650
+ return 1;
626651 }
627652 }
628653 }
....@@ -675,6 +700,53 @@
675700 return 1;
676701 }
677702
703
+static int rockchip_canfd_get_rx_fifo_cnt(struct net_device *ndev)
704
+{
705
+ struct rockchip_canfd *rcan = netdev_priv(ndev);
706
+ int quota = 0;
707
+
708
+ if (read_poll_timeout_atomic(rockchip_canfd_read, quota,
709
+ (quota & rcan->rx_fifo_mask) >> rcan->rx_fifo_shift,
710
+ 0, 500000, false, rcan, CAN_RXFC))
711
+ netdev_dbg(ndev, "Warning: get fifo cnt failed\n");
712
+
713
+ quota = (quota & rcan->rx_fifo_mask) >> rcan->rx_fifo_shift;
714
+
715
+ return quota;
716
+}
717
+
718
+/* rockchip_canfd_rx_poll - Poll routine for rx packets (NAPI)
719
+ * @napi: napi structure pointer
720
+ * @quota: Max number of rx packets to be processed.
721
+ *
722
+ * This is the poll routine for rx part.
723
+ * It will process the packets maximux quota value.
724
+ *
725
+ * Return: number of packets received
726
+ */
727
+static int rockchip_canfd_rx_poll(struct napi_struct *napi, int quota)
728
+{
729
+ struct net_device *ndev = napi->dev;
730
+ struct rockchip_canfd *rcan = netdev_priv(ndev);
731
+ int work_done = 0;
732
+
733
+ quota = rockchip_canfd_get_rx_fifo_cnt(ndev);
734
+ if (quota) {
735
+ while (work_done < quota)
736
+ work_done += rockchip_canfd_rx(ndev);
737
+ }
738
+
739
+ if (work_done)
740
+ can_led_event(ndev, CAN_LED_EVENT_RX);
741
+
742
+ if (work_done < 6) {
743
+ napi_complete_done(napi, work_done);
744
+ rockchip_canfd_write(rcan, CAN_INT_MASK, 0);
745
+ }
746
+
747
+ return work_done;
748
+}
749
+
678750 static int rockchip_canfd_err(struct net_device *ndev, u32 isr)
679751 {
680752 struct rockchip_canfd *rcan = netdev_priv(ndev);
....@@ -724,8 +796,14 @@
724796 }
725797
726798 if (rcan->can.state >= CAN_STATE_BUS_OFF ||
727
- ((sta_reg & 0x20) == 0x20))
728
- can_bus_off(ndev);
799
+ ((sta_reg & CAN_BUSOFF_FLAG) == CAN_BUSOFF_FLAG)) {
800
+ cancel_delayed_work(&rcan->tx_err_work);
801
+ netif_stop_queue(ndev);
802
+ rockchip_canfd_stop(ndev);
803
+ can_free_echo_skb(ndev, 0);
804
+ rockchip_canfd_start(ndev);
805
+ netif_start_queue(ndev);
806
+ }
729807
730808 stats->rx_packets++;
731809 stats->rx_bytes += cf->can_dlc;
....@@ -740,13 +818,14 @@
740818 struct rockchip_canfd *rcan = netdev_priv(ndev);
741819 struct net_device_stats *stats = &ndev->stats;
742820 u32 err_int = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT |
743
- TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT;
821
+ BUS_ERR_INT | BUS_OFF_INT;
744822 u32 isr;
745823 u32 dlc = 0;
746824 u32 quota, work_done = 0;
747825
748826 isr = rockchip_canfd_read(rcan, CAN_INT);
749827 if (isr & TX_FINISH_INT) {
828
+ cancel_delayed_work(&rcan->tx_err_work);
750829 dlc = rockchip_canfd_read(rcan, CAN_TXFIC);
751830 /* transmission complete interrupt */
752831 if (dlc & FDF_MASK)
....@@ -754,12 +833,9 @@
754833 else
755834 stats->tx_bytes += (dlc & DLC_MASK);
756835 stats->tx_packets++;
757
- if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && dlc & FORMAT_MASK) {
758
- cancel_delayed_work(&rcan->tx_err_work);
836
+ if (rcan->txtorx && rcan->mode <= ROCKCHIP_RK3568_CAN_MODE && dlc & FORMAT_MASK) {
759837 rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, FORMAT_MASK);
760
- quota = (rockchip_canfd_read(rcan, CAN_RXFC) &
761
- rcan->rx_fifo_mask) >>
762
- rcan->rx_fifo_shift;
838
+ quota = rockchip_canfd_get_rx_fifo_cnt(ndev);
763839 if (quota) {
764840 while (work_done < quota)
765841 work_done += rockchip_canfd_rx(ndev);
....@@ -768,6 +844,10 @@
768844 rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
769845 rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, 0);
770846 }
847
+ if (read_poll_timeout_atomic(rockchip_canfd_read, quota,
848
+ !(quota & 0x3),
849
+ 0, 5000000, false, rcan, CAN_CMD))
850
+ netdev_err(ndev, "Warning: wait tx req timeout!\n");
771851 rockchip_canfd_write(rcan, CAN_CMD, 0);
772852 can_get_echo_skb(ndev, 0);
773853 netif_wake_queue(ndev);
....@@ -775,11 +855,18 @@
775855 }
776856
777857 if (isr & RX_FINISH_INT) {
778
- quota = (rockchip_canfd_read(rcan, CAN_RXFC) & rcan->rx_fifo_mask) >>
779
- rcan->rx_fifo_shift;
780
- if (quota) {
781
- while (work_done < quota)
782
- work_done += rockchip_canfd_rx(ndev);
858
+ if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2) {
859
+ rockchip_canfd_write(rcan, CAN_INT_MASK, 0x1);
860
+ napi_schedule(&rcan->napi);
861
+ } else {
862
+ work_done = 0;
863
+ quota = (rockchip_canfd_read(rcan, CAN_RXFC) &
864
+ rcan->rx_fifo_mask) >>
865
+ rcan->rx_fifo_shift;
866
+ if (quota) {
867
+ while (work_done < quota)
868
+ work_done += rockchip_canfd_rx(ndev);
869
+ }
783870 }
784871 }
785872
....@@ -817,6 +904,8 @@
817904 }
818905
819906 can_led_event(ndev, CAN_LED_EVENT_OPEN);
907
+ if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
908
+ napi_enable(&rcan->napi);
820909 netif_start_queue(ndev);
821910
822911 netdev_dbg(ndev, "%s\n", __func__);
....@@ -834,6 +923,8 @@
834923 struct rockchip_canfd *rcan = netdev_priv(ndev);
835924
836925 netif_stop_queue(ndev);
926
+ if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
927
+ napi_disable(&rcan->napi);
837928 rockchip_canfd_stop(ndev);
838929 close_candev(ndev);
839930 can_led_event(ndev, CAN_LED_EVENT_STOP);
....@@ -1011,6 +1102,9 @@
10111102
10121103 rcan->mode = (unsigned long)of_device_get_match_data(&pdev->dev);
10131104
1105
+ if ((cpu_is_rk3566() || cpu_is_rk3568()) && (rockchip_get_cpu_version() == 3))
1106
+ rcan->mode = ROCKCHIP_RK3568_CAN_MODE_V2;
1107
+
10141108 rcan->base = addr;
10151109 rcan->can.clock.freq = clk_get_rate(rcan->clks[0].clk);
10161110 rcan->dev = &pdev->dev;
....@@ -1032,6 +1126,7 @@
10321126 break;
10331127 case ROCKCHIP_CAN_MODE:
10341128 case ROCKCHIP_RK3568_CAN_MODE:
1129
+ case ROCKCHIP_RK3568_CAN_MODE_V2:
10351130 rcan->can.bittiming_const = &rockchip_canfd_bittiming_const;
10361131 rcan->can.do_set_mode = rockchip_canfd_set_mode;
10371132 rcan->can.do_get_berr_counter = rockchip_canfd_get_berr_counter;
....@@ -1056,10 +1151,17 @@
10561151 rcan->tx_invalid, 4))
10571152 rcan->txtorx = 1;
10581153
1154
+ if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2) {
1155
+ rcan->txtorx = 0;
1156
+ netif_napi_add(ndev, &rcan->napi, rockchip_canfd_rx_poll, 6);
1157
+ }
1158
+
10591159 ndev->netdev_ops = &rockchip_canfd_netdev_ops;
10601160 ndev->irq = irq;
10611161 ndev->flags |= IFF_ECHO;
10621162 rcan->can.restart_ms = 1;
1163
+
1164
+ irq_set_affinity_hint(irq, get_cpu_mask(num_online_cpus() - 1));
10631165
10641166 INIT_DELAYED_WORK(&rcan->tx_err_work, rockchip_canfd_tx_err_delay_work);
10651167
....@@ -1097,9 +1199,12 @@
10971199 static int rockchip_canfd_remove(struct platform_device *pdev)
10981200 {
10991201 struct net_device *ndev = platform_get_drvdata(pdev);
1202
+ struct rockchip_canfd *rcan = netdev_priv(ndev);
11001203
11011204 unregister_netdev(ndev);
11021205 pm_runtime_disable(&pdev->dev);
1206
+ if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
1207
+ netif_napi_del(&rcan->napi);
11031208 free_candev(ndev);
11041209
11051210 return 0;
....@@ -1117,4 +1222,5 @@
11171222 module_platform_driver(rockchip_canfd_driver);
11181223
11191224 MODULE_AUTHOR("Elaine Zhang <zhangqing@rock-chips.com>");
1225
+MODULE_LICENSE("GPL");
11201226 MODULE_DESCRIPTION("Rockchip CANFD Drivers");