From a88e58cc9d2c4b9f852716240b3cabc9449d8679 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Thu, 23 Jul 2015 15:10:42 -0700 Subject: gpu: nvgpu: vgpu: add t210 gm20b support - add hal initializaiton - create folders vgpu/gk20a and vgpu/gm20b for specific code Bug 1653185 Change-Id: If94d45e22a1d73d2e4916673736cc29751be4e40 Signed-off-by: Richard Zhao Reviewed-on: http://git-master/r/774148 GVS: Gerrit_Virtual_Submit Reviewed-by: Aingara Paramakuru Reviewed-by: Ken Adams --- drivers/gpu/nvgpu/Makefile | 6 ++- drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.c | 50 ++++++++++++++++++++ drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.h | 21 +++++++++ drivers/gpu/nvgpu/vgpu/gk20a/vgpu_hal_gk20a.c | 29 ++++++++++++ drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.c | 42 +++++++++++++++++ drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.h | 21 +++++++++ drivers/gpu/nvgpu/vgpu/gm20b/vgpu_hal_gm20b.c | 29 ++++++++++++ drivers/gpu/nvgpu/vgpu/gr_vgpu.c | 68 +++++++++++++++++---------- drivers/gpu/nvgpu/vgpu/ltc_vgpu.c | 36 ++++++++++++-- drivers/gpu/nvgpu/vgpu/mm_vgpu.c | 1 + drivers/gpu/nvgpu/vgpu/vgpu.c | 31 ++++++++---- drivers/gpu/nvgpu/vgpu/vgpu.h | 4 ++ 12 files changed, 300 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.c create mode 100644 drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.h create mode 100644 drivers/gpu/nvgpu/vgpu/gk20a/vgpu_hal_gk20a.c create mode 100644 drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.c create mode 100644 drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.h create mode 100644 drivers/gpu/nvgpu/vgpu/gm20b/vgpu_hal_gm20b.c (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 4ae636fa..ee2096d9 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -74,7 +74,11 @@ nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \ vgpu/ce2_vgpu.o \ vgpu/mm_vgpu.o \ vgpu/debug_vgpu.o \ - vgpu/vgpu.o + vgpu/vgpu.o \ + vgpu/gk20a/vgpu_hal_gk20a.o \ + vgpu/gk20a/vgpu_gr_gk20a.o \ + vgpu/gm20b/vgpu_hal_gm20b.o \ + vgpu/gm20b/vgpu_gr_gm20b.o nvgpu-$(CONFIG_TEGRA_CLK_FRAMEWORK) += \ gm20b/clk_gm20b.o \ diff --git a/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.c b/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.c new file mode 100644 index 00000000..8d32773e --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include + +#include "gk20a/hw_gr_gk20a.h" +#include "gk20a/gk20a.h" +#include "vgpu/vgpu.h" + +static void vgpu_gk20a_detect_sm_arch(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + u32 v = 0, raw_version, version = 0; + + gk20a_dbg_fn(""); + + if (vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_GPC0_TPC0_SM_ARCH, &v)) + gk20a_err(dev_from_gk20a(g), "failed to retrieve SM arch"); + + raw_version = gr_gpc0_tpc0_sm_arch_spa_version_v(v); + + if (raw_version == gr_gpc0_tpc0_sm_arch_spa_version_smkepler_lp_v()) + version = 0x320; /* SM 3.2 */ + else + gk20a_err(dev_from_gk20a(g), "Unknown SM version 0x%x", + raw_version); + + /* on Kepler, SM version == SPA version */ + g->gpu_characteristics.sm_arch_spa_version = version; + g->gpu_characteristics.sm_arch_sm_version = version; + + g->gpu_characteristics.sm_arch_warp_count = + gr_gpc0_tpc0_sm_arch_warp_count_v(v); +} + +void vgpu_gk20a_init_gr_ops(struct gpu_ops *gops) +{ + gops->gr.detect_sm_arch = vgpu_gk20a_detect_sm_arch; +} diff --git a/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.h b/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.h new file mode 100644 index 00000000..bb80aff8 --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_gr_gk20a.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2015, 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 __VGPU_GR_GK20A_H__ +#define __VGPU_GR_GK20A_H__ + +#include "gk20a/gk20a.h" + +void vgpu_gk20a_init_gr_ops(struct gpu_ops *gops); + +#endif diff --git a/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_hal_gk20a.c b/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_hal_gk20a.c new file mode 100644 index 00000000..aeeb2ad9 --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/gk20a/vgpu_hal_gk20a.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include "gk20a/hal_gk20a.h" +#include "vgpu/vgpu.h" +#include "vgpu_gr_gk20a.h" + +int vgpu_gk20a_init_hal(struct gk20a *g) +{ + int err; + + err = gk20a_init_hal(g); + if (err) + return err; + vgpu_init_hal_common(g); + vgpu_gk20a_init_gr_ops(&g->ops); + + return 0; +} diff --git a/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.c b/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.c new file mode 100644 index 00000000..0ebecfe4 --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include + +#include "gm20b/hw_gr_gm20b.h" +#include "gk20a/gk20a.h" +#include "vgpu/vgpu.h" + +static void vgpu_gm20b_detect_sm_arch(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + u32 v = 0; + + gk20a_dbg_fn(""); + + if (vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_GPC0_TPC0_SM_ARCH, &v)) + gk20a_err(dev_from_gk20a(g), "failed to retrieve SM arch"); + + g->gpu_characteristics.sm_arch_spa_version = + gr_gpc0_tpc0_sm_arch_spa_version_v(v); + g->gpu_characteristics.sm_arch_sm_version = + gr_gpc0_tpc0_sm_arch_sm_version_v(v); + g->gpu_characteristics.sm_arch_warp_count = + gr_gpc0_tpc0_sm_arch_warp_count_v(v); +} + +void vgpu_gm20b_init_gr_ops(struct gpu_ops *gops) +{ + gops->gr.detect_sm_arch = vgpu_gm20b_detect_sm_arch; +} diff --git a/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.h b/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.h new file mode 100644 index 00000000..75dfebf7 --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_gr_gm20b.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2015, 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 __VGPU_GR_GM20B_H__ +#define __VGPU_GR_GM20B_H__ + +#include "gk20a/gk20a.h" + +void vgpu_gm20b_init_gr_ops(struct gpu_ops *gops); + +#endif diff --git a/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_hal_gm20b.c b/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_hal_gm20b.c new file mode 100644 index 00000000..c9cb0ade --- /dev/null +++ b/drivers/gpu/nvgpu/vgpu/gm20b/vgpu_hal_gm20b.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include "gm20b/hal_gm20b.h" +#include "vgpu/vgpu.h" +#include "vgpu_gr_gm20b.h" + +int vgpu_gm20b_init_hal(struct gk20a *g) +{ + int err; + + err = gm20b_init_hal(g); + if (err) + return err; + vgpu_init_hal_common(g); + vgpu_gm20b_init_gr_ops(&g->ops); + + return 0; +} diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c index 99754cae..60a8f6c5 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c @@ -601,36 +601,18 @@ static int vgpu_gr_get_zcull_info(struct gk20a *g, struct gr_gk20a *gr, return 0; } -static void vgpu_gr_detect_sm_arch(struct gk20a *g) +static u32 vgpu_gr_get_gpc_tpc_mask(struct gk20a *g, u32 gpc_index) { struct gk20a_platform *platform = gk20a_get_platform(g->dev); - u32 v = 0, raw_version, version = 0; + u32 data; - gk20a_dbg_fn(""); + WARN_ON(gpc_index > 0); if (vgpu_get_attribute(platform->virt_handle, - TEGRA_VGPU_ATTRIB_GPC0_TPC0_SM_ARCH, &v)) - gk20a_err(dev_from_gk20a(g), "failed to retrieve SM arch"); - - raw_version = gr_gpc0_tpc0_sm_arch_spa_version_v(v); - if (raw_version == gr_gpc0_tpc0_sm_arch_spa_version_smkepler_lp_v()) - version = 0x320; /* SM 3.2 */ - else - gk20a_err(dev_from_gk20a(g), "Unknown SM version 0x%x", - raw_version); - - /* on Kepler, SM version == SPA version */ - g->gpu_characteristics.sm_arch_spa_version = version; - g->gpu_characteristics.sm_arch_sm_version = version; - - g->gpu_characteristics.sm_arch_warp_count = - gr_gpc0_tpc0_sm_arch_warp_count_v(v); -} + TEGRA_VGPU_ATTRIB_GPC0_TPC_MASK, &data)) + gk20a_err(dev_from_gk20a(g), "failed to retrieve gpc0_tpc_mask"); -static u32 vgpu_gr_get_gpc_tpc_mask(struct gk20a *g, u32 gpc_index) -{ - /* One TPC for gk20a */ - return 0x1; + return data; } static u32 vgpu_gr_get_max_fbps_count(struct gk20a *g) @@ -661,6 +643,40 @@ static u32 vgpu_gr_get_fbp_en_mask(struct gk20a *g) return fbp_en_mask; } +static u32 vgpu_gr_get_max_ltc_per_fbp(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + u32 val = 0; + + gk20a_dbg_fn(""); + + if (vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_MAX_LTC_PER_FBP, &val)) + gk20a_err(dev_from_gk20a(g), "failed to retrieve max ltc per fbp"); + + return val; +} + +static u32 vgpu_gr_get_max_lts_per_ltc(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + u32 val = 0; + + gk20a_dbg_fn(""); + + if (vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_MAX_LTS_PER_LTC, &val)) + gk20a_err(dev_from_gk20a(g), "failed to retrieve lts per ltc"); + + return val; +} + +static u32 *vgpu_gr_rop_l2_en_mask(struct gk20a *g) +{ + /* no one use it yet */ + return NULL; +} + static int vgpu_gr_add_zbc(struct gk20a *g, struct gr_gk20a *gr, struct zbc_entry *zbc_val) { @@ -875,10 +891,12 @@ void vgpu_init_gr_ops(struct gpu_ops *gops) gops->gr.free_obj_ctx = vgpu_gr_free_obj_ctx; gops->gr.bind_ctxsw_zcull = vgpu_gr_bind_ctxsw_zcull; gops->gr.get_zcull_info = vgpu_gr_get_zcull_info; - gops->gr.detect_sm_arch = vgpu_gr_detect_sm_arch; gops->gr.get_gpc_tpc_mask = vgpu_gr_get_gpc_tpc_mask; gops->gr.get_max_fbps_count = vgpu_gr_get_max_fbps_count; gops->gr.get_fbp_en_mask = vgpu_gr_get_fbp_en_mask; + gops->gr.get_max_ltc_per_fbp = vgpu_gr_get_max_ltc_per_fbp; + gops->gr.get_max_lts_per_ltc = vgpu_gr_get_max_lts_per_ltc; + gops->gr.get_rop_l2_en_mask = vgpu_gr_rop_l2_en_mask; gops->gr.zbc_set_table = vgpu_gr_add_zbc; gops->gr.zbc_query_table = vgpu_gr_query_zbc; } diff --git a/drivers/gpu/nvgpu/vgpu/ltc_vgpu.c b/drivers/gpu/nvgpu/vgpu/ltc_vgpu.c index 211e34b5..199e880b 100644 --- a/drivers/gpu/nvgpu/vgpu/ltc_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/ltc_vgpu.c @@ -1,7 +1,7 @@ /* * Virtualized GPU L2 * - * Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2015 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, @@ -24,7 +24,7 @@ static int vgpu_determine_L2_size_bytes(struct gk20a *g) if (vgpu_get_attribute(platform->virt_handle, TEGRA_VGPU_ATTRIB_L2_SIZE, &cache_size)) - dev_err(dev_from_gk20a(g), "unable to get L2 size"); + dev_err(dev_from_gk20a(g), "unable to get L2 size\n"); return cache_size; } @@ -33,11 +33,26 @@ static int vgpu_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr) { struct gk20a_platform *platform = gk20a_get_platform(g->dev); u32 max_comptag_lines = 0; + int err; gk20a_dbg_fn(""); - vgpu_get_attribute(platform->virt_handle, + err = vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_CACHELINE_SIZE, + &gr->cacheline_size); + err |= vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_COMPTAGS_PER_CACHELINE, + &gr->comptags_per_cacheline); + err |= vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_SLICES_PER_LTC, + &gr->slices_per_ltc); + err |= vgpu_get_attribute(platform->virt_handle, TEGRA_VGPU_ATTRIB_COMPTAG_LINES, &max_comptag_lines); + if (err) { + dev_err(dev_from_gk20a(g), "failed to get ctags atributes\n"); + return -ENXIO; + } + if (max_comptag_lines < 2) return -ENXIO; @@ -46,8 +61,23 @@ static int vgpu_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr) return 0; } +static void vgpu_ltc_init_fs_state(struct gk20a *g) +{ + struct gk20a_platform *platform = gk20a_get_platform(g->dev); + u32 ltc_count = 0; + int err; + + gk20a_dbg_fn(""); + + err = vgpu_get_attribute(platform->virt_handle, + TEGRA_VGPU_ATTRIB_LTC_COUNT, <c_count); + WARN_ON(err); + g->ltc_count = ltc_count; +} + void vgpu_init_ltc_ops(struct gpu_ops *gops) { gops->ltc.determine_L2_size_bytes = vgpu_determine_L2_size_bytes; gops->ltc.init_comptags = vgpu_ltc_init_comptags; + gops->ltc.init_fs_state = vgpu_ltc_init_fs_state; } diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c index 640111b5..c73037b6 100644 --- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c @@ -282,6 +282,7 @@ static int vgpu_vm_alloc_share(struct gk20a_as_share *as_share, msg.cmd = TEGRA_VGPU_CMD_AS_ALLOC_SHARE; msg.handle = platform->virt_handle; p->size = vm->va_limit; + p->big_page_size = vm->big_page_size; err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); if (err || msg.ret) { err = -ENOMEM; diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index b16fe47c..b2c08d68 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c @@ -22,6 +22,8 @@ #include "gk20a/hal_gk20a.h" #include "gk20a/hw_mc_gk20a.h" +#include "gm20b/hal_gm20b.h" + static inline int vgpu_comm_init(struct platform_device *pdev) { size_t queue_sizes[] = { TEGRA_VGPU_QUEUE_SIZES }; @@ -243,27 +245,38 @@ static void vgpu_detect_chip(struct gk20a *g) g->gpu_characteristics.rev); } +void vgpu_init_hal_common(struct gk20a *g) +{ + struct gpu_ops *gops = &g->ops; + + vgpu_init_fifo_ops(gops); + vgpu_init_gr_ops(gops); + vgpu_init_ltc_ops(gops); + vgpu_init_mm_ops(gops); + vgpu_init_debug_ops(gops); +} + static int vgpu_init_hal(struct gk20a *g) { u32 ver = g->gpu_characteristics.arch + g->gpu_characteristics.impl; + int err; switch (ver) { case GK20A_GPUID_GK20A: gk20a_dbg_info("gk20a detected"); - /* init gk20a ops then override with virt extensions */ - gk20a_init_hal(g); - vgpu_init_fifo_ops(&g->ops); - vgpu_init_gr_ops(&g->ops); - vgpu_init_ltc_ops(&g->ops); - vgpu_init_mm_ops(&g->ops); - vgpu_init_debug_ops(&g->ops); + err = vgpu_gk20a_init_hal(g); + break; + case GK20A_GPUID_GM20B: + gk20a_dbg_info("gm20b detected"); + err = vgpu_gm20b_init_hal(g); break; default: gk20a_err(&g->dev->dev, "no support for %x", ver); - return -ENODEV; + err = -ENODEV; + break; } - return 0; + return err; } int vgpu_pm_finalize_poweron(struct device *dev) diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.h b/drivers/gpu/nvgpu/vgpu/vgpu.h index d577f32e..f1590593 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.h +++ b/drivers/gpu/nvgpu/vgpu/vgpu.h @@ -46,6 +46,10 @@ int vgpu_init_fifo_support(struct gk20a *g); int vgpu_get_attribute(u64 handle, u32 attrib, u32 *value); int vgpu_comm_sendrecv(struct tegra_vgpu_cmd_msg *msg, size_t size_in, size_t size_out); + +void vgpu_init_hal_common(struct gk20a *g); +int vgpu_gk20a_init_hal(struct gk20a *g); +int vgpu_gm20b_init_hal(struct gk20a *g); #else static inline int vgpu_pm_prepare_poweroff(struct device *dev) { -- cgit v1.2.2