From 89772b03cb093b3556dd4803e5a8deee60046ac9 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 8 Aug 2017 10:53:25 -0700 Subject: gpu: nvgpu: Move XVE debugfs code to Linux module Move XVE debugfs initialization code to live under common/linux. JIRA NVGPU-62 Change-Id: Ic6677511d249bc0a2455dde01db5b230afc70bb1 Signed-off-by: Terje Bergstrom Reviewed-on: https://git-master.nvidia.com/r/1535133 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile.nvgpu | 3 +- drivers/gpu/nvgpu/common/linux/debug.c | 3 + drivers/gpu/nvgpu/common/linux/debug_xve.c | 176 +++++++++++++++++++++++++++++ drivers/gpu/nvgpu/common/linux/debug_xve.h | 21 ++++ drivers/gpu/nvgpu/gk20a/gk20a.c | 1 - drivers/gpu/nvgpu/gk20a/gk20a.h | 2 +- drivers/gpu/nvgpu/gp106/hal_gp106.c | 2 +- drivers/gpu/nvgpu/gp106/xve_gp106.c | 170 +--------------------------- drivers/gpu/nvgpu/gp106/xve_gp106.h | 51 +-------- drivers/gpu/nvgpu/include/nvgpu/xve.h | 58 ++++++++++ 10 files changed, 269 insertions(+), 218 deletions(-) create mode 100644 drivers/gpu/nvgpu/common/linux/debug_xve.c create mode 100644 drivers/gpu/nvgpu/common/linux/debug_xve.h create mode 100644 drivers/gpu/nvgpu/include/nvgpu/xve.h (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu index 87199316..e60dc0b6 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu +++ b/drivers/gpu/nvgpu/Makefile.nvgpu @@ -132,7 +132,8 @@ nvgpu-$(CONFIG_DEBUG_FS) += \ common/linux/debug_allocator.o \ common/linux/debug_hal.o \ common/linux/debug_kmem.o \ - common/linux/debug_clk.o + common/linux/debug_clk.o \ + common/linux/debug_xve.o nvgpu-$(CONFIG_TEGRA_GK20A) += common/linux/platform_gk20a_tegra.o nvgpu-$(CONFIG_SYNC) += gk20a/sync_gk20a.o diff --git a/drivers/gpu/nvgpu/common/linux/debug.c b/drivers/gpu/nvgpu/common/linux/debug.c index abc8b907..5750800f 100644 --- a/drivers/gpu/nvgpu/common/linux/debug.c +++ b/drivers/gpu/nvgpu/common/linux/debug.c @@ -22,6 +22,7 @@ #include "debug_pmu.h" #include "debug_sched.h" #include "debug_hal.h" +#include "debug_xve.h" #include "os_linux.h" #include "gk20a/gk20a.h" @@ -394,6 +395,8 @@ void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) #ifdef CONFIG_NVGPU_TRACK_MEM_USAGE nvgpu_kmem_debugfs_init(g); #endif + if (g->pci_vendor_id) + nvgpu_xve_debugfs_init(g); } void gk20a_debug_deinit(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/common/linux/debug_xve.c b/drivers/gpu/nvgpu/common/linux/debug_xve.c new file mode 100644 index 00000000..743702a2 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/debug_xve.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that 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. + * + */ + +#include +#include + +#include "debug_xve.h" +#include "os_linux.h" + +#include +#include + +static ssize_t xve_link_speed_write(struct file *filp, + const char __user *buff, + size_t len, loff_t *off) +{ + struct gk20a *g = ((struct seq_file *)filp->private_data)->private; + char kbuff[16]; + u32 buff_size, check_len; + u32 link_speed = 0; + int ret; + + buff_size = min_t(size_t, 16, len); + + memset(kbuff, 0, 16); + if (copy_from_user(kbuff, buff, buff_size)) + return -EFAULT; + + check_len = strlen("Gen1"); + if (strncmp(kbuff, "Gen1", check_len) == 0) + link_speed = GPU_XVE_SPEED_2P5; + else if (strncmp(kbuff, "Gen2", check_len) == 0) + link_speed = GPU_XVE_SPEED_5P0; + else if (strncmp(kbuff, "Gen3", check_len) == 0) + link_speed = GPU_XVE_SPEED_8P0; + else + nvgpu_err(g, "%s: Unknown PCIe speed: %s", + __func__, kbuff); + + if (!link_speed) + return -EINVAL; + + /* Brief pause... To help rate limit this. */ + nvgpu_msleep(250); + + /* + * And actually set the speed. Yay. + */ + ret = g->ops.xve.set_speed(g, link_speed); + if (ret) + return ret; + + return len; +} + +static int xve_link_speed_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + u32 speed; + int err; + + err = g->ops.xve.get_speed(g, &speed); + if (err) + return err; + + seq_printf(s, "Current PCIe speed:\n %s\n", xve_speed_to_str(speed)); + + return 0; +} + +static int xve_link_speed_open(struct inode *inode, struct file *file) +{ + return single_open(file, xve_link_speed_show, inode->i_private); +} + +static const struct file_operations xve_link_speed_fops = { + .open = xve_link_speed_open, + .read = seq_read, + .write = xve_link_speed_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int xve_available_speeds_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + u32 available_speeds; + + g->ops.xve.available_speeds(g, &available_speeds); + + seq_puts(s, "Available PCIe bus speeds:\n"); + if (available_speeds & GPU_XVE_SPEED_2P5) + seq_puts(s, " Gen1\n"); + if (available_speeds & GPU_XVE_SPEED_5P0) + seq_puts(s, " Gen2\n"); + if (available_speeds & GPU_XVE_SPEED_8P0) + seq_puts(s, " Gen3\n"); + + return 0; +} + +static int xve_available_speeds_open(struct inode *inode, struct file *file) +{ + return single_open(file, xve_available_speeds_show, inode->i_private); +} + +static const struct file_operations xve_available_speeds_fops = { + .open = xve_available_speeds_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int xve_link_control_status_show(struct seq_file *s, void *unused) +{ + struct gk20a *g = s->private; + u32 link_status; + + link_status = g->ops.xve.get_link_control_status(g); + seq_printf(s, "0x%08x\n", link_status); + + return 0; +} + +static int xve_link_control_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, xve_link_control_status_show, inode->i_private); +} + +static const struct file_operations xve_link_control_status_fops = { + .open = xve_link_control_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +int nvgpu_xve_debugfs_init(struct gk20a *g) +{ + int err = -ENODEV; + + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct dentry *gpu_root = l->debugfs; + + l->debugfs_xve = debugfs_create_dir("xve", gpu_root); + if (IS_ERR_OR_NULL(l->debugfs_xve)) + goto fail; + + /* + * These are just debug nodes. If they fail to get made it's not worth + * worrying the higher level SW. + */ + debugfs_create_file("link_speed", S_IRUGO, + l->debugfs_xve, g, + &xve_link_speed_fops); + debugfs_create_file("available_speeds", S_IRUGO, + l->debugfs_xve, g, + &xve_available_speeds_fops); + debugfs_create_file("link_control_status", S_IRUGO, + l->debugfs_xve, g, + &xve_link_control_status_fops); + + err = 0; +fail: + return err; +} diff --git a/drivers/gpu/nvgpu/common/linux/debug_xve.h b/drivers/gpu/nvgpu/common/linux/debug_xve.h new file mode 100644 index 00000000..f3b1ac54 --- /dev/null +++ b/drivers/gpu/nvgpu/common/linux/debug_xve.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that 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. + * + */ + +#ifndef __NVGPU_DEBUG_XVE_H__ +#define __NVGPU_DEBUG_XVE_H__ + +struct gk20a; +int nvgpu_xve_debugfs_init(struct gk20a *g); + +#endif /* __NVGPU_DEBUG_SVE_H__ */ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 63ea5bc4..455fa238 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -329,7 +329,6 @@ int gk20a_finalize_poweron(struct gk20a *g) if (platform->disable_aspm && g->ops.xve.disable_aspm) g->ops.xve.disable_aspm(g); - g->ops.xve.sw_init(g); g->ops.xve.available_speeds(g, &speed); /* Set to max speed */ diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 69cb2253..d2a752d7 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -971,7 +971,6 @@ struct gpu_ops { } css; #endif struct { - int (*sw_init)(struct gk20a *g); int (*get_speed)(struct gk20a *g, u32 *xve_link_speed); int (*set_speed)(struct gk20a *g, u32 xve_link_speed); void (*available_speeds)(struct gk20a *g, u32 *speed_mask); @@ -984,6 +983,7 @@ struct gpu_ops { #endif void (*enable_shadow_rom)(struct gk20a *g); void (*disable_shadow_rom)(struct gk20a *g); + u32 (*get_link_control_status)(struct gk20a *g); } xve; struct { void (*falcon_hal_sw_init)(struct nvgpu_falcon *flcn); diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index 7e7fc195..b33e80ec 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c @@ -660,7 +660,6 @@ static const struct gpu_ops gp106_ops = { }, #endif .xve = { - .sw_init = xve_sw_init_gp106, .get_speed = xve_get_speed_gp106, .set_speed = xve_set_speed_gp106, .available_speeds = xve_available_speeds_gp106, @@ -673,6 +672,7 @@ static const struct gpu_ops gp106_ops = { #endif .enable_shadow_rom = xve_enable_shadow_rom_gp106, .disable_shadow_rom = xve_disable_shadow_rom_gp106, + .get_link_control_status = xve_get_link_control_status, }, .falcon = { .falcon_hal_sw_init = gp106_falcon_hal_sw_init, diff --git a/drivers/gpu/nvgpu/gp106/xve_gp106.c b/drivers/gpu/nvgpu/gp106/xve_gp106.c index a3514fc0..3a84ca17 100644 --- a/drivers/gpu/nvgpu/gp106/xve_gp106.c +++ b/drivers/gpu/nvgpu/gp106/xve_gp106.c @@ -14,17 +14,13 @@ * along with this program. If not, see . */ -#ifdef CONFIG_DEBUG_FS -#include -#include -#endif - #include "gk20a/gk20a.h" #include "gm206/bios_gm206.h" #include "gp106/xve_gp106.h" #include "common/linux/os_linux.h" #include +#include #include #include @@ -475,165 +471,6 @@ void xve_available_speeds_gp106(struct gk20a *g, u32 *speed_mask) *speed_mask = GPU_XVE_SPEED_2P5 | GPU_XVE_SPEED_5P0; } -#ifdef CONFIG_DEBUG_FS -static ssize_t xve_link_speed_write(struct file *filp, - const char __user *buff, - size_t len, loff_t *off) -{ - struct gk20a *g = ((struct seq_file *)filp->private_data)->private; - char kbuff[16]; - u32 buff_size, check_len; - u32 link_speed = 0; - int ret; - - buff_size = min_t(size_t, 16, len); - - memset(kbuff, 0, 16); - if (copy_from_user(kbuff, buff, buff_size)) - return -EFAULT; - - check_len = strlen("Gen1"); - if (strncmp(kbuff, "Gen1", check_len) == 0) - link_speed = GPU_XVE_SPEED_2P5; - else if (strncmp(kbuff, "Gen2", check_len) == 0) - link_speed = GPU_XVE_SPEED_5P0; - else if (strncmp(kbuff, "Gen3", check_len) == 0) - link_speed = GPU_XVE_SPEED_8P0; - else - nvgpu_err(g, "%s: Unknown PCIe speed: %s", - __func__, kbuff); - - if (!link_speed) - return -EINVAL; - - /* Brief pause... To help rate limit this. */ - nvgpu_msleep(250); - - /* - * And actually set the speed. Yay. - */ - ret = g->ops.xve.set_speed(g, link_speed); - if (ret) - return ret; - - return len; -} - -static int xve_link_speed_show(struct seq_file *s, void *unused) -{ - struct gk20a *g = s->private; - u32 speed; - int err; - - err = g->ops.xve.get_speed(g, &speed); - if (err) - return err; - - seq_printf(s, "Current PCIe speed:\n %s\n", xve_speed_to_str(speed)); - - return 0; -} - -static int xve_link_speed_open(struct inode *inode, struct file *file) -{ - return single_open(file, xve_link_speed_show, inode->i_private); -} - -static const struct file_operations xve_link_speed_fops = { - .open = xve_link_speed_open, - .read = seq_read, - .write = xve_link_speed_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static int xve_available_speeds_show(struct seq_file *s, void *unused) -{ - struct gk20a *g = s->private; - u32 available_speeds; - - g->ops.xve.available_speeds(g, &available_speeds); - - seq_puts(s, "Available PCIe bus speeds:\n"); - if (available_speeds & GPU_XVE_SPEED_2P5) - seq_puts(s, " Gen1\n"); - if (available_speeds & GPU_XVE_SPEED_5P0) - seq_puts(s, " Gen2\n"); - if (available_speeds & GPU_XVE_SPEED_8P0) - seq_puts(s, " Gen3\n"); - - return 0; -} - -static int xve_available_speeds_open(struct inode *inode, struct file *file) -{ - return single_open(file, xve_available_speeds_show, inode->i_private); -} - -static const struct file_operations xve_available_speeds_fops = { - .open = xve_available_speeds_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int xve_link_control_status_show(struct seq_file *s, void *unused) -{ - struct gk20a *g = s->private; - u32 link_status; - - link_status = g->ops.xve.xve_readl(g, xve_link_control_status_r()); - seq_printf(s, "0x%08x\n", link_status); - - return 0; -} - -static int xve_link_control_status_open(struct inode *inode, struct file *file) -{ - return single_open(file, xve_link_control_status_show, inode->i_private); -} - -static const struct file_operations xve_link_control_status_fops = { - .open = xve_link_control_status_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -int xve_sw_init_gp106(struct gk20a *g) -{ - int err = -ENODEV; -#ifdef CONFIG_DEBUG_FS - struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); - struct dentry *gpu_root = l->debugfs; - - l->debugfs_xve = debugfs_create_dir("xve", gpu_root); - if (IS_ERR_OR_NULL(l->debugfs_xve)) - goto fail; - - /* - * These are just debug nodes. If they fail to get made it's not worth - * worrying the higher level SW. - */ - debugfs_create_file("link_speed", S_IRUGO, - l->debugfs_xve, g, - &xve_link_speed_fops); - debugfs_create_file("available_speeds", S_IRUGO, - l->debugfs_xve, g, - &xve_available_speeds_fops); - debugfs_create_file("link_control_status", S_IRUGO, - l->debugfs_xve, g, - &xve_link_control_status_fops); - - err = 0; -fail: - return err; -#else - return err; -#endif -} - #if defined(CONFIG_PCI_MSI) void xve_rearm_msi_gp106(struct gk20a *g) { @@ -653,3 +490,8 @@ void xve_disable_shadow_rom_gp106(struct gk20a *g) g->ops.xve.xve_writel(g, xve_rom_ctrl_r(), xve_rom_ctrl_rom_shadow_disabled_f()); } + +u32 xve_get_link_control_status(struct gk20a *g) +{ + return g->ops.xve.xve_readl(g, xve_link_control_status_r()); +} diff --git a/drivers/gpu/nvgpu/gp106/xve_gp106.h b/drivers/gpu/nvgpu/gp106/xve_gp106.h index 37ead910..55192fc8 100644 --- a/drivers/gpu/nvgpu/gp106/xve_gp106.h +++ b/drivers/gpu/nvgpu/gp106/xve_gp106.h @@ -28,55 +28,6 @@ int gp106_init_xve_ops(struct gpu_ops *gops); */ #define GPU_XVE_TIMEOUT_MS 500 -/* - * For the available speeds bitmap. - */ -#define GPU_XVE_SPEED_2P5 (1 << 0) -#define GPU_XVE_SPEED_5P0 (1 << 1) -#define GPU_XVE_SPEED_8P0 (1 << 2) -#define GPU_XVE_NR_SPEEDS 3 - -#define GPU_XVE_SPEED_MASK (GPU_XVE_SPEED_2P5 | \ - GPU_XVE_SPEED_5P0 | \ - GPU_XVE_SPEED_8P0) - -/* - * The HW uses a 2 bit field where speed is defined by a number: - * - * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_2P5 = 1 - * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_5P0 = 2 - * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_8P0 = 3 - * - * This isn't ideal for a bitmap with available speeds. So the external - * APIs think about speeds as a bit in a bitmap and this function converts - * from those bits to the actual HW speed setting. - * - * @speed_bit must have only 1 bit set and must be one of the 3 available - * HW speeds. Not all chips support all speeds so use available_speeds() to - * determine what a given chip supports. - */ -static inline u32 xve_speed_to_hw_speed_setting(u32 speed_bit) -{ - if (!speed_bit || - !is_power_of_2(speed_bit) || - !(speed_bit & GPU_XVE_SPEED_MASK)) - return -EINVAL; - - return ilog2(speed_bit) + 1; -} - -static inline const char *xve_speed_to_str(u32 speed) -{ - if (!speed || !is_power_of_2(speed) || - !(speed & GPU_XVE_SPEED_MASK)) - return "Unknown ???"; - - return speed & GPU_XVE_SPEED_2P5 ? "Gen1" : - speed & GPU_XVE_SPEED_5P0 ? "Gen2" : - speed & GPU_XVE_SPEED_8P0 ? "Gen3" : - "Unknown ???"; -} - /* * Debugging for the speed change. */ @@ -104,7 +55,7 @@ int xve_get_speed_gp106(struct gk20a *g, u32 *xve_link_speed); void xve_disable_aspm_gp106(struct gk20a *g); int xve_set_speed_gp106(struct gk20a *g, u32 next_link_speed); void xve_available_speeds_gp106(struct gk20a *g, u32 *speed_mask); -int xve_sw_init_gp106(struct gk20a *g); +u32 xve_get_link_control_status(struct gk20a *g); #if defined(CONFIG_PCI_MSI) void xve_rearm_msi_gp106(struct gk20a *g); #endif diff --git a/drivers/gpu/nvgpu/include/nvgpu/xve.h b/drivers/gpu/nvgpu/include/nvgpu/xve.h new file mode 100644 index 00000000..ee599300 --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/xve.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * 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. + */ +#ifndef __NVGPU_XVE_H__ +#define __NVGPU_XVE_H__ + +#include +#include + +/* + * For the available speeds bitmap. + */ +#define GPU_XVE_SPEED_2P5 (1 << 0) +#define GPU_XVE_SPEED_5P0 (1 << 1) +#define GPU_XVE_SPEED_8P0 (1 << 2) +#define GPU_XVE_NR_SPEEDS 3 + +#define GPU_XVE_SPEED_MASK (GPU_XVE_SPEED_2P5 | \ + GPU_XVE_SPEED_5P0 | \ + GPU_XVE_SPEED_8P0) + +/* + * The HW uses a 2 bit field where speed is defined by a number: + * + * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_2P5 = 1 + * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_5P0 = 2 + * NV_XVE_LINK_CONTROL_STATUS_LINK_SPEED_8P0 = 3 + * + * This isn't ideal for a bitmap with available speeds. So the external + * APIs think about speeds as a bit in a bitmap and this function converts + * from those bits to the actual HW speed setting. + * + * @speed_bit must have only 1 bit set and must be one of the 3 available + * HW speeds. Not all chips support all speeds so use available_speeds() to + * determine what a given chip supports. + */ +static inline const char *xve_speed_to_str(u32 speed) +{ + if (!speed || !is_power_of_2(speed) || + !(speed & GPU_XVE_SPEED_MASK)) + return "Unknown ???"; + + return speed & GPU_XVE_SPEED_2P5 ? "Gen1" : + speed & GPU_XVE_SPEED_5P0 ? "Gen2" : + speed & GPU_XVE_SPEED_8P0 ? "Gen3" : + "Unknown ???"; +} + +#endif -- cgit v1.2.2