diff options
author | Sami Kiminki <skiminki@nvidia.com> | 2013-12-03 22:36:10 +0200 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2014-01-08 03:52:49 -0800 |
commit | 0b9ceca5a06d07cc8d281a92b76ebef8d4da0c92 (patch) | |
tree | dbd786c88a2e802d7be3bb8bf0bb5018e9d11a20 /drivers | |
parent | 674db82ac5d039342d67e9fadd161a428a094fd9 (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.c | 31 | ||||
-rw-r--r-- | drivers/video/tegra/host/gk20a/gk20a.c | 87 | ||||
-rw-r--r-- | drivers/video/tegra/host/gk20a/gk20a.h | 16 | ||||
-rw-r--r-- | drivers/video/tegra/host/gk20a/hw_ltc_gk20a.h | 26 | ||||
-rw-r--r-- | drivers/video/tegra/host/gk20a/hw_mc_gk20a.h | 22 |
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; |