Commit 8c6bba10 authored by Mika Westerberg's avatar Mika Westerberg Committed by David S. Miller

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: default avatarMichael Jamet <michael.jamet@intel.com>
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: default avatarYehezkel Bernat <yehezkel.bernat@intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d1ff7024
...@@ -651,6 +651,22 @@ static int nhi_suspend_noirq(struct device *dev) ...@@ -651,6 +651,22 @@ static int nhi_suspend_noirq(struct device *dev)
return tb_domain_suspend_noirq(tb); return tb_domain_suspend_noirq(tb);
} }
static void nhi_enable_int_throttling(struct tb_nhi *nhi)
{
/* Throttling is specified in 256ns increments */
u32 throttle = DIV_ROUND_UP(128 * NSEC_PER_USEC, 256);
unsigned int i;
/*
* Configure interrupt throttling for all vectors even if we
* only use few.
*/
for (i = 0; i < MSIX_MAX_VECS; i++) {
u32 reg = REG_INT_THROTTLING_RATE + i * 4;
iowrite32(throttle, nhi->iobase + reg);
}
}
static int nhi_resume_noirq(struct device *dev) static int nhi_resume_noirq(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
...@@ -663,6 +679,8 @@ static int nhi_resume_noirq(struct device *dev) ...@@ -663,6 +679,8 @@ static int nhi_resume_noirq(struct device *dev)
*/ */
if (!pci_device_is_present(pdev)) if (!pci_device_is_present(pdev))
tb->nhi->going_away = true; tb->nhi->going_away = true;
else
nhi_enable_int_throttling(tb->nhi);
return tb_domain_resume_noirq(tb); return tb_domain_resume_noirq(tb);
} }
...@@ -717,6 +735,8 @@ static int nhi_init_msi(struct tb_nhi *nhi) ...@@ -717,6 +735,8 @@ static int nhi_init_msi(struct tb_nhi *nhi)
/* In case someone left them on. */ /* In case someone left them on. */
nhi_disable_interrupts(nhi); nhi_disable_interrupts(nhi);
nhi_enable_int_throttling(nhi);
ida_init(&nhi->msix_ida); ida_init(&nhi->msix_ida);
/* /*
...@@ -796,9 +816,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -796,9 +816,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_master(pdev); pci_set_master(pdev);
/* magic value - clock related? */
iowrite32(3906250 / 10000, nhi->iobase + 0x38c00);
tb = icm_probe(nhi); tb = icm_probe(nhi);
if (!tb) if (!tb)
tb = tb_probe(nhi); tb = tb_probe(nhi);
......
...@@ -95,6 +95,8 @@ struct ring_desc { ...@@ -95,6 +95,8 @@ struct ring_desc {
#define REG_RING_INTERRUPT_BASE 0x38200 #define REG_RING_INTERRUPT_BASE 0x38200
#define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32) #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
#define REG_INT_THROTTLING_RATE 0x38c00
/* Interrupt Vector Allocation */ /* Interrupt Vector Allocation */
#define REG_INT_VEC_ALLOC_BASE 0x38c40 #define REG_INT_VEC_ALLOC_BASE 0x38c40
#define REG_INT_VEC_ALLOC_BITS 4 #define REG_INT_VEC_ALLOC_BITS 4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment