| .. | .. |
|---|
| 27 | 27 | #include <linux/can/led.h> |
|---|
| 28 | 28 | #include <linux/reset.h> |
|---|
| 29 | 29 | #include <linux/pm_runtime.h> |
|---|
| 30 | +#include <linux/rockchip/cpu.h> |
|---|
| 30 | 31 | |
|---|
| 31 | 32 | /* registers definition */ |
|---|
| 32 | 33 | enum rockchip_canfd_reg { |
|---|
| .. | .. |
|---|
| 105 | 106 | ROCKCHIP_CANFD_MODE = 0, |
|---|
| 106 | 107 | ROCKCHIP_CAN_MODE, |
|---|
| 107 | 108 | ROCKCHIP_RK3568_CAN_MODE, |
|---|
| 109 | + ROCKCHIP_RK3568_CAN_MODE_V2, |
|---|
| 108 | 110 | }; |
|---|
| 109 | 111 | |
|---|
| 110 | 112 | #define DATE_LENGTH_12_BYTE (0x9) |
|---|
| .. | .. |
|---|
| 212 | 214 | #define CAN_RXFRD_OFFSET(n) (CAN_RXFRD + CAN_RF_SIZE * (n)) |
|---|
| 213 | 215 | |
|---|
| 214 | 216 | #define CAN_RX_FILTER_MASK 0x1fffffff |
|---|
| 217 | +#define NOACK_ERR_FLAG 0xc200800 |
|---|
| 218 | +#define CAN_BUSOFF_FLAG 0x20 |
|---|
| 215 | 219 | |
|---|
| 216 | 220 | #define DRV_NAME "rockchip_canfd" |
|---|
| 217 | 221 | |
|---|
| .. | .. |
|---|
| 220 | 224 | struct rockchip_canfd { |
|---|
| 221 | 225 | struct can_priv can; |
|---|
| 222 | 226 | struct device *dev; |
|---|
| 227 | + struct napi_struct napi; |
|---|
| 223 | 228 | struct clk_bulk_data *clks; |
|---|
| 224 | 229 | int num_clks; |
|---|
| 225 | 230 | struct reset_control *reset; |
|---|
| .. | .. |
|---|
| 231 | 236 | bool txtorx; |
|---|
| 232 | 237 | u32 tx_invalid[4]; |
|---|
| 233 | 238 | struct delayed_work tx_err_work; |
|---|
| 239 | + u32 delay_time_ms; |
|---|
| 234 | 240 | }; |
|---|
| 235 | 241 | |
|---|
| 236 | 242 | static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv, |
|---|
| .. | .. |
|---|
| 292 | 298 | |
|---|
| 293 | 299 | val = rockchip_canfd_read(rcan, CAN_MODE); |
|---|
| 294 | 300 | val |= WORK_MODE; |
|---|
| 295 | | - if (rcan->mode >= ROCKCHIP_CAN_MODE && rcan->txtorx) |
|---|
| 296 | | - val |= MODE_RXSTX; |
|---|
| 297 | 301 | rockchip_canfd_write(rcan, CAN_MODE, val); |
|---|
| 298 | 302 | |
|---|
| 299 | 303 | netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__, |
|---|
| .. | .. |
|---|
| 356 | 360 | |
|---|
| 357 | 361 | rockchip_canfd_write(rcan, CAN_DBTP, reg_btp); |
|---|
| 358 | 362 | } |
|---|
| 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; |
|---|
| 359 | 369 | |
|---|
| 360 | 370 | netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__, |
|---|
| 361 | 371 | rockchip_canfd_read(rcan, CAN_NBTP), |
|---|
| .. | .. |
|---|
| 427 | 437 | if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
|---|
| 428 | 438 | val |= MODE_SELF_TEST | MODE_LBACK; |
|---|
| 429 | 439 | |
|---|
| 430 | | - val |= MODE_AUTO_RETX; |
|---|
| 440 | + /* Listen-only mode */ |
|---|
| 441 | + if (rcan->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
|---|
| 442 | + val |= MODE_SILENT; |
|---|
| 431 | 443 | |
|---|
| 432 | 444 | rockchip_canfd_write(rcan, CAN_MODE, val); |
|---|
| 433 | 445 | |
|---|
| .. | .. |
|---|
| 488 | 500 | { |
|---|
| 489 | 501 | struct rockchip_canfd *rcan = |
|---|
| 490 | 502 | container_of(work, struct rockchip_canfd, tx_err_work.work); |
|---|
| 491 | | - u32 mode, err_code, id; |
|---|
| 503 | + u32 mode, err_code; |
|---|
| 492 | 504 | |
|---|
| 493 | | - id = rockchip_canfd_read(rcan, CAN_TXID); |
|---|
| 505 | + mode = rockchip_canfd_read(rcan, CAN_MODE); |
|---|
| 494 | 506 | 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 { |
|---|
| 497 | 515 | rockchip_canfd_write(rcan, CAN_MODE, 0); |
|---|
| 498 | 516 | rockchip_canfd_write(rcan, CAN_MODE, mode); |
|---|
| 517 | + rockchip_canfd_write(rcan, CAN_MODE, |
|---|
| 518 | + rockchip_canfd_read(rcan, CAN_MODE) | MODE_SPACE_RX); |
|---|
| 499 | 519 | 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)); |
|---|
| 503 | 523 | } |
|---|
| 504 | 524 | } |
|---|
| 505 | 525 | |
|---|
| .. | .. |
|---|
| 552 | 572 | dlc |= TX_FD_BRS_ENABLE; |
|---|
| 553 | 573 | } |
|---|
| 554 | 574 | |
|---|
| 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) { |
|---|
| 556 | 583 | /* Two frames are sent consecutively. |
|---|
| 557 | 584 | * Before the first frame is tx finished, |
|---|
| 558 | 585 | * the register of the second frame is configured. |
|---|
| .. | .. |
|---|
| 569 | 596 | for (i = 0; i < cf->len; i += 4) |
|---|
| 570 | 597 | rockchip_canfd_write(rcan, CAN_TXDAT0 + i, |
|---|
| 571 | 598 | *(u32 *)(cf->data + i)); |
|---|
| 599 | + can_put_echo_skb(skb, ndev, 0); |
|---|
| 572 | 600 | rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ); |
|---|
| 573 | 601 | local_irq_restore(flags); |
|---|
| 574 | | - can_put_echo_skb(skb, ndev, 0); |
|---|
| 575 | | - |
|---|
| 576 | 602 | return NETDEV_TX_OK; |
|---|
| 577 | 603 | } |
|---|
| 578 | 604 | |
|---|
| .. | .. |
|---|
| 583 | 609 | rockchip_canfd_write(rcan, CAN_TXDAT0 + i, |
|---|
| 584 | 610 | *(u32 *)(cf->data + i)); |
|---|
| 585 | 611 | |
|---|
| 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 | | - |
|---|
| 591 | 612 | 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)); |
|---|
| 593 | 619 | return NETDEV_TX_OK; |
|---|
| 594 | 620 | } |
|---|
| 595 | 621 | |
|---|
| .. | .. |
|---|
| 602 | 628 | u32 id_rockchip_canfd, dlc; |
|---|
| 603 | 629 | int i = 0; |
|---|
| 604 | 630 | u32 __maybe_unused ts, ret; |
|---|
| 605 | | - u32 data[16] = {0}; |
|---|
| 631 | + u32 data[16]; |
|---|
| 606 | 632 | |
|---|
| 607 | 633 | dlc = rockchip_canfd_read(rcan, CAN_RXFRD); |
|---|
| 608 | 634 | id_rockchip_canfd = rockchip_canfd_read(rcan, CAN_RXFRD); |
|---|
| 609 | 635 | ts = rockchip_canfd_read(rcan, CAN_RXFRD); |
|---|
| 610 | | - for (i = 0; i < 16; i++) |
|---|
| 636 | + for (i = 0; i < ARRAY_SIZE(data); i++) |
|---|
| 611 | 637 | data[i] = rockchip_canfd_read(rcan, CAN_RXFRD); |
|---|
| 612 | 638 | |
|---|
| 613 | | - if (rcan->mode >= ROCKCHIP_CAN_MODE) { |
|---|
| 639 | + if (rcan->mode <= ROCKCHIP_RK3568_CAN_MODE) { |
|---|
| 614 | 640 | /* may be an empty frame */ |
|---|
| 615 | 641 | if (!dlc && !id_rockchip_canfd) |
|---|
| 616 | 642 | return 1; |
|---|
| .. | .. |
|---|
| 618 | 644 | if (rcan->txtorx) { |
|---|
| 619 | 645 | if (rockchip_canfd_read(rcan, CAN_TX_CHECK_FIC) & FORMAT_MASK) { |
|---|
| 620 | 646 | 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)) |
|---|
| 622 | 648 | rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, |
|---|
| 623 | 649 | ts | CAN_TX0_REQ); |
|---|
| 624 | | - return 1; |
|---|
| 625 | | - } |
|---|
| 650 | + return 1; |
|---|
| 626 | 651 | } |
|---|
| 627 | 652 | } |
|---|
| 628 | 653 | } |
|---|
| .. | .. |
|---|
| 675 | 700 | return 1; |
|---|
| 676 | 701 | } |
|---|
| 677 | 702 | |
|---|
| 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 | + |
|---|
| 678 | 750 | static int rockchip_canfd_err(struct net_device *ndev, u32 isr) |
|---|
| 679 | 751 | { |
|---|
| 680 | 752 | struct rockchip_canfd *rcan = netdev_priv(ndev); |
|---|
| .. | .. |
|---|
| 724 | 796 | } |
|---|
| 725 | 797 | |
|---|
| 726 | 798 | 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 | + } |
|---|
| 729 | 807 | |
|---|
| 730 | 808 | stats->rx_packets++; |
|---|
| 731 | 809 | stats->rx_bytes += cf->can_dlc; |
|---|
| .. | .. |
|---|
| 740 | 818 | struct rockchip_canfd *rcan = netdev_priv(ndev); |
|---|
| 741 | 819 | struct net_device_stats *stats = &ndev->stats; |
|---|
| 742 | 820 | 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; |
|---|
| 744 | 822 | u32 isr; |
|---|
| 745 | 823 | u32 dlc = 0; |
|---|
| 746 | 824 | u32 quota, work_done = 0; |
|---|
| 747 | 825 | |
|---|
| 748 | 826 | isr = rockchip_canfd_read(rcan, CAN_INT); |
|---|
| 749 | 827 | if (isr & TX_FINISH_INT) { |
|---|
| 828 | + cancel_delayed_work(&rcan->tx_err_work); |
|---|
| 750 | 829 | dlc = rockchip_canfd_read(rcan, CAN_TXFIC); |
|---|
| 751 | 830 | /* transmission complete interrupt */ |
|---|
| 752 | 831 | if (dlc & FDF_MASK) |
|---|
| .. | .. |
|---|
| 754 | 833 | else |
|---|
| 755 | 834 | stats->tx_bytes += (dlc & DLC_MASK); |
|---|
| 756 | 835 | 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) { |
|---|
| 759 | 837 | 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); |
|---|
| 763 | 839 | if (quota) { |
|---|
| 764 | 840 | while (work_done < quota) |
|---|
| 765 | 841 | work_done += rockchip_canfd_rx(ndev); |
|---|
| .. | .. |
|---|
| 768 | 844 | rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ); |
|---|
| 769 | 845 | rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, 0); |
|---|
| 770 | 846 | } |
|---|
| 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"); |
|---|
| 771 | 851 | rockchip_canfd_write(rcan, CAN_CMD, 0); |
|---|
| 772 | 852 | can_get_echo_skb(ndev, 0); |
|---|
| 773 | 853 | netif_wake_queue(ndev); |
|---|
| .. | .. |
|---|
| 775 | 855 | } |
|---|
| 776 | 856 | |
|---|
| 777 | 857 | 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 | + } |
|---|
| 783 | 870 | } |
|---|
| 784 | 871 | } |
|---|
| 785 | 872 | |
|---|
| .. | .. |
|---|
| 817 | 904 | } |
|---|
| 818 | 905 | |
|---|
| 819 | 906 | can_led_event(ndev, CAN_LED_EVENT_OPEN); |
|---|
| 907 | + if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2) |
|---|
| 908 | + napi_enable(&rcan->napi); |
|---|
| 820 | 909 | netif_start_queue(ndev); |
|---|
| 821 | 910 | |
|---|
| 822 | 911 | netdev_dbg(ndev, "%s\n", __func__); |
|---|
| .. | .. |
|---|
| 834 | 923 | struct rockchip_canfd *rcan = netdev_priv(ndev); |
|---|
| 835 | 924 | |
|---|
| 836 | 925 | netif_stop_queue(ndev); |
|---|
| 926 | + if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2) |
|---|
| 927 | + napi_disable(&rcan->napi); |
|---|
| 837 | 928 | rockchip_canfd_stop(ndev); |
|---|
| 838 | 929 | close_candev(ndev); |
|---|
| 839 | 930 | can_led_event(ndev, CAN_LED_EVENT_STOP); |
|---|
| .. | .. |
|---|
| 1011 | 1102 | |
|---|
| 1012 | 1103 | rcan->mode = (unsigned long)of_device_get_match_data(&pdev->dev); |
|---|
| 1013 | 1104 | |
|---|
| 1105 | + if ((cpu_is_rk3566() || cpu_is_rk3568()) && (rockchip_get_cpu_version() == 3)) |
|---|
| 1106 | + rcan->mode = ROCKCHIP_RK3568_CAN_MODE_V2; |
|---|
| 1107 | + |
|---|
| 1014 | 1108 | rcan->base = addr; |
|---|
| 1015 | 1109 | rcan->can.clock.freq = clk_get_rate(rcan->clks[0].clk); |
|---|
| 1016 | 1110 | rcan->dev = &pdev->dev; |
|---|
| .. | .. |
|---|
| 1032 | 1126 | break; |
|---|
| 1033 | 1127 | case ROCKCHIP_CAN_MODE: |
|---|
| 1034 | 1128 | case ROCKCHIP_RK3568_CAN_MODE: |
|---|
| 1129 | + case ROCKCHIP_RK3568_CAN_MODE_V2: |
|---|
| 1035 | 1130 | rcan->can.bittiming_const = &rockchip_canfd_bittiming_const; |
|---|
| 1036 | 1131 | rcan->can.do_set_mode = rockchip_canfd_set_mode; |
|---|
| 1037 | 1132 | rcan->can.do_get_berr_counter = rockchip_canfd_get_berr_counter; |
|---|
| .. | .. |
|---|
| 1056 | 1151 | rcan->tx_invalid, 4)) |
|---|
| 1057 | 1152 | rcan->txtorx = 1; |
|---|
| 1058 | 1153 | |
|---|
| 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 | + |
|---|
| 1059 | 1159 | ndev->netdev_ops = &rockchip_canfd_netdev_ops; |
|---|
| 1060 | 1160 | ndev->irq = irq; |
|---|
| 1061 | 1161 | ndev->flags |= IFF_ECHO; |
|---|
| 1062 | 1162 | rcan->can.restart_ms = 1; |
|---|
| 1163 | + |
|---|
| 1164 | + irq_set_affinity_hint(irq, get_cpu_mask(num_online_cpus() - 1)); |
|---|
| 1063 | 1165 | |
|---|
| 1064 | 1166 | INIT_DELAYED_WORK(&rcan->tx_err_work, rockchip_canfd_tx_err_delay_work); |
|---|
| 1065 | 1167 | |
|---|
| .. | .. |
|---|
| 1097 | 1199 | static int rockchip_canfd_remove(struct platform_device *pdev) |
|---|
| 1098 | 1200 | { |
|---|
| 1099 | 1201 | struct net_device *ndev = platform_get_drvdata(pdev); |
|---|
| 1202 | + struct rockchip_canfd *rcan = netdev_priv(ndev); |
|---|
| 1100 | 1203 | |
|---|
| 1101 | 1204 | unregister_netdev(ndev); |
|---|
| 1102 | 1205 | pm_runtime_disable(&pdev->dev); |
|---|
| 1206 | + if (rcan->mode == ROCKCHIP_RK3568_CAN_MODE_V2) |
|---|
| 1207 | + netif_napi_del(&rcan->napi); |
|---|
| 1103 | 1208 | free_candev(ndev); |
|---|
| 1104 | 1209 | |
|---|
| 1105 | 1210 | return 0; |
|---|
| .. | .. |
|---|
| 1117 | 1222 | module_platform_driver(rockchip_canfd_driver); |
|---|
| 1118 | 1223 | |
|---|
| 1119 | 1224 | MODULE_AUTHOR("Elaine Zhang <zhangqing@rock-chips.com>"); |
|---|
| 1225 | +MODULE_LICENSE("GPL"); |
|---|
| 1120 | 1226 | MODULE_DESCRIPTION("Rockchip CANFD Drivers"); |
|---|