mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 02:22:34 +03:00
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:
committed by
mobile promotions
parent
f31e575ed6
commit
70cad5fbb5
@@ -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 \
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
@@ -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;
|
||||
|
||||
154
drivers/gpu/nvgpu/nvgpu_common.c
Normal file
154
drivers/gpu/nvgpu/nvgpu_common.c
Normal 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;
|
||||
}
|
||||
27
drivers/gpu/nvgpu/nvgpu_common.h
Normal file
27
drivers/gpu/nvgpu/nvgpu_common.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user