summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSami Kiminki <skiminki@nvidia.com>2013-12-03 22:36:10 +0200
committerTerje Bergstrom <tbergstrom@nvidia.com>2014-01-08 03:52:49 -0800
commit0b9ceca5a06d07cc8d281a92b76ebef8d4da0c92 (patch)
treedbd786c88a2e802d7be3bb8bf0bb5018e9d11a20 /drivers
parent674db82ac5d039342d67e9fadd161a428a094fd9 (diff)
video: tegra: host: gk20a: GPU characteristics
This adds new IOCTL that provides information for the userspace for GPU characterization. Specifically, the following items are provided: GPU arch/impl/rev, number of GPCs, L2 cache size, on-board video memory size, num of tpc:s per gpc, and bus type. The primary user of the new IOCTL will be rmapi_tegra. Bug 1392902 Signed-off-by: Sami Kiminki <skiminki@nvidia.com> Change-Id: Ia7c25c83c8a07821ec60be3edd018c6e0894df0f Reviewed-on: http://git-master/r/346379 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Sami Kiminki <skiminki@nvidia.com> Tested-by: Sami Kiminki <skiminki@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/gk20a/ctrl_gk20a.c31
-rw-r--r--drivers/video/tegra/host/gk20a/gk20a.c87
-rw-r--r--drivers/video/tegra/host/gk20a/gk20a.h16
-rw-r--r--drivers/video/tegra/host/gk20a/hw_ltc_gk20a.h26
-rw-r--r--drivers/video/tegra/host/gk20a/hw_mc_gk20a.h22
5 files changed, 178 insertions, 4 deletions
diff --git a/drivers/video/tegra/host/gk20a/ctrl_gk20a.c b/drivers/video/tegra/host/gk20a/ctrl_gk20a.c
index 189781957c5d..a4b1ed873ff9 100644
--- a/drivers/video/tegra/host/gk20a/ctrl_gk20a.c
+++ b/drivers/video/tegra/host/gk20a/ctrl_gk20a.c
@@ -63,6 +63,31 @@ int gk20a_ctrl_dev_release(struct inode *inode, struct file *filp)
return 0;
}
+static long
+gk20a_ctrl_ioctl_gpu_characteristics(
+ struct gk20a *g,
+ struct nvhost_gpu_get_characteristics *request)
+{
+ struct nvhost_gpu_characteristics *pgpu = &g->gpu_characteristics;
+ long err = 0;
+
+ if (request->gpu_characteristics_buf_size > 0) {
+ size_t write_size = sizeof(*pgpu);
+
+ if (write_size > request->gpu_characteristics_buf_size)
+ write_size = request->gpu_characteristics_buf_size;
+
+ err = copy_to_user((void __user *)(uintptr_t)
+ request->gpu_characteristics_buf_addr,
+ pgpu, write_size);
+ }
+
+ if (err == 0)
+ request->gpu_characteristics_buf_size = sizeof(*pgpu);
+
+ return err;
+}
+
long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct platform_device *dev = filp->private_data;
@@ -201,6 +226,12 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg
if (zbc_tbl)
kfree(zbc_tbl);
break;
+
+ case NVHOST_GPU_IOCTL_GET_CHARACTERISTICS:
+ err = gk20a_ctrl_ioctl_gpu_characteristics(
+ g, (struct nvhost_gpu_get_characteristics *)buf);
+ break;
+
default:
nvhost_err(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd);
err = -ENOTTY;
diff --git a/drivers/video/tegra/host/gk20a/gk20a.c b/drivers/video/tegra/host/gk20a/gk20a.c
index dc776d1624c3..319e2e29be92 100644
--- a/drivers/video/tegra/host/gk20a/gk20a.c
+++ b/drivers/video/tegra/host/gk20a/gk20a.c
@@ -3,7 +3,7 @@
*
* GK20A Graphics
*
- * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2014, 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,
@@ -52,6 +52,7 @@
#include "hw_bus_gk20a.h"
#include "hw_sim_gk20a.h"
#include "hw_top_gk20a.h"
+#include "hw_ltc_gk20a.h"
#include "gk20a_scale.h"
#include "gr3d/pod_scaling.h"
#include "dbg_gpu_gk20a.h"
@@ -904,6 +905,12 @@ int nvhost_gk20a_finalize_poweron(struct platform_device *dev)
goto done;
}
+ err = gk20a_init_gpu_characteristics(g);
+ if (err) {
+ nvhost_err(&dev->dev, "failed to init gk20a gpu characteristics");
+ goto done;
+ }
+
gk20a_channel_resume(g);
set_user_nice(current, nice_value);
@@ -1216,5 +1223,83 @@ void gk20a_reset(struct gk20a *g, u32 units)
gk20a_enable(g, units);
}
+static u32 gk20a_determine_L2_size_bytes(struct gk20a *g)
+{
+ const u32 gpuid = GK20A_GPUID(g->gpu_characteristics.arch,
+ g->gpu_characteristics.impl);
+ u32 lts_per_ltc;
+ u32 ways;
+ u32 sets;
+ u32 bytes_per_line;
+ u32 active_ltcs;
+ u32 cache_size;
+
+ u32 tmp;
+ u32 active_sets_value;
+
+ tmp = gk20a_readl(g, ltc_ltc0_lts0_tstg_cfg1_r());
+ ways = hweight32(ltc_ltc0_lts0_tstg_cfg1_active_ways_v(tmp));
+
+ active_sets_value = ltc_ltc0_lts0_tstg_cfg1_active_sets_v(tmp);
+ if (active_sets_value == ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v()) {
+ sets = 64;
+ } else if (active_sets_value ==
+ ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v()) {
+ sets = 32;
+ } else if (active_sets_value ==
+ ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v()) {
+ sets = 16;
+ } else {
+ dev_err(dev_from_gk20a(g),
+ "Unknown constant %u for active sets",
+ (unsigned)active_sets_value);
+ sets = 0;
+ }
+
+ active_ltcs = g->gr.num_fbps;
+
+ /* chip-specific values */
+ switch (gpuid) {
+ case GK20A_GPUID_GK20A:
+ lts_per_ltc = 1;
+ bytes_per_line = 128;
+ break;
+
+ default:
+ dev_err(dev_from_gk20a(g), "Unknown GPU id 0x%02x\n",
+ (unsigned)gpuid);
+ lts_per_ltc = 0;
+ bytes_per_line = 0;
+ }
+
+ cache_size = active_ltcs * lts_per_ltc * ways * sets * bytes_per_line;
+
+ return cache_size;
+}
+
+int gk20a_init_gpu_characteristics(struct gk20a *g)
+{
+ struct nvhost_gpu_characteristics *gpu = &g->gpu_characteristics;
+
+ u32 mc_boot_0_value;
+ mc_boot_0_value = gk20a_readl(g, mc_boot_0_r());
+ gpu->arch = mc_boot_0_architecture_v(mc_boot_0_value) <<
+ NVHOST_GPU_ARCHITECTURE_SHIFT;
+ gpu->impl = mc_boot_0_implementation_v(mc_boot_0_value);
+ gpu->rev =
+ (mc_boot_0_major_revision_v(mc_boot_0_value) << 4) |
+ mc_boot_0_minor_revision_v(mc_boot_0_value);
+
+ gpu->L2_cache_size = gk20a_determine_L2_size_bytes(g);
+ gpu->on_board_video_memory_size = 0; /* integrated GPU */
+
+ gpu->num_gpc = g->gr.gpc_count;
+ gpu->num_tpc_per_gpc = g->gr.max_tpc_per_gpc_count;
+
+ gpu->bus_type = NVHOST_GPU_BUS_TYPE_AXI; /* always AXI for now */
+
+ return 0;
+}
+
module_init(gk20a_init);
module_exit(gk20a_exit);
diff --git a/drivers/video/tegra/host/gk20a/gk20a.h b/drivers/video/tegra/host/gk20a/gk20a.h
index f18562fd0f5b..acef9038c4cb 100644
--- a/drivers/video/tegra/host/gk20a/gk20a.h
+++ b/drivers/video/tegra/host/gk20a/gk20a.h
@@ -3,7 +3,7 @@
*
* GK20A Graphics
*
- * Copyright (c) 2011-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2014, 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,
@@ -30,6 +30,7 @@ struct sim_gk20a;
#include <linux/tegra-soc.h>
#include <linux/spinlock.h>
+#include <linux/nvhost_gpu_ioctl.h>
#include "clk_gk20a.h"
#include "fifo_gk20a.h"
#include "gr_gk20a.h"
@@ -112,6 +113,8 @@ struct gk20a {
u32 pg_gating_cnt;
spinlock_t mc_enable_lock;
+
+ struct nvhost_gpu_characteristics gpu_characteristics;
};
static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g)
@@ -280,4 +283,15 @@ void gk20a_disable(struct gk20a *g, u32 units);
void gk20a_enable(struct gk20a *g, u32 units);
void gk20a_reset(struct gk20a *g, u32 units);
+#define NVHOST_GPU_ARCHITECTURE_SHIFT 4
+
+/* constructs unique and compact GPUID from nvhost_gpu_characteristics
+ * arch/impl fields */
+#define GK20A_GPUID(arch, impl) ((u32) ((arch) | (impl)))
+
+#define GK20A_GPUID_GK20A \
+ GK20A_GPUID(NVHOST_GPU_ARCH_GK100, NVHOST_GPU_IMPL_GK20A)
+
+int gk20a_init_gpu_characteristics(struct gk20a *g);
+
#endif /* _NVHOST_GK20A_H_ */
diff --git a/drivers/video/tegra/host/gk20a/hw_ltc_gk20a.h b/drivers/video/tegra/host/gk20a/hw_ltc_gk20a.h
index 595676ef26e2..65221b59909a 100644
--- a/drivers/video/tegra/host/gk20a/hw_ltc_gk20a.h
+++ b/drivers/video/tegra/host/gk20a/hw_ltc_gk20a.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2014, 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,
@@ -54,6 +54,30 @@ static inline u32 ltc_ltcs_lts0_cbc_ctrl1_r(void)
{
return 0x001410c8;
}
+static inline u32 ltc_ltc0_lts0_tstg_cfg1_r(void)
+{
+ return 0x00141104;
+}
+static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_ways_v(u32 r)
+{
+ return (r >> 0) & 0xffff;
+}
+static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_v(u32 r)
+{
+ return (r >> 16) & 0x3;
+}
+static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_all_v(void)
+{
+ return 0x00000000;
+}
+static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_half_v(void)
+{
+ return 0x00000001;
+}
+static inline u32 ltc_ltc0_lts0_tstg_cfg1_active_sets_quarter_v(void)
+{
+ return 0x00000002;
+}
static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void)
{
return 0x0017e8c8;
diff --git a/drivers/video/tegra/host/gk20a/hw_mc_gk20a.h b/drivers/video/tegra/host/gk20a/hw_mc_gk20a.h
index 646312871814..1692bb5430cb 100644
--- a/drivers/video/tegra/host/gk20a/hw_mc_gk20a.h
+++ b/drivers/video/tegra/host/gk20a/hw_mc_gk20a.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2012-2014, 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,
@@ -50,6 +50,26 @@
#ifndef _hw_mc_gk20a_h_
#define _hw_mc_gk20a_h_
+static inline u32 mc_boot_0_r(void)
+{
+ return 0x00000000;
+}
+static inline u32 mc_boot_0_architecture_v(u32 r)
+{
+ return (r >> 24) & 0x1f;
+}
+static inline u32 mc_boot_0_implementation_v(u32 r)
+{
+ return (r >> 20) & 0xf;
+}
+static inline u32 mc_boot_0_major_revision_v(u32 r)
+{
+ return (r >> 4) & 0xf;
+}
+static inline u32 mc_boot_0_minor_revision_v(u32 r)
+{
+ return (r >> 0) & 0xf;
+}
static inline u32 mc_intr_0_r(void)
{
return 0x00000100;