From 70cad5fbb593602a49f91e57c04d1da0334b3a49 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 17 Aug 2016 22:01:43 +0530 Subject: 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 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 --- drivers/gpu/nvgpu/Makefile.nvgpu | 1 + drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 3 + drivers/gpu/nvgpu/gk20a/ce2_gk20a.c | 3 + drivers/gpu/nvgpu/gk20a/debug_gk20a.c | 103 ++++++++++++++--- drivers/gpu/nvgpu/gk20a/debug_gk20a.h | 2 +- drivers/gpu/nvgpu/gk20a/gk20a.c | 177 ++---------------------------- drivers/gpu/nvgpu/gk20a/gk20a.h | 5 + drivers/gpu/nvgpu/gk20a/gk20a_allocator.c | 4 +- drivers/gpu/nvgpu/gk20a/gk20a_allocator.h | 2 +- drivers/gpu/nvgpu/gk20a/gk20a_scale.c | 3 + drivers/gpu/nvgpu/nvgpu_common.c | 154 ++++++++++++++++++++++++++ drivers/gpu/nvgpu/nvgpu_common.h | 27 +++++ drivers/gpu/nvgpu/pci.c | 74 +++---------- drivers/gpu/nvgpu/vgpu/vgpu.c | 2 +- 14 files changed, 313 insertions(+), 247 deletions(-) create mode 100644 drivers/gpu/nvgpu/nvgpu_common.c create mode 100644 drivers/gpu/nvgpu/nvgpu_common.h diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu index 7e703706..5ca2f56f 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu +++ b/drivers/gpu/nvgpu/Makefile.nvgpu @@ -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 \ diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index 6f8c160c..844718a7 100644 --- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c @@ -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, diff --git a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c index 8548ae84..109ec240 100644 --- a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c @@ -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, diff --git a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c index 93580a7f..9a84e2e3 100644 --- a/drivers/gpu/nvgpu/gk20a/debug_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/debug_gk20a.c @@ -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 + } diff --git a/drivers/gpu/nvgpu/gk20a/debug_gk20a.h b/drivers/gpu/nvgpu/gk20a/debug_gk20a.h index e83076b8..ac8e3236 100644 --- a/drivers/gpu/nvgpu/gk20a/debug_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/debug_gk20a.h @@ -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); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 1fe1d330..f6bb9445 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -45,6 +45,7 @@ #include #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; } diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index c255f8f8..669ef1b9 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -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 */ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c index d9e38200..3b20fa2e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.c @@ -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); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.h b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.h index fbfda881..93865190 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_allocator.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a_allocator.h @@ -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 { \ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_scale.c b/drivers/gpu/nvgpu/gk20a/gk20a_scale.c index ec9ca5db..ac28d967 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_scale.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_scale.c @@ -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; diff --git a/drivers/gpu/nvgpu/nvgpu_common.c b/drivers/gpu/nvgpu/nvgpu_common.c new file mode 100644 index 00000000..bdc07e50 --- /dev/null +++ b/drivers/gpu/nvgpu/nvgpu_common.c @@ -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 . + */ + +#include + +#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; +} diff --git a/drivers/gpu/nvgpu/nvgpu_common.h b/drivers/gpu/nvgpu/nvgpu_common.h new file mode 100644 index 00000000..c9914089 --- /dev/null +++ b/drivers/gpu/nvgpu/nvgpu_common.h @@ -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 . + */ + +#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 diff --git a/drivers/gpu/nvgpu/pci.c b/drivers/gpu/nvgpu/pci.c index cbf444ad..a67bbd54 100644 --- a/drivers/gpu/nvgpu/pci.c +++ b/drivers/gpu/nvgpu/pci.c @@ -18,6 +18,7 @@ #include #include #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); - kfree(nodefmt); - nodefmt = NULL; - if (err) - return err; - - err = nvgpu_pci_init_support(pdev); + err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class); 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); + kfree(nodefmt); + nodefmt = NULL; 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; } diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index c548175a..27d98eb8 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c @@ -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; -- cgit v1.2.2