diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2017-10-02 06:38:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-02 14:24:41 -0400 |
commit | 8c6bba10fb9262d7b3a11e86a40621d5b37810a6 (patch) | |
tree | dd1ea0a7e55932118808c6721a6da67adf044aa3 /drivers/thunderbolt | |
parent | d1ff70241a275133e1a0258b7c23588b122276c8 (diff) |
thunderbolt: Configure interrupt throttling for all interrupts
This will keep the interrupt delivery rate reasonable. The value used
here (128 us) is a recommendation from the hardware people.
This code is based on the work done by Amir Levy and Michael Jamet.
Signed-off-by: Michael Jamet <michael.jamet@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/thunderbolt')
-rw-r--r-- | drivers/thunderbolt/nhi.c | 23 | ||||
-rw-r--r-- | drivers/thunderbolt/nhi_regs.h | 2 |
2 files changed, 22 insertions, 3 deletions
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 05af126a2435..8a7a3d0133f9 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c | |||
@@ -651,6 +651,22 @@ static int nhi_suspend_noirq(struct device *dev) | |||
651 | return tb_domain_suspend_noirq(tb); | 651 | return tb_domain_suspend_noirq(tb); |
652 | } | 652 | } |
653 | 653 | ||
654 | static void nhi_enable_int_throttling(struct tb_nhi *nhi) | ||
655 | { | ||
656 | /* Throttling is specified in 256ns increments */ | ||
657 | u32 throttle = DIV_ROUND_UP(128 * NSEC_PER_USEC, 256); | ||
658 | unsigned int i; | ||
659 | |||
660 | /* | ||
661 | * Configure interrupt throttling for all vectors even if we | ||
662 | * only use few. | ||
663 | */ | ||
664 | for (i = 0; i < MSIX_MAX_VECS; i++) { | ||
665 | u32 reg = REG_INT_THROTTLING_RATE + i * 4; | ||
666 | iowrite32(throttle, nhi->iobase + reg); | ||
667 | } | ||
668 | } | ||
669 | |||
654 | static int nhi_resume_noirq(struct device *dev) | 670 | static int nhi_resume_noirq(struct device *dev) |
655 | { | 671 | { |
656 | struct pci_dev *pdev = to_pci_dev(dev); | 672 | struct pci_dev *pdev = to_pci_dev(dev); |
@@ -663,6 +679,8 @@ static int nhi_resume_noirq(struct device *dev) | |||
663 | */ | 679 | */ |
664 | if (!pci_device_is_present(pdev)) | 680 | if (!pci_device_is_present(pdev)) |
665 | tb->nhi->going_away = true; | 681 | tb->nhi->going_away = true; |
682 | else | ||
683 | nhi_enable_int_throttling(tb->nhi); | ||
666 | 684 | ||
667 | return tb_domain_resume_noirq(tb); | 685 | return tb_domain_resume_noirq(tb); |
668 | } | 686 | } |
@@ -717,6 +735,8 @@ static int nhi_init_msi(struct tb_nhi *nhi) | |||
717 | /* In case someone left them on. */ | 735 | /* In case someone left them on. */ |
718 | nhi_disable_interrupts(nhi); | 736 | nhi_disable_interrupts(nhi); |
719 | 737 | ||
738 | nhi_enable_int_throttling(nhi); | ||
739 | |||
720 | ida_init(&nhi->msix_ida); | 740 | ida_init(&nhi->msix_ida); |
721 | 741 | ||
722 | /* | 742 | /* |
@@ -796,9 +816,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
796 | 816 | ||
797 | pci_set_master(pdev); | 817 | pci_set_master(pdev); |
798 | 818 | ||
799 | /* magic value - clock related? */ | ||
800 | iowrite32(3906250 / 10000, nhi->iobase + 0x38c00); | ||
801 | |||
802 | tb = icm_probe(nhi); | 819 | tb = icm_probe(nhi); |
803 | if (!tb) | 820 | if (!tb) |
804 | tb = tb_probe(nhi); | 821 | tb = tb_probe(nhi); |
diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h index 09ed574e92ff..46eff69b19ad 100644 --- a/drivers/thunderbolt/nhi_regs.h +++ b/drivers/thunderbolt/nhi_regs.h | |||
@@ -95,6 +95,8 @@ struct ring_desc { | |||
95 | #define REG_RING_INTERRUPT_BASE 0x38200 | 95 | #define REG_RING_INTERRUPT_BASE 0x38200 |
96 | #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32) | 96 | #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32) |
97 | 97 | ||
98 | #define REG_INT_THROTTLING_RATE 0x38c00 | ||
99 | |||
98 | /* Interrupt Vector Allocation */ | 100 | /* Interrupt Vector Allocation */ |
99 | #define REG_INT_VEC_ALLOC_BASE 0x38c40 | 101 | #define REG_INT_VEC_ALLOC_BASE 0x38c40 |
100 | #define REG_INT_VEC_ALLOC_BITS 4 | 102 | #define REG_INT_VEC_ALLOC_BITS 4 |