mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: linux: add virtual function support
vf probe is called by pci general probe when platform data indicates it's a virtual device. vf_linux covers PCIE specific initialization, then call common vgpu probe. Jira GVSCI-15779 Change-Id: I47ce1c4807b23363a9062ff0cbc8e08b9c6cdc97 Signed-off-by: Richard Zhao <rizhao@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2884177 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
8a411096c9
commit
f9242c032e
@@ -232,6 +232,8 @@ vgpu:
|
|||||||
os/linux/vgpu/platform_vgpu_tegra.c,
|
os/linux/vgpu/platform_vgpu_tegra.c,
|
||||||
os/linux/vgpu/platform_vgpu_tegra.h,
|
os/linux/vgpu/platform_vgpu_tegra.h,
|
||||||
os/linux/vgpu/sysfs_vgpu.c,
|
os/linux/vgpu/sysfs_vgpu.c,
|
||||||
|
os/linux/vgpu/vf_linux.c,
|
||||||
|
os/linux/vgpu/vf_linux.h,
|
||||||
os/linux/vgpu/vgpu_common.c,
|
os/linux/vgpu/vgpu_common.c,
|
||||||
os/linux/vgpu/vgpu_common.h,
|
os/linux/vgpu/vgpu_common.h,
|
||||||
os/linux/vgpu/vgpu_ivc.c,
|
os/linux/vgpu/vgpu_ivc.c,
|
||||||
|
|||||||
@@ -627,6 +627,9 @@ nvgpu-$(CONFIG_NVGPU_GR_VIRTUALIZATION) += \
|
|||||||
os/linux/vgpu/vgpu_linux.o \
|
os/linux/vgpu/vgpu_linux.o \
|
||||||
os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.o
|
os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.o
|
||||||
|
|
||||||
|
nvgpu-$(CONFIG_NVGPU_GR_VIRTUALIZATION) += \
|
||||||
|
os/linux/vgpu/vf_linux.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_NVGPU_FECS_TRACE),y)
|
ifeq ($(CONFIG_NVGPU_FECS_TRACE),y)
|
||||||
nvgpu-$(CONFIG_NVGPU_GR_VIRTUALIZATION) += \
|
nvgpu-$(CONFIG_NVGPU_GR_VIRTUALIZATION) += \
|
||||||
os/linux/vgpu/fecs_trace_vgpu_linux.o
|
os/linux/vgpu/fecs_trace_vgpu_linux.o
|
||||||
|
|||||||
@@ -52,6 +52,8 @@
|
|||||||
#include "driver_common.h"
|
#include "driver_common.h"
|
||||||
#include "dmabuf_priv.h"
|
#include "dmabuf_priv.h"
|
||||||
|
|
||||||
|
#include "vgpu/vf_linux.h"
|
||||||
|
|
||||||
#if defined(CONFIG_NVGPU_HAL_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
#if defined(CONFIG_NVGPU_HAL_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
||||||
#include <nvgpu_next_chips.h>
|
#include <nvgpu_next_chips.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -564,10 +566,30 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
u32 device_index = PCI_DEVICE_INDEX(pent->driver_data);
|
u32 device_index = PCI_DEVICE_INDEX(pent->driver_data);
|
||||||
u32 device_flags = PCI_DEVICE_FLAGS(pent->driver_data);
|
u32 device_flags = PCI_DEVICE_FLAGS(pent->driver_data);
|
||||||
|
|
||||||
|
/* Allocate memory to hold platform data*/
|
||||||
|
platform = (struct gk20a_platform *)kzalloc(
|
||||||
|
sizeof(struct gk20a_platform), GFP_KERNEL);
|
||||||
|
if (!platform) {
|
||||||
|
dev_err(&pdev->dev, "couldn't allocate platform data");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy detected device data to allocated platform space*/
|
||||||
|
err = nvgpu_pci_get_platform_data(platform, device_index);
|
||||||
|
if (err)
|
||||||
|
goto err_free_platform;
|
||||||
|
|
||||||
|
if (platform->virtual_dev) {
|
||||||
|
err = vf_probe(pdev, platform);
|
||||||
|
if (err)
|
||||||
|
goto err_free_platform;
|
||||||
|
}
|
||||||
|
|
||||||
l = kzalloc(sizeof(*l), GFP_KERNEL);
|
l = kzalloc(sizeof(*l), GFP_KERNEL);
|
||||||
if (!l) {
|
if (!l) {
|
||||||
dev_err(&pdev->dev, "couldn't allocate gk20a support");
|
dev_err(&pdev->dev, "couldn't allocate gk20a support");
|
||||||
return -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
goto err_free_platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
g = &l->g;
|
g = &l->g;
|
||||||
@@ -578,27 +600,13 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
nvgpu_kmem_init(g);
|
nvgpu_kmem_init(g);
|
||||||
|
|
||||||
/* Allocate memory to hold platform data*/
|
|
||||||
platform = (struct gk20a_platform *)nvgpu_kzalloc( g,
|
|
||||||
sizeof(struct gk20a_platform));
|
|
||||||
if (!platform) {
|
|
||||||
dev_err(&pdev->dev, "couldn't allocate platform data");
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto err_free_l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy detected device data to allocated platform space*/
|
|
||||||
err = nvgpu_pci_get_platform_data(platform, device_index);
|
|
||||||
if (err)
|
|
||||||
goto err_free_platform;
|
|
||||||
|
|
||||||
g->is_pci_igpu = platform->is_pci_igpu;
|
g->is_pci_igpu = platform->is_pci_igpu;
|
||||||
nvgpu_info(g, "is_pci_igpu: %s", g->is_pci_igpu ? "true" : "false");
|
nvgpu_info(g, "is_pci_igpu: %s", g->is_pci_igpu ? "true" : "false");
|
||||||
pci_set_drvdata(pdev, platform);
|
pci_set_drvdata(pdev, platform);
|
||||||
|
|
||||||
err = nvgpu_init_errata_flags(g);
|
err = nvgpu_init_errata_flags(g);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_platform;
|
goto err_free_l;
|
||||||
|
|
||||||
err = nvgpu_init_enabled_flags(g);
|
err = nvgpu_init_enabled_flags(g);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -783,13 +791,13 @@ err_disable_msi:
|
|||||||
nvgpu_free_enabled_flags(g);
|
nvgpu_free_enabled_flags(g);
|
||||||
err_free_errata:
|
err_free_errata:
|
||||||
nvgpu_free_errata_flags(g);
|
nvgpu_free_errata_flags(g);
|
||||||
err_free_platform:
|
|
||||||
nvgpu_kfree(g, platform);
|
|
||||||
err_free_l:
|
err_free_l:
|
||||||
|
|
||||||
if (g->is_pci_igpu)
|
if (g->is_pci_igpu)
|
||||||
nvgpu_kmem_fini(g, NVGPU_KMEM_FINI_FORCE_CLEANUP);
|
nvgpu_kmem_fini(g, NVGPU_KMEM_FINI_FORCE_CLEANUP);
|
||||||
kfree(l);
|
kfree(l);
|
||||||
|
err_free_platform:
|
||||||
|
kfree(platform);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
163
drivers/gpu/nvgpu/os/linux/vgpu/vf_linux.c
Normal file
163
drivers/gpu/nvgpu/os/linux/vgpu/vf_linux.c
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nvgpu/nvgpu_init.h>
|
||||||
|
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
|
||||||
|
#include "os/linux/module.h"
|
||||||
|
#include "os/linux/os_linux.h"
|
||||||
|
#include "os/linux/platform_gk20a.h"
|
||||||
|
#include "os/linux/vgpu/vgpu_common.h"
|
||||||
|
|
||||||
|
static irqreturn_t vf_isr(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct gk20a *g = dev_id;
|
||||||
|
u32 ret_nonstall = nvgpu_cic_mon_intr_nonstall_isr(g);
|
||||||
|
|
||||||
|
if (ret_nonstall == NVGPU_CIC_INTR_HANDLE) {
|
||||||
|
return IRQ_WAKE_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IRQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t vf_intr_thread(int irq, void *dev_id)
|
||||||
|
{
|
||||||
|
struct gk20a *g = dev_id;
|
||||||
|
|
||||||
|
nvgpu_cic_mon_intr_nonstall_handle(g);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vf_pci_init_support(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
void __iomem *addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
addr = devm_ioremap(dev, pci_resource_start(pdev, 0),
|
||||||
|
pci_resource_len(pdev, 0));
|
||||||
|
if (IS_ERR(addr)) {
|
||||||
|
nvgpu_err(g, "failed to remap gk20a registers");
|
||||||
|
err = PTR_ERR(addr);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
g->func_regs = (uintptr_t)addr;
|
||||||
|
|
||||||
|
g->regs_bus_addr = pci_resource_start(pdev, 0);
|
||||||
|
if (!g->regs_bus_addr) {
|
||||||
|
nvgpu_err(g, "failed to read register bus offset");
|
||||||
|
err = -ENODEV;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = devm_ioremap(dev, pci_resource_start(pdev, 1),
|
||||||
|
pci_resource_len(pdev, 1));
|
||||||
|
if (IS_ERR(addr)) {
|
||||||
|
nvgpu_err(g, "failed to remap gk20a bar1");
|
||||||
|
err = PTR_ERR(addr);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
g->bar1 = (uintptr_t)addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vf_probe(struct pci_dev *pdev, struct gk20a_platform *platform)
|
||||||
|
{
|
||||||
|
struct nvgpu_os_linux *l;
|
||||||
|
struct gk20a *g;
|
||||||
|
struct device_node *np;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
l = devm_kzalloc(&pdev->dev, sizeof(*l), GFP_KERNEL);
|
||||||
|
if (l == NULL) {
|
||||||
|
dev_err(&pdev->dev, "couldn't allocate gk20a support");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
g = &l->g;
|
||||||
|
platform->g = g;
|
||||||
|
l->dev = &pdev->dev;
|
||||||
|
|
||||||
|
g->log_mask = NVGPU_DEFAULT_DBG_MASK;
|
||||||
|
g->is_pci_igpu = platform->is_pci_igpu;
|
||||||
|
|
||||||
|
pci_set_drvdata(pdev, platform);
|
||||||
|
|
||||||
|
np = nvgpu_get_node(g);
|
||||||
|
if (of_dma_is_coherent(np)) {
|
||||||
|
nvgpu_set_enabled(g, NVGPU_USE_COHERENT_SYSMEM, true);
|
||||||
|
nvgpu_set_enabled(g, NVGPU_SUPPORT_IO_COHERENCE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pci_enable_device(pdev);
|
||||||
|
if (err) {
|
||||||
|
nvgpu_err(g, "enable device failed err=%d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
pci_set_master(pdev);
|
||||||
|
|
||||||
|
g->pci_vendor_id = pdev->vendor;
|
||||||
|
g->pci_device_id = pdev->device;
|
||||||
|
g->pci_subsystem_vendor_id = pdev->subsystem_vendor;
|
||||||
|
g->pci_subsystem_device_id = pdev->subsystem_device;
|
||||||
|
g->pci_class = (pdev->class >> 8) & 0xFFFFU; // we only want base/sub
|
||||||
|
g->pci_revision = pdev->revision;
|
||||||
|
|
||||||
|
err = pci_alloc_irq_vectors(pdev, 1, 64, PCI_IRQ_MSIX);
|
||||||
|
if (err < 0) {
|
||||||
|
nvgpu_err(g,
|
||||||
|
"MSI-X alloc failed, err=%d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
/* TODO: separate stall/non-stall interrupts once support multi-vector */
|
||||||
|
l->interrupts.nonstall_size = err;
|
||||||
|
g->msi_enabled = true;
|
||||||
|
|
||||||
|
/* TODO: support multiple nonstall irqs */
|
||||||
|
l->interrupts.nonstall_line = pci_irq_vector(pdev, 0);
|
||||||
|
|
||||||
|
err = devm_request_threaded_irq(&pdev->dev,
|
||||||
|
l->interrupts.nonstall_line,
|
||||||
|
vf_isr,
|
||||||
|
vf_intr_thread,
|
||||||
|
0, "nvgpu", g);
|
||||||
|
if (err) {
|
||||||
|
nvgpu_err(g,
|
||||||
|
"failed to request irq @ %d err=%d",
|
||||||
|
l->interrupts.nonstall_line, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
nvgpu_disable_irqs(g);
|
||||||
|
|
||||||
|
err = vf_pci_init_support(pdev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = vgpu_probe_common(l);
|
||||||
|
if (err) {
|
||||||
|
nvgpu_err(g, "common probe failed, err=%d", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
g->probe_done = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
33
drivers/gpu/nvgpu/os/linux/vgpu/vf_linux.h
Normal file
33
drivers/gpu/nvgpu/os/linux/vgpu/vf_linux.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NVGPU_VF_LINUX_H
|
||||||
|
#define NVGPU_VF_LINUX_H
|
||||||
|
|
||||||
|
struct pci_dev;
|
||||||
|
struct gk20a_platform;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NVGPU_GR_VIRTUALIZATION
|
||||||
|
int vf_probe(struct pci_dev *pdev, struct gk20a_platform *platform);
|
||||||
|
#else
|
||||||
|
static inline int vf_probe(struct pci_dev *pdev,
|
||||||
|
struct gk20a_platform *platform)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user