gpu: nvgpu: unify nvgpu and pci probe

We have completely different versions of probe for
nvgpu and pci device
Extract out common steps into nvgpu_probe() function
and separate it out in new file nvgpu_common.c
Divide task of nvgpu_probe() into further smaller
functions

Do platform specific things (like irq handling,
memresource management, power management) only in
individual probes and then call nvgpu_probe() to
complete the common initialization

Move all debugfs initialization to common gk20a_debug_init()
This also helps to bringup all debug nodes to pci device

Pass debugfs_symlink name as a parameter to gk20a_debug_init()
This allows us to set separate debugfs symlink for nvgpu
and pci device

In case of railgating, cde and ce debugfs, check if
platform supports them or not

Copy vidmem_is_vidmem from platform to mm structure
and set it to true for pci device

Return from gk20a_scale_init() if we don't have either of
governor or qos_notifier

Fix gk20a_alloc_debugfs_init() and gk20a_secure_page_alloc()
to receive device pointer instead of platform_device

Export gk20a_railgating_debugfs_init() so that we can call
it from gk20a_debug_init()

Jira DNVGPU-56
Jira DNVGPU-58

Change-Id: I3cc048082b0a1e57415a9fb8bfb9eec0f0a280cd
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1204207
(cherry picked from commit add6bb0a3d5bd98131bbe6f62d4358d4d722b0fe)
Reviewed-on: http://git-master/r/1204462
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Deepak Nibade
2016-08-17 22:01:43 +05:30
committed by mobile promotions
parent f31e575ed6
commit 70cad5fbb5
14 changed files with 314 additions and 248 deletions

View File

@@ -26,6 +26,7 @@ obj-$(CONFIG_GK20A) := nvgpu.o
nvgpu-y := \
gk20a/gk20a.o \
nvgpu_common.o \
gk20a/sched_gk20a.o \
gk20a/as_gk20a.o \
gk20a/ctrl_gk20a.o \

View File

@@ -1653,6 +1653,9 @@ void gk20a_cde_debugfs_init(struct device *dev)
struct gk20a_platform *platform = dev_get_drvdata(dev);
struct gk20a *g = get_gk20a(dev);
if (!platform->has_cde)
return;
debugfs_create_u32("cde_parameter", S_IWUSR | S_IRUGO,
platform->debugfs, &g->cde_app.shader_parameter);
debugfs_create_u32("cde_ctx_count", S_IWUSR | S_IRUGO,

View File

@@ -710,6 +710,9 @@ void gk20a_ce_debugfs_init(struct device *dev)
struct gk20a_platform *platform = dev_get_drvdata(dev);
struct gk20a *g = get_gk20a(dev);
if (!platform->has_ce)
return;
debugfs_create_u32("ce_app_ctx_count", S_IWUSR | S_IRUGO,
platform->debugfs, &g->ce_app.ctx_count);
debugfs_create_u32("ce_app_state", S_IWUSR | S_IRUGO,

View File

@@ -386,30 +386,101 @@ void gk20a_init_debug_ops(struct gpu_ops *gops)
gops->debug.show_dump = gk20a_debug_show_dump;
}
void gk20a_debug_init(struct device *dev)
void gk20a_debug_init(struct device *dev, const char *debugfs_symlink)
{
struct gk20a_platform *platform = dev_get_drvdata(dev);
#ifdef CONFIG_DEBUG_FS
struct gk20a *g = platform->g;
#endif
platform->debugfs = debugfs_create_dir(dev_name(dev), NULL);
if (platform->debugfs) {
if (!platform->debugfs)
return;
if (debugfs_symlink)
platform->debugfs_alias =
debugfs_create_symlink("gpu.0", NULL, dev_name(dev));
debugfs_create_symlink(debugfs_symlink,
NULL, dev_name(dev));
debugfs_create_file("status", S_IRUGO, platform->debugfs,
dev, &gk20a_debug_fops);
debugfs_create_file("gr_status", S_IRUGO, platform->debugfs,
dev, &gk20a_gr_debug_fops);
debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR,
platform->debugfs, &gk20a_debug_trace_cmdbuf);
debugfs_create_file("status", S_IRUGO, platform->debugfs,
dev, &gk20a_debug_fops);
debugfs_create_file("gr_status", S_IRUGO, platform->debugfs,
dev, &gk20a_gr_debug_fops);
debugfs_create_u32("trace_cmdbuf", S_IRUGO|S_IWUSR,
platform->debugfs, &gk20a_debug_trace_cmdbuf);
debugfs_create_u32("ch_wdt_timeout_ms", S_IRUGO|S_IWUSR,
platform->debugfs, &platform->ch_wdt_timeout_ms);
debugfs_create_u32("ch_wdt_timeout_ms", S_IRUGO|S_IWUSR,
platform->debugfs, &platform->ch_wdt_timeout_ms);
#if defined(GK20A_DEBUG)
debugfs_create_u32("dbg_mask", S_IRUGO|S_IWUSR,
platform->debugfs, &gk20a_dbg_mask);
debugfs_create_u32("dbg_ftrace", S_IRUGO|S_IWUSR,
platform->debugfs, &gk20a_dbg_ftrace);
debugfs_create_u32("dbg_mask", S_IRUGO|S_IWUSR,
platform->debugfs, &gk20a_dbg_mask);
debugfs_create_u32("dbg_ftrace", S_IRUGO|S_IWUSR,
platform->debugfs, &gk20a_dbg_ftrace);
#endif
}
#ifdef CONFIG_DEBUG_FS
spin_lock_init(&g->debugfs_lock);
g->mm.ltc_enabled = true;
g->mm.ltc_enabled_debug = true;
g->debugfs_ltc_enabled =
debugfs_create_bool("ltc_enabled", S_IRUGO|S_IWUSR,
platform->debugfs,
&g->mm.ltc_enabled_debug);
g->debugfs_gr_idle_timeout_default =
debugfs_create_u32("gr_idle_timeout_default_us",
S_IRUGO|S_IWUSR, platform->debugfs,
&g->gr_idle_timeout_default);
g->debugfs_timeouts_enabled =
debugfs_create_bool("timeouts_enabled",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->timeouts_enabled);
g->debugfs_bypass_smmu =
debugfs_create_bool("bypass_smmu",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->mm.bypass_smmu);
g->debugfs_disable_bigpage =
debugfs_create_bool("disable_bigpage",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->mm.disable_bigpage);
g->debugfs_timeslice_low_priority_us =
debugfs_create_u32("timeslice_low_priority_us",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->timeslice_low_priority_us);
g->debugfs_timeslice_medium_priority_us =
debugfs_create_u32("timeslice_medium_priority_us",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->timeslice_medium_priority_us);
g->debugfs_timeslice_high_priority_us =
debugfs_create_u32("timeslice_high_priority_us",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->timeslice_high_priority_us);
g->debugfs_runlist_interleave =
debugfs_create_bool("runlist_interleave",
S_IRUGO|S_IWUSR,
platform->debugfs,
&g->runlist_interleave);
gr_gk20a_debugfs_init(g);
gk20a_pmu_debugfs_init(g->dev);
gk20a_railgating_debugfs_init(g->dev);
gk20a_cde_debugfs_init(g->dev);
gk20a_ce_debugfs_init(g->dev);
gk20a_alloc_debugfs_init(g->dev);
gk20a_mm_debugfs_init(g->dev);
gk20a_fifo_debugfs_init(g->dev);
gk20a_sched_debugfs_init(g->dev);
#endif
}

View File

@@ -35,7 +35,7 @@ void gk20a_debug_output(struct gk20a_debug_output *o,
void gk20a_debug_dump(struct device *pdev);
void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o);
int gk20a_gr_debug_dump(struct device *pdev);
void gk20a_debug_init(struct device *dev);
void gk20a_debug_init(struct device *dev, const char *debugfs_symlink);
void gk20a_init_debug_ops(struct gpu_ops *gops);
void gk20a_debug_dump_device(void *dev);

View File

@@ -45,6 +45,7 @@
#include <linux/version.h>
#include "gk20a.h"
#include "nvgpu_common.h"
#include "debug_gk20a.h"
#include "ctrl_gk20a.h"
#include "hw_mc_gk20a.h"
@@ -83,8 +84,6 @@
#define GK20A_NUM_CDEVS 7
#define EMC3D_DEFAULT_RATIO 750
#if defined(GK20A_DEBUG)
u32 gk20a_dbg_mask = GK20A_DEFAULT_DBG_MASK;
u32 gk20a_dbg_ftrace;
@@ -144,11 +143,14 @@ static const struct file_operations railgate_residency_fops = {
.release = single_release,
};
static int gk20a_railgating_debugfs_init(struct device *dev)
int gk20a_railgating_debugfs_init(struct device *dev)
{
struct dentry *d;
struct gk20a_platform *platform = dev_get_drvdata(dev);
if (!platform->can_railgate)
return 0;
d = debugfs_create_file(
"railgate_residency", S_IRUGO|S_IWUSR, platform->debugfs, dev,
&railgate_residency_fops);
@@ -740,32 +742,15 @@ static int gk20a_init_support(struct platform_device *dev)
goto fail;
}
g->regs_saved = g->regs;
g->bar1_saved = g->bar1;
/* Get interrupt numbers */
g->irq_nonstall = platform_get_irq(dev, 1);
if (g->irq_stall < 0 || g->irq_nonstall < 0) {
err = -ENXIO;
goto fail;
}
if (tegra_cpu_is_asim()) {
err = gk20a_init_sim_support(dev);
if (err)
goto fail;
}
mutex_init(&g->dbg_sessions_lock);
mutex_init(&g->client_lock);
mutex_init(&g->ch_wdt_lock);
mutex_init(&g->poweroff_lock);
g->remove_support = gk20a_remove_support;
return 0;
fail:
gk20a_remove_support(&dev->dev);
return err;
}
@@ -1449,13 +1434,13 @@ int gk20a_pm_init(struct device *dev)
return err;
}
static int gk20a_secure_page_alloc(struct platform_device *pdev)
int gk20a_secure_page_alloc(struct device *dev)
{
struct gk20a_platform *platform = platform_get_drvdata(pdev);
struct gk20a_platform *platform = dev_get_drvdata(dev);
int err = 0;
if (platform->secure_page_alloc) {
err = platform->secure_page_alloc(&pdev->dev);
err = platform->secure_page_alloc(dev);
if (!err)
platform->secure_alloc_ready = true;
}
@@ -1499,9 +1484,6 @@ static int gk20a_probe(struct platform_device *dev)
return -ENOMEM;
}
init_waitqueue_head(&gk20a->sw_irq_stall_last_handled_wq);
init_waitqueue_head(&gk20a->sw_irq_nonstall_last_handled_wq);
set_gk20a(dev, gk20a);
gk20a->dev = &dev->dev;
@@ -1509,6 +1491,7 @@ static int gk20a_probe(struct platform_device *dev)
gk20a->irq_nonstall = platform_get_irq(dev, 1);
if (gk20a->irq_stall < 0 || gk20a->irq_nonstall < 0)
return -ENXIO;
err = devm_request_threaded_irq(&dev->dev,
gk20a->irq_stall,
gk20a_intr_isr_stall,
@@ -1535,36 +1518,19 @@ static int gk20a_probe(struct platform_device *dev)
if (gk20a->irq_stall != gk20a->irq_nonstall)
disable_irq(gk20a->irq_nonstall);
err = gk20a_user_init(&dev->dev, INTERFACE_NAME, &nvgpu_class);
err = gk20a_init_support(dev);
if (err)
return err;
gk20a_init_support(dev);
init_rwsem(&gk20a->busy_lock);
mutex_init(&platform->railgate_lock);
spin_lock_init(&gk20a->mc_enable_lock);
#ifdef CONFIG_RESET_CONTROLLER
platform->reset_control = devm_reset_control_get(&dev->dev, NULL);
if (IS_ERR(platform->reset_control))
platform->reset_control = NULL;
#endif
gk20a_debug_init(&dev->dev);
/* Initialize the platform interface. */
err = platform->probe(&dev->dev);
if (err) {
dev_err(&dev->dev, "platform probe failed");
return err;
}
err = gk20a_secure_page_alloc(dev);
err = nvgpu_probe(gk20a, "gpu.0", INTERFACE_NAME, &nvgpu_class);
if (err)
dev_err(&dev->dev,
"failed to allocate secure buffer %d\n", err);
return err;
err = gk20a_pm_init(&dev->dev);
if (err) {
@@ -1572,127 +1538,8 @@ static int gk20a_probe(struct platform_device *dev)
return err;
}
gk20a->emc3d_ratio = EMC3D_DEFAULT_RATIO;
/* Initialise scaling */
if (IS_ENABLED(CONFIG_GK20A_DEVFREQ))
gk20a_scale_init(&dev->dev);
/* Set DMA parameters to allow larger sgt lists */
dev->dev.dma_parms = &gk20a->dma_parms;
dma_set_max_seg_size(&dev->dev, UINT_MAX);
gk20a->gr_idle_timeout_default =
CONFIG_GK20A_DEFAULT_TIMEOUT;
if (tegra_platform_is_silicon())
gk20a->timeouts_enabled = true;
gk20a->runlist_interleave = true;
gk20a->timeslice_low_priority_us = 1300;
gk20a->timeslice_medium_priority_us = 2600;
gk20a->timeslice_high_priority_us = 5200;
/* Set up initial power settings. For non-slicon platforms, disable *
* power features and for silicon platforms, read from platform data */
gk20a->slcg_enabled =
tegra_platform_is_silicon() ? platform->enable_slcg : false;
gk20a->blcg_enabled =
tegra_platform_is_silicon() ? platform->enable_blcg : false;
gk20a->elcg_enabled =
tegra_platform_is_silicon() ? platform->enable_elcg : false;
gk20a->elpg_enabled =
tegra_platform_is_silicon() ? platform->enable_elpg : false;
gk20a->aelpg_enabled =
tegra_platform_is_silicon() ? platform->enable_aelpg : false;
/* set default values to aelpg parameters */
gk20a->pmu.aelpg_param[0] = APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US;
gk20a->pmu.aelpg_param[1] = APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US;
gk20a->pmu.aelpg_param[2] = APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US;
gk20a->pmu.aelpg_param[3] = APCTRL_POWER_BREAKEVEN_DEFAULT_US;
gk20a->pmu.aelpg_param[4] = APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT;
if (platform->late_probe) {
err = platform->late_probe(&dev->dev);
if (err) {
dev_err(&dev->dev, "late probe failed");
return err;
}
}
gk20a_create_sysfs(&dev->dev);
gk20a->mm.bypass_smmu = platform->bypass_smmu;
gk20a->mm.disable_bigpage = platform->disable_bigpage;
gk20a->mm.has_physical_mode = !is_tegra_hypervisor_mode();
#ifdef CONFIG_DEBUG_FS
spin_lock_init(&gk20a->debugfs_lock);
gk20a->mm.ltc_enabled = true;
gk20a->mm.ltc_enabled_debug = true;
gk20a->debugfs_ltc_enabled =
debugfs_create_bool("ltc_enabled", S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->mm.ltc_enabled_debug);
gk20a->mm.ltc_enabled_debug = true;
gk20a->debugfs_gr_idle_timeout_default =
debugfs_create_u32("gr_idle_timeout_default_us",
S_IRUGO|S_IWUSR, platform->debugfs,
&gk20a->gr_idle_timeout_default);
gk20a->debugfs_timeouts_enabled =
debugfs_create_bool("timeouts_enabled",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->timeouts_enabled);
gk20a->debugfs_bypass_smmu =
debugfs_create_bool("bypass_smmu",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->mm.bypass_smmu);
gk20a->debugfs_disable_bigpage =
debugfs_create_bool("disable_bigpage",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->mm.disable_bigpage);
gk20a->debugfs_timeslice_low_priority_us =
debugfs_create_u32("timeslice_low_priority_us",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->timeslice_low_priority_us);
gk20a->debugfs_timeslice_medium_priority_us =
debugfs_create_u32("timeslice_medium_priority_us",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->timeslice_medium_priority_us);
gk20a->debugfs_timeslice_high_priority_us =
debugfs_create_u32("timeslice_high_priority_us",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->timeslice_high_priority_us);
gk20a->debugfs_runlist_interleave =
debugfs_create_bool("runlist_interleave",
S_IRUGO|S_IWUSR,
platform->debugfs,
&gk20a->runlist_interleave);
gr_gk20a_debugfs_init(gk20a);
gk20a_pmu_debugfs_init(&dev->dev);
gk20a_railgating_debugfs_init(&dev->dev);
gk20a_cde_debugfs_init(&dev->dev);
gk20a_ce_debugfs_init(&dev->dev);
gk20a_alloc_debugfs_init(dev);
gk20a_mm_debugfs_init(&dev->dev);
gk20a_fifo_debugfs_init(&dev->dev);
gk20a_sched_debugfs_init(&dev->dev);
#endif
gk20a_init_gr(gk20a);
return 0;
}

View File

@@ -1205,4 +1205,9 @@ static inline void gk20a_channel_trace_sched_param(
ch->ch_ctx.gr_ctx->compute_preempt_mode : 0));
}
#ifdef CONFIG_DEBUG_FS
int gk20a_railgating_debugfs_init(struct device *dev);
#endif
int gk20a_secure_page_alloc(struct device *dev);
#endif /* GK20A_H */

View File

@@ -168,9 +168,9 @@ void gk20a_fini_alloc_debug(struct gk20a_allocator *a)
debugfs_remove(a->debugfs_entry);
}
void gk20a_alloc_debugfs_init(struct platform_device *pdev)
void gk20a_alloc_debugfs_init(struct device *dev)
{
struct gk20a_platform *platform = platform_get_drvdata(pdev);
struct gk20a_platform *platform = dev_get_drvdata(dev);
struct dentry *gpu_root = platform->debugfs;
gk20a_alloc_debugfs_root = debugfs_create_dir("allocators", gpu_root);

View File

@@ -210,7 +210,7 @@ static inline void gk20a_alloc_disable_dbg(struct gk20a_allocator *a)
*/
extern u32 gk20a_alloc_tracing_on;
void gk20a_alloc_debugfs_init(struct platform_device *pdev);
void gk20a_alloc_debugfs_init(struct device *dev);
#define gk20a_alloc_trace_func() \
do { \

View File

@@ -319,6 +319,9 @@ void gk20a_scale_init(struct device *dev)
if (g->scale_profile)
return;
if (!platform->devfreq_governor && !platform->qos_notify)
return;
profile = kzalloc(sizeof(*profile), GFP_KERNEL);
profile->dev = dev;

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2016, 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 <linux/dma-mapping.h>
#include "gk20a/gk20a_scale.h"
#include "gk20a/gk20a.h"
#define EMC3D_DEFAULT_RATIO 750
static void nvgpu_init_vars(struct gk20a *g)
{
struct gk20a_platform *platform = dev_get_drvdata(g->dev);
init_waitqueue_head(&g->sw_irq_stall_last_handled_wq);
init_waitqueue_head(&g->sw_irq_nonstall_last_handled_wq);
gk20a_init_gr(g);
init_rwsem(&g->busy_lock);
spin_lock_init(&g->mc_enable_lock);
mutex_init(&platform->railgate_lock);
mutex_init(&g->dbg_sessions_lock);
mutex_init(&g->client_lock);
mutex_init(&g->ch_wdt_lock);
mutex_init(&g->poweroff_lock);
g->regs_saved = g->regs;
g->bar1_saved = g->bar1;
g->emc3d_ratio = EMC3D_DEFAULT_RATIO;
/* Set DMA parameters to allow larger sgt lists */
g->dev->dma_parms = &g->dma_parms;
dma_set_max_seg_size(g->dev, UINT_MAX);
}
static void nvgpu_init_timeout(struct gk20a *g)
{
g->gr_idle_timeout_default = CONFIG_GK20A_DEFAULT_TIMEOUT;
if (tegra_platform_is_silicon())
g->timeouts_enabled = true;
}
static void nvgpu_init_timeslice(struct gk20a *g)
{
g->runlist_interleave = true;
g->timeslice_low_priority_us = 1300;
g->timeslice_medium_priority_us = 2600;
g->timeslice_high_priority_us = 5200;
}
static void nvgpu_init_pm_vars(struct gk20a *g)
{
struct gk20a_platform *platform = dev_get_drvdata(g->dev);
/*
* Set up initial power settings. For non-slicon platforms, disable
* power features and for silicon platforms, read from platform data
*/
g->slcg_enabled =
tegra_platform_is_silicon() ? platform->enable_slcg : false;
g->blcg_enabled =
tegra_platform_is_silicon() ? platform->enable_blcg : false;
g->elcg_enabled =
tegra_platform_is_silicon() ? platform->enable_elcg : false;
g->elpg_enabled =
tegra_platform_is_silicon() ? platform->enable_elpg : false;
g->aelpg_enabled =
tegra_platform_is_silicon() ? platform->enable_aelpg : false;
/* set default values to aelpg parameters */
g->pmu.aelpg_param[0] = APCTRL_SAMPLING_PERIOD_PG_DEFAULT_US;
g->pmu.aelpg_param[1] = APCTRL_MINIMUM_IDLE_FILTER_DEFAULT_US;
g->pmu.aelpg_param[2] = APCTRL_MINIMUM_TARGET_SAVING_DEFAULT_US;
g->pmu.aelpg_param[3] = APCTRL_POWER_BREAKEVEN_DEFAULT_US;
g->pmu.aelpg_param[4] = APCTRL_CYCLES_PER_SAMPLE_MAX_DEFAULT;
}
static void nvgpu_init_mm_vars(struct gk20a *g)
{
struct gk20a_platform *platform = dev_get_drvdata(g->dev);
g->mm.bypass_smmu = platform->bypass_smmu;
g->mm.disable_bigpage = platform->disable_bigpage;
g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem;
}
int nvgpu_probe(struct gk20a *g,
const char *debugfs_symlink,
const char *interface_name,
struct class *class)
{
struct gk20a_platform *platform = dev_get_drvdata(g->dev);
int err = 0;
nvgpu_init_vars(g);
nvgpu_init_timeout(g);
nvgpu_init_timeslice(g);
nvgpu_init_pm_vars(g);
err = gk20a_user_init(g->dev, interface_name, class);
if (err)
return err;
/* Initialize the platform interface. */
err = platform->probe(g->dev);
if (err) {
dev_err(g->dev, "platform probe failed");
return err;
}
/* Initialise scaling */
if (IS_ENABLED(CONFIG_GK20A_DEVFREQ))
gk20a_scale_init(g->dev);
err = gk20a_secure_page_alloc(g->dev);
if (err)
dev_err(g->dev,
"failed to allocate secure buffer %d\n", err);
if (platform->late_probe) {
err = platform->late_probe(g->dev);
if (err) {
dev_err(g->dev, "late probe failed");
return err;
}
}
nvgpu_init_mm_vars(g);
gk20a_create_sysfs(g->dev);
gk20a_debug_init(g->dev, debugfs_symlink);
g->remove_support = gk20a_remove_support;
return 0;
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2016, 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_COMMON_H
#define NVGPU_COMMON_H
struct gk20a;
int nvgpu_probe(struct gk20a *g,
const char *debugfs_symlink,
const char *interface_name,
struct class *class);
#endif

View File

@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include "pci.h"
#include "nvgpu_common.h"
#include "gk20a/gk20a.h"
#include "gk20a/platform_gk20a.h"
@@ -58,6 +59,8 @@ static struct gk20a_platform nvgpu_pci_device = {
.ch_wdt_timeout_ms = 7000,
.has_ce = true,
.vidmem_is_vidmem = true,
};
static struct pci_device_id nvgpu_pci_table[] = {
@@ -113,19 +116,9 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
goto fail;
}
g->regs_saved = g->regs;
g->bar1_saved = g->bar1;
mutex_init(&g->dbg_sessions_lock);
mutex_init(&g->client_lock);
mutex_init(&g->ch_wdt_lock);
mutex_init(&g->poweroff_lock);
g->remove_support = gk20a_remove_support;
return 0;
fail:
gk20a_remove_support(&pdev->dev);
return err;
}
@@ -200,9 +193,6 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
return -ENOMEM;
}
init_waitqueue_head(&g->sw_irq_stall_last_handled_wq);
init_waitqueue_head(&g->sw_irq_nonstall_last_handled_wq);
platform->g = g;
g->dev = &pdev->dev;
@@ -215,6 +205,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
g->irq_nonstall = pdev->irq;
if (g->irq_stall < 0)
return -ENXIO;
err = devm_request_threaded_irq(&pdev->dev,
g->irq_stall,
nvgpu_pci_isr,
@@ -227,6 +218,10 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
}
disable_irq(g->irq_stall);
err = nvgpu_pci_init_support(pdev);
if (err)
return err;
if (strchr(dev_name(&pdev->dev), '%')) {
gk20a_err(&pdev->dev, "illegal character in device name");
return -EINVAL;
@@ -236,57 +231,12 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
if (!nodefmt)
return -ENOMEM;
err = gk20a_user_init(&pdev->dev, nodefmt, &nvgpu_pci_class);
err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class);
if (err)
return err;
kfree(nodefmt);
nodefmt = NULL;
if (err)
return err;
err = nvgpu_pci_init_support(pdev);
if (err)
return err;
init_rwsem(&g->busy_lock);
mutex_init(&platform->railgate_lock);
spin_lock_init(&g->mc_enable_lock);
gk20a_debug_init(&pdev->dev);
/* Initialize the platform interface. */
err = platform->probe(&pdev->dev);
if (err) {
gk20a_err(&pdev->dev, "platform probe failed");
return err;
}
/* Set DMA parameters to allow larger sgt lists */
pdev->dev.dma_parms = &g->dma_parms;
dma_set_max_seg_size(&pdev->dev, UINT_MAX);
g->gr_idle_timeout_default =
CONFIG_GK20A_DEFAULT_TIMEOUT;
if (tegra_platform_is_silicon())
g->timeouts_enabled = true;
g->runlist_interleave = true;
g->timeslice_low_priority_us = 1300;
g->timeslice_medium_priority_us = 2600;
g->timeslice_high_priority_us = 5200;
gk20a_create_sysfs(&pdev->dev);
g->mm.has_physical_mode = false;
g->mm.vidmem_is_vidmem = true;
#ifdef CONFIG_DEBUG_FS
g->mm.ltc_enabled = true;
g->mm.ltc_enabled_debug = true;
#endif
g->mm.bypass_smmu = platform->bypass_smmu;
g->mm.disable_bigpage = platform->disable_bigpage;
gk20a_init_gr(g);
err = nvgpu_pci_pm_init(&pdev->dev);
if (err) {
@@ -294,6 +244,8 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
return err;
}
g->mm.has_physical_mode = false;
return 0;
}

View File

@@ -599,7 +599,7 @@ int vgpu_probe(struct platform_device *pdev)
if (IS_ERR(priv->intr_handler))
return -ENOMEM;
gk20a_debug_init(dev);
gk20a_debug_init(dev, "gpu.0");
/* Set DMA parameters to allow larger sgt lists */
dev->dma_parms = &gk20a->dma_parms;