From 73243017514ac509c3a91224286f2bcf9f5a95bd Mon Sep 17 00:00:00 2001 From: David Nieto Date: Thu, 19 Jan 2017 16:04:50 -0800 Subject: gpu: nvgpu: enable PCI MSI interrupts Use MSI interrupts instead of legacy on PCIe dGPUs to reduce latency and contention with other PCIe devices JIRA EVLR-986 Change-Id: I6cecc7e62e5797860d42a5bee21e8f4f664e1b18 Signed-off-by: David Nieto Reviewed-on: http://git-master/r/1291758 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/gk20a/gk20a.h | 8 +++++++ drivers/gpu/nvgpu/gp106/xve_gp106.c | 14 ++++++++++-- .../nvgpu/include/nvgpu/hw/gp106/hw_xve_gp106.h | 5 +++++ drivers/gpu/nvgpu/pci.c | 26 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 19fa4e26..72f9170e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -780,6 +780,9 @@ struct gpu_ops { void (*xve_writel)(struct gk20a *g, u32 reg, u32 val); void (*disable_aspm)(struct gk20a *g); void (*reset_gpu)(struct gk20a *g); +#if defined(CONFIG_PCI_MSI) + void (*rearm_msi)(struct gk20a *g); +#endif } xve; }; @@ -1037,6 +1040,11 @@ struct gk20a { /* Current warning temp in sfxp24.8 */ s32 curr_warn_temp; + +#if defined(CONFIG_PCI_MSI) + /* Check if msi is enabled */ + bool msi_enabled; +#endif }; static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/gp106/xve_gp106.c b/drivers/gpu/nvgpu/gp106/xve_gp106.c index 561140c6..83ae9306 100644 --- a/drivers/gpu/nvgpu/gp106/xve_gp106.c +++ b/drivers/gpu/nvgpu/gp106/xve_gp106.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -653,6 +653,14 @@ fail: #endif } +#if defined(CONFIG_PCI_MSI) +static void xve_rearm_msi_gp106(struct gk20a *g) +{ + /* We just need to write a dummy val in the CYA_2 offset */ + g->ops.xve.xve_writel(g, xve_cya_2_r(), 0); +} +#endif + /* * Init the HAL functions and what not. xve_sw_init_gp106() is for initializing * all the other stuff like debugfs nodes, etc. @@ -667,6 +675,8 @@ int gp106_init_xve_ops(struct gpu_ops *gops) gops->xve.xve_writel = xve_xve_writel_gp106; gops->xve.disable_aspm = xve_disable_aspm_gp106; gops->xve.reset_gpu = xve_reset_gpu_gp106; - +#if defined(CONFIG_PCI_MSI) + gops->xve.rearm_msi = xve_rearm_msi_gp106; +#endif return 0; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/hw/gp106/hw_xve_gp106.h b/drivers/gpu/nvgpu/include/nvgpu/hw/gp106/hw_xve_gp106.h index bfcb4883..c6e9a654 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/hw/gp106/hw_xve_gp106.h +++ b/drivers/gpu/nvgpu/include/nvgpu/hw/gp106/hw_xve_gp106.h @@ -194,4 +194,9 @@ static inline u32 xve_reset_clock_counter_val_v(u32 r) { return (r >> 17) & 0x7ff; } +static inline u32 xve_cya_2_r(void) +{ + return 0x00000704; +} + #endif diff --git a/drivers/gpu/nvgpu/pci.c b/drivers/gpu/nvgpu/pci.c index feb253b6..648fc60e 100644 --- a/drivers/gpu/nvgpu/pci.c +++ b/drivers/gpu/nvgpu/pci.c @@ -226,6 +226,12 @@ static irqreturn_t nvgpu_pci_isr(int irq, void *dev_id) ret_stall = g->ops.mc.isr_stall(g); ret_nonstall = g->ops.mc.isr_nonstall(g); +#if defined(CONFIG_PCI_MSI) + /* Send MSI EOI */ + if (g->ops.xve.rearm_msi && g->msi_enabled) + g->ops.xve.rearm_msi(g); +#endif + return (ret_stall == IRQ_NONE && ret_nonstall == IRQ_NONE) ? IRQ_NONE : IRQ_WAKE_THREAD; } @@ -361,6 +367,16 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, g->pci_class = (pdev->class >> 8) & 0xFFFFU; // we only want base/sub g->pci_revision = pdev->revision; +#if defined(CONFIG_PCI_MSI) + err = pci_enable_msi(pdev); + if (err) { + gk20a_err(&pdev->dev, + "MSI could not be enabled, falling back to legacy"); + g->msi_enabled = false; + } else + g->msi_enabled = true; +#endif + g->irq_stall = pdev->irq; g->irq_nonstall = pdev->irq; if (g->irq_stall < 0) @@ -370,6 +386,9 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, g->irq_stall, nvgpu_pci_isr, nvgpu_pci_intr_thread, +#if defined(CONFIG_PCI_MSI) + g->msi_enabled ? 0 : +#endif IRQF_SHARED, "nvgpu", g); if (err) { gk20a_err(&pdev->dev, @@ -419,6 +438,13 @@ static void nvgpu_pci_remove(struct pci_dev *pdev) disable_irq(g->irq_stall); devm_free_irq(&pdev->dev, g->irq_stall, g); + +#if defined(CONFIG_PCI_MSI) + if (g->msi_enabled) { + pci_disable_msi(pdev); + g->msi_enabled = false; + } +#endif gk20a_dbg(gpu_dbg_shutdown, "IRQs disabled.\n"); /* -- cgit v1.2.2