summaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2017-10-02 06:38:35 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-02 14:24:41 -0400
commit8c6bba10fb9262d7b3a11e86a40621d5b37810a6 (patch)
treedd1ea0a7e55932118808c6721a6da67adf044aa3 /drivers/thunderbolt
parentd1ff70241a275133e1a0258b7c23588b122276c8 (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.c23
-rw-r--r--drivers/thunderbolt/nhi_regs.h2
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
654static 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
654static int nhi_resume_noirq(struct device *dev) 670static 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