From 9454529abe0ac42d15df01e36898cd2c840de9c8 Mon Sep 17 00:00:00 2001 From: Lakshmanan M Date: Thu, 2 Jun 2016 09:39:52 +0530 Subject: gpu: nvgpu: Add multiple engine and runlist support This CL covers the following modification, 1) Added multiple engine_info support 2) Added multiple runlist_info support 3) Initial changes for ASYNC CE support 4) Added ASYNC CE interrupt support for Pascal GPU series 5) Removed hard coded engine_id logic and made generic way 6) Code cleanup for readability JIRA DNVGPU-26 Change-Id: Ibf46a89a5308c82f01040ffa979c5014b3206f8e Signed-off-by: Lakshmanan M Reviewed-on: http://git-master/r/1156022 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/Makefile | 2 +- drivers/gpu/nvgpu/gp106/hal_gp106.c | 7 ++- drivers/gpu/nvgpu/gp106/hw_ce2_gp106.h | 81 -------------------------------- drivers/gpu/nvgpu/gp106/hw_ce_gp106.h | 81 ++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gp106/hw_proj_gp106.h | 4 ++ drivers/gpu/nvgpu/gp106/hw_top_gp106.h | 8 ++++ drivers/gpu/nvgpu/gp10b/ce2_gp10b.c | 83 --------------------------------- drivers/gpu/nvgpu/gp10b/ce2_gp10b.h | 29 ------------ drivers/gpu/nvgpu/gp10b/ce_gp10b.c | 82 ++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gp10b/ce_gp10b.h | 26 +++++++++++ drivers/gpu/nvgpu/gp10b/fifo_gp10b.c | 9 ++-- drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 5 +- drivers/gpu/nvgpu/gp10b/hal_gp10b.c | 7 ++- drivers/gpu/nvgpu/gp10b/hw_ce2_gp10b.h | 81 -------------------------------- drivers/gpu/nvgpu/gp10b/hw_ce_gp10b.h | 81 ++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gp10b/hw_proj_gp10b.h | 4 ++ drivers/gpu/nvgpu/gp10b/mc_gp10b.c | 59 ++++++++++++++++++----- drivers/gpu/nvgpu/gp10b/therm_gp10b.c | 9 ++-- 18 files changed, 360 insertions(+), 298 deletions(-) delete mode 100644 drivers/gpu/nvgpu/gp106/hw_ce2_gp106.h create mode 100644 drivers/gpu/nvgpu/gp106/hw_ce_gp106.h delete mode 100644 drivers/gpu/nvgpu/gp10b/ce2_gp10b.c delete mode 100644 drivers/gpu/nvgpu/gp10b/ce2_gp10b.h create mode 100644 drivers/gpu/nvgpu/gp10b/ce_gp10b.c create mode 100644 drivers/gpu/nvgpu/gp10b/ce_gp10b.h delete mode 100644 drivers/gpu/nvgpu/gp10b/hw_ce2_gp10b.h create mode 100644 drivers/gpu/nvgpu/gp10b/hw_ce_gp10b.h diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 20ba4b46..89b9b13a 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -3,7 +3,7 @@ nvgpu-t18x := ../../../../nvgpu-t18x/drivers/gpu/nvgpu nvgpu-y += \ $(nvgpu-t18x)/gp10b/gr_gp10b.o \ $(nvgpu-t18x)/gp10b/gr_ctx_gp10b.o \ - $(nvgpu-t18x)/gp10b/ce2_gp10b.o \ + $(nvgpu-t18x)/gp10b/ce_gp10b.o \ $(nvgpu-t18x)/gp10b/mc_gp10b.o \ $(nvgpu-t18x)/gp10b/fifo_gp10b.o \ $(nvgpu-t18x)/gp10b/ltc_gp10b.o \ diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index 5c9e012d..1dd16139 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c @@ -24,7 +24,7 @@ #include "gp10b/mc_gp10b.h" #include "gp10b/ltc_gp10b.h" #include "gp10b/mm_gp10b.h" -#include "gp10b/ce2_gp10b.h" +#include "gp10b/ce_gp10b.h" #include "gp10b/fb_gp10b.h" #include "gp10b/fifo_gp10b.h" #include "gp10b/gp10b_gating_reglist.h" @@ -149,6 +149,9 @@ static int gp106_get_litter_value(struct gk20a *g, case GPU_LIT_ROP_SHARED_BASE: ret = proj_rop_shared_base_v(); break; + case GPU_LIT_HOST_NUM_ENGINES: + ret = proj_host_num_engines_v(); + break; case GPU_LIT_HOST_NUM_PBDMA: ret = proj_host_num_pbdma_v(); break; @@ -189,7 +192,7 @@ int gp106_init_hal(struct gk20a *g) gp10b_init_ltc(gops); gp10b_init_fb(gops); gp10b_init_fifo(gops); - gp10b_init_ce2(gops); + gp10b_init_ce(gops); gp106_init_gr_ctx(gops); gp10b_init_mm(gops); gp106_init_pmu_ops(gops); diff --git a/drivers/gpu/nvgpu/gp106/hw_ce2_gp106.h b/drivers/gpu/nvgpu/gp106/hw_ce2_gp106.h deleted file mode 100644 index d56b930b..00000000 --- a/drivers/gpu/nvgpu/gp106/hw_ce2_gp106.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 . - */ -/* - * Function naming determines intended use: - * - * _r(void) : Returns the offset for register . - * - * _o(void) : Returns the offset for element . - * - * _w(void) : Returns the word offset for word (4 byte) element . - * - * __s(void) : Returns size of field of register in bits. - * - * __f(u32 v) : Returns a value based on 'v' which has been shifted - * and masked to place it at field of register . This value - * can be |'d with others to produce a full register value for - * register . - * - * __m(void) : Returns a mask for field of register . This - * value can be ~'d and then &'d to clear the value of field for - * register . - * - * ___f(void) : Returns the constant value after being shifted - * to place it at field of register . This value can be |'d - * with others to produce a full register value for . - * - * __v(u32 r) : Returns the value of field from a full register - * value 'r' after being shifted to place its LSB at bit 0. - * This value is suitable for direct comparison with other unshifted - * values appropriate for use in field of register . - * - * ___v(void) : Returns the constant value for defined for - * field of register . This value is suitable for direct - * comparison with unshifted values appropriate for use in field - * of register . - */ -#ifndef _hw_ce2_gp106_h_ -#define _hw_ce2_gp106_h_ - -static inline u32 ce2_intr_status_r(u32 i) -{ - return 0x00104410 + i*128; -} -static inline u32 ce2_intr_status_blockpipe_pending_f(void) -{ - return 0x1; -} -static inline u32 ce2_intr_status_blockpipe_reset_f(void) -{ - return 0x1; -} -static inline u32 ce2_intr_status_nonblockpipe_pending_f(void) -{ - return 0x2; -} -static inline u32 ce2_intr_status_nonblockpipe_reset_f(void) -{ - return 0x2; -} -static inline u32 ce2_intr_status_launcherr_pending_f(void) -{ - return 0x4; -} -static inline u32 ce2_intr_status_launcherr_reset_f(void) -{ - return 0x4; -} -#endif diff --git a/drivers/gpu/nvgpu/gp106/hw_ce_gp106.h b/drivers/gpu/nvgpu/gp106/hw_ce_gp106.h new file mode 100644 index 00000000..36311136 --- /dev/null +++ b/drivers/gpu/nvgpu/gp106/hw_ce_gp106.h @@ -0,0 +1,81 @@ +/* + * 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 . + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce_gp106_h_ +#define _hw_ce_gp106_h_ + +static inline u32 ce_intr_status_r(u32 i) +{ + return 0x00104410 + i*128; +} +static inline u32 ce_intr_status_blockpipe_pending_f(void) +{ + return 0x1; +} +static inline u32 ce_intr_status_blockpipe_reset_f(void) +{ + return 0x1; +} +static inline u32 ce_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2; +} +static inline u32 ce_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2; +} +static inline u32 ce_intr_status_launcherr_pending_f(void) +{ + return 0x4; +} +static inline u32 ce_intr_status_launcherr_reset_f(void) +{ + return 0x4; +} +#endif diff --git a/drivers/gpu/nvgpu/gp106/hw_proj_gp106.h b/drivers/gpu/nvgpu/gp106/hw_proj_gp106.h index 0b4b86b1..01e835ec 100644 --- a/drivers/gpu/nvgpu/gp106/hw_proj_gp106.h +++ b/drivers/gpu/nvgpu/gp106/hw_proj_gp106.h @@ -106,6 +106,10 @@ static inline u32 proj_tpc_in_gpc_shared_base_v(void) { return 0x00001800; } +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000009; +} static inline u32 proj_host_num_pbdma_v(void) { return 0x00000004; diff --git a/drivers/gpu/nvgpu/gp106/hw_top_gp106.h b/drivers/gpu/nvgpu/gp106/hw_top_gp106.h index bef6b804..e833c152 100644 --- a/drivers/gpu/nvgpu/gp106/hw_top_gp106.h +++ b/drivers/gpu/nvgpu/gp106/hw_top_gp106.h @@ -146,6 +146,14 @@ static inline u32 top_device_info_type_enum_copy0_f(void) { return 0x4; } +static inline u32 top_device_info_type_enum_lce_v(void) +{ + return 0x00000013; +} +static inline u32 top_device_info_type_enum_lce_f(void) +{ + return 0x4c; +} static inline u32 top_device_info_entry_v(u32 r) { return (r >> 0) & 0x3; diff --git a/drivers/gpu/nvgpu/gp10b/ce2_gp10b.c b/drivers/gpu/nvgpu/gp10b/ce2_gp10b.c deleted file mode 100644 index 4cb13f3b..00000000 --- a/drivers/gpu/nvgpu/gp10b/ce2_gp10b.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * GK20A Graphics Copy Engine (gr host) - * - * Copyright (c) 2011-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. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "gk20a/gk20a.h" /* FERMI and MAXWELL classes defined here */ -#include "hw_ce2_gp10b.h" -#include "ce2_gp10b.h" - -static u32 ce2_nonblockpipe_isr(struct gk20a *g, u32 fifo_intr) -{ - gk20a_dbg(gpu_dbg_intr, "ce2 non-blocking pipe interrupt\n"); - - /* wake theads waiting in this channel */ - gk20a_channel_semaphore_wakeup(g, true); - return ce2_intr_status_nonblockpipe_pending_f(); -} - -static u32 ce2_blockpipe_isr(struct gk20a *g, u32 fifo_intr) -{ - gk20a_dbg(gpu_dbg_intr, "ce2 blocking pipe interrupt\n"); - - return ce2_intr_status_blockpipe_pending_f(); -} - -static u32 ce2_launcherr_isr(struct gk20a *g, u32 fifo_intr) -{ - gk20a_dbg(gpu_dbg_intr, "ce2 launch error interrupt\n"); - - return ce2_intr_status_launcherr_pending_f(); -} - -static void gp10b_ce2_isr(struct gk20a *g) -{ - u32 ce2_intr = gk20a_readl(g, ce2_intr_status_r(0)); - u32 clear_intr = 0; - - gk20a_dbg(gpu_dbg_intr, "ce2 isr %08x\n", ce2_intr); - - /* clear blocking interrupts: they exibit broken behavior */ - if (ce2_intr & ce2_intr_status_blockpipe_pending_f()) - clear_intr |= ce2_blockpipe_isr(g, ce2_intr); - - if (ce2_intr & ce2_intr_status_launcherr_pending_f()) - clear_intr |= ce2_launcherr_isr(g, ce2_intr); - - gk20a_writel(g, ce2_intr_status_r(0), clear_intr); - return; -} - -static void gp10b_ce2_nonstall_isr(struct gk20a *g) -{ - u32 ce2_intr = gk20a_readl(g, ce2_intr_status_r(0)); - u32 clear_intr = 0; - - gk20a_dbg(gpu_dbg_intr, "ce2 nonstall isr %08x\n", ce2_intr); - - if (ce2_intr & ce2_intr_status_nonblockpipe_pending_f()) - clear_intr |= ce2_nonblockpipe_isr(g, ce2_intr); - - gk20a_writel(g, ce2_intr_status_r(0), clear_intr); - - return; -} -void gp10b_init_ce2(struct gpu_ops *gops) -{ - gops->ce2.isr_stall = gp10b_ce2_isr; - gops->ce2.isr_nonstall = gp10b_ce2_nonstall_isr; -} diff --git a/drivers/gpu/nvgpu/gp10b/ce2_gp10b.h b/drivers/gpu/nvgpu/gp10b/ce2_gp10b.h deleted file mode 100644 index d432d1e0..00000000 --- a/drivers/gpu/nvgpu/gp10b/ce2_gp10b.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * drivers/video/tegra/host/gk20a/fifo_gk20a.h - * - * GK20A graphics copy engine (gr host) - * - * Copyright (c) 2011-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. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef __CE2_GP10B_H__ -#define __CE2_GP10B_H__ - -#include "gk20a/channel_gk20a.h" -#include "gk20a/tsg_gk20a.h" - -void gp10b_init_ce2(struct gpu_ops *gops); - -#endif /*__CE2_GP10B_H__*/ diff --git a/drivers/gpu/nvgpu/gp10b/ce_gp10b.c b/drivers/gpu/nvgpu/gp10b/ce_gp10b.c new file mode 100644 index 00000000..a35c9817 --- /dev/null +++ b/drivers/gpu/nvgpu/gp10b/ce_gp10b.c @@ -0,0 +1,82 @@ +/* + * Pascal GPU series Copy Engine. + * + * Copyright (c) 2011-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. + */ + +#include "gk20a/gk20a.h" /* FERMI and MAXWELL classes defined here */ +#include "hw_ce_gp10b.h" +#include "ce_gp10b.h" + +static u32 ce_nonblockpipe_isr(struct gk20a *g, u32 fifo_intr) +{ + gk20a_dbg(gpu_dbg_intr, "ce non-blocking pipe interrupt\n"); + + /* wake theads waiting in this channel */ + gk20a_channel_semaphore_wakeup(g, true); + return ce_intr_status_nonblockpipe_pending_f(); +} + +static u32 ce_blockpipe_isr(struct gk20a *g, u32 fifo_intr) +{ + gk20a_dbg(gpu_dbg_intr, "ce blocking pipe interrupt\n"); + + return ce_intr_status_blockpipe_pending_f(); +} + +static u32 ce_launcherr_isr(struct gk20a *g, u32 fifo_intr) +{ + gk20a_dbg(gpu_dbg_intr, "ce launch error interrupt\n"); + + return ce_intr_status_launcherr_pending_f(); +} + +static void gp10b_ce_isr(struct gk20a *g, u32 inst_id, u32 pri_base) +{ + u32 ce_intr = gk20a_readl(g, ce_intr_status_r(inst_id)); + u32 clear_intr = 0; + + gk20a_dbg(gpu_dbg_intr, "ce isr %08x %08x\n", ce_intr, inst_id); + + /* clear blocking interrupts: they exibit broken behavior */ + if (ce_intr & ce_intr_status_blockpipe_pending_f()) + clear_intr |= ce_blockpipe_isr(g, ce_intr); + + if (ce_intr & ce_intr_status_launcherr_pending_f()) + clear_intr |= ce_launcherr_isr(g, ce_intr); + + gk20a_writel(g, ce_intr_status_r(inst_id), clear_intr); + return; +} + +static void gp10b_ce_nonstall_isr(struct gk20a *g, u32 inst_id, u32 pri_base) +{ + u32 ce_intr = gk20a_readl(g, ce_intr_status_r(inst_id)); + u32 clear_intr = 0; + + gk20a_dbg(gpu_dbg_intr, "ce nonstall isr %08x %08x\n", ce_intr, inst_id); + + if (ce_intr & ce_intr_status_nonblockpipe_pending_f()) + clear_intr |= ce_nonblockpipe_isr(g, ce_intr); + + gk20a_writel(g, ce_intr_status_r(inst_id), clear_intr); + + return; +} +void gp10b_init_ce(struct gpu_ops *gops) +{ + gops->ce2.isr_stall = gp10b_ce_isr; + gops->ce2.isr_nonstall = gp10b_ce_nonstall_isr; +} diff --git a/drivers/gpu/nvgpu/gp10b/ce_gp10b.h b/drivers/gpu/nvgpu/gp10b/ce_gp10b.h new file mode 100644 index 00000000..948d0454 --- /dev/null +++ b/drivers/gpu/nvgpu/gp10b/ce_gp10b.h @@ -0,0 +1,26 @@ +/* + * Pascal GPU series Copy Engine. + * + * Copyright (c) 2011-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. + */ +#ifndef __CE_GP10B_H__ +#define __CE_GP10B_H__ + +#include "gk20a/channel_gk20a.h" +#include "gk20a/tsg_gk20a.h" + +void gp10b_init_ce(struct gpu_ops *gops); + +#endif /*__CE2_GP10B_H__*/ diff --git a/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c index aa38dc54..0aa6e29e 100644 --- a/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c @@ -188,15 +188,17 @@ static int gp10b_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type, gk20a_dbg_info("engine type %d", engine_type); if (engine_type == top_device_info_type_enum_graphics_v()) ret = ENGINE_GR_GK20A; - else if (engine_type == top_device_info_type_enum_lce_v()) - ret = ENGINE_CE2_GK20A; + else if (engine_type == top_device_info_type_enum_lce_v()) { + /* Default assumptions - all the CE engine have separate runlist */ + ret = ENGINE_ASYNC_CE_GK20A; + } else gk20a_err(g->dev, "unknown engine %d", engine_type); return ret; } -void gp10b_device_info_data_parse(struct gk20a *g, u32 table_entry, +static void gp10b_device_info_data_parse(struct gk20a *g, u32 table_entry, u32 *inst_id, u32 *pri_base, u32 *fault_id) { if (top_device_info_data_type_v(table_entry) == @@ -226,4 +228,5 @@ void gp10b_init_fifo(struct gpu_ops *gops) gops->fifo.resetup_ramfc = gp10b_fifo_resetup_ramfc; gops->fifo.engine_enum_from_type = gp10b_fifo_engine_enum_from_type; gops->fifo.device_info_data_parse = gp10b_device_info_data_parse; + gops->fifo.eng_runlist_base_size = fifo_eng_runlist_base__size_1_v; } diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c index 2ba18410..607fca59 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c @@ -1182,6 +1182,9 @@ static int gr_gp10b_dump_gr_status_regs(struct gk20a *g, struct gk20a_debug_output *o) { struct gr_gk20a *gr = &g->gr; + u32 gr_engine_id; + + gr_engine_id = gk20a_fifo_get_gr_engine_id(g); gk20a_debug_output(o, "NV_PGRAPH_STATUS: 0x%x\n", gk20a_readl(g, gr_status_r())); @@ -1202,7 +1205,7 @@ static int gr_gp10b_dump_gr_status_regs(struct gk20a *g, gk20a_debug_output(o, "NV_PGRAPH_FECS_INTR : 0x%x\n", gk20a_readl(g, gr_fecs_intr_r())); gk20a_debug_output(o, "NV_PFIFO_ENGINE_STATUS(GR) : 0x%x\n", - gk20a_readl(g, fifo_engine_status_r(ENGINE_GR_GK20A))); + gk20a_readl(g, fifo_engine_status_r(gr_engine_id))); gk20a_debug_output(o, "NV_PGRAPH_ACTIVITY0: 0x%x\n", gk20a_readl(g, gr_activity_0_r())); gk20a_debug_output(o, "NV_PGRAPH_ACTIVITY1: 0x%x\n", diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c index a75d2604..b8fffab3 100644 --- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c @@ -25,7 +25,7 @@ #include "gp10b/mc_gp10b.h" #include "gp10b/ltc_gp10b.h" #include "gp10b/mm_gp10b.h" -#include "gp10b/ce2_gp10b.h" +#include "gp10b/ce_gp10b.h" #include "gp10b/fb_gp10b.h" #include "gp10b/pmu_gp10b.h" #include "gp10b/gr_ctx_gp10b.h" @@ -150,6 +150,9 @@ static int gp10b_get_litter_value(struct gk20a *g, case GPU_LIT_ROP_SHARED_BASE: ret = proj_rop_shared_base_v(); break; + case GPU_LIT_HOST_NUM_ENGINES: + ret = proj_host_num_engines_v(); + break; case GPU_LIT_HOST_NUM_PBDMA: ret = proj_host_num_pbdma_v(); break; @@ -219,7 +222,7 @@ int gp10b_init_hal(struct gk20a *g) gp10b_init_ltc(gops); gp10b_init_fb(gops); gp10b_init_fifo(gops); - gp10b_init_ce2(gops); + gp10b_init_ce(gops); gp10b_init_gr_ctx(gops); gp10b_init_mm(gops); gp10b_init_pmu_ops(gops); diff --git a/drivers/gpu/nvgpu/gp10b/hw_ce2_gp10b.h b/drivers/gpu/nvgpu/gp10b/hw_ce2_gp10b.h deleted file mode 100644 index b0c35a30..00000000 --- a/drivers/gpu/nvgpu/gp10b/hw_ce2_gp10b.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -/* - * Function naming determines intended use: - * - * _r(void) : Returns the offset for register . - * - * _o(void) : Returns the offset for element . - * - * _w(void) : Returns the word offset for word (4 byte) element . - * - * __s(void) : Returns size of field of register in bits. - * - * __f(u32 v) : Returns a value based on 'v' which has been shifted - * and masked to place it at field of register . This value - * can be |'d with others to produce a full register value for - * register . - * - * __m(void) : Returns a mask for field of register . This - * value can be ~'d and then &'d to clear the value of field for - * register . - * - * ___f(void) : Returns the constant value after being shifted - * to place it at field of register . This value can be |'d - * with others to produce a full register value for . - * - * __v(u32 r) : Returns the value of field from a full register - * value 'r' after being shifted to place its LSB at bit 0. - * This value is suitable for direct comparison with other unshifted - * values appropriate for use in field of register . - * - * ___v(void) : Returns the constant value for defined for - * field of register . This value is suitable for direct - * comparison with unshifted values appropriate for use in field - * of register . - */ -#ifndef _hw_ce2_gp10b_h_ -#define _hw_ce2_gp10b_h_ - -static inline u32 ce2_intr_status_r(u32 i) -{ - return 0x00104410 + i*128; -} -static inline u32 ce2_intr_status_blockpipe_pending_f(void) -{ - return 0x1; -} -static inline u32 ce2_intr_status_blockpipe_reset_f(void) -{ - return 0x1; -} -static inline u32 ce2_intr_status_nonblockpipe_pending_f(void) -{ - return 0x2; -} -static inline u32 ce2_intr_status_nonblockpipe_reset_f(void) -{ - return 0x2; -} -static inline u32 ce2_intr_status_launcherr_pending_f(void) -{ - return 0x4; -} -static inline u32 ce2_intr_status_launcherr_reset_f(void) -{ - return 0x4; -} -#endif diff --git a/drivers/gpu/nvgpu/gp10b/hw_ce_gp10b.h b/drivers/gpu/nvgpu/gp10b/hw_ce_gp10b.h new file mode 100644 index 00000000..3f6e1470 --- /dev/null +++ b/drivers/gpu/nvgpu/gp10b/hw_ce_gp10b.h @@ -0,0 +1,81 @@ +/* + * 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 . + */ +/* + * Function naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef _hw_ce_gp10b_h_ +#define _hw_ce_gp10b_h_ + +static inline u32 ce_intr_status_r(u32 i) +{ + return 0x00104410 + i*128; +} +static inline u32 ce_intr_status_blockpipe_pending_f(void) +{ + return 0x1; +} +static inline u32 ce_intr_status_blockpipe_reset_f(void) +{ + return 0x1; +} +static inline u32 ce_intr_status_nonblockpipe_pending_f(void) +{ + return 0x2; +} +static inline u32 ce_intr_status_nonblockpipe_reset_f(void) +{ + return 0x2; +} +static inline u32 ce_intr_status_launcherr_pending_f(void) +{ + return 0x4; +} +static inline u32 ce_intr_status_launcherr_reset_f(void) +{ + return 0x4; +} +#endif diff --git a/drivers/gpu/nvgpu/gp10b/hw_proj_gp10b.h b/drivers/gpu/nvgpu/gp10b/hw_proj_gp10b.h index dedc5a3f..d1a60c29 100644 --- a/drivers/gpu/nvgpu/gp10b/hw_proj_gp10b.h +++ b/drivers/gpu/nvgpu/gp10b/hw_proj_gp10b.h @@ -106,6 +106,10 @@ static inline u32 proj_tpc_in_gpc_shared_base_v(void) { return 0x00001800; } +static inline u32 proj_host_num_engines_v(void) +{ + return 0x00000002; +} static inline u32 proj_host_num_pbdma_v(void) { return 0x00000001; diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c index 4d9573d1..eda961b6 100644 --- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c @@ -1,7 +1,7 @@ /* * GP20B master * - * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-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, @@ -101,6 +101,9 @@ irqreturn_t mc_gp10b_isr_nonstall(struct gk20a *g) irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) { u32 mc_intr_0; + u32 engine_id_idx; + u32 active_engine_id = 0; + u32 engine_enum = ENGINE_INVAL_GK20A; gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); @@ -108,11 +111,26 @@ irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) gk20a_dbg(gpu_dbg_intr, "stall intr %08x\n", mc_intr_0); - if (mc_intr_0 & g->fifo.engine_info[ENGINE_GR_GK20A].intr_mask) - gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); - if (mc_intr_0 & g->fifo.engine_info[ENGINE_CE2_GK20A].intr_mask - && g->ops.ce2.isr_stall) - g->ops.ce2.isr_stall(g); + for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; engine_id_idx++) { + active_engine_id = g->fifo.active_engines_list[engine_id_idx]; + + if (mc_intr_0 & g->fifo.engine_info[active_engine_id].intr_mask) { + engine_enum = g->fifo.engine_info[active_engine_id].engine_enum; + /* GR Engine */ + if (engine_enum == ENGINE_GR_GK20A) { + gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g)); + } + + /* CE Engine */ + if (((engine_enum == ENGINE_GRCE_GK20A) || + (engine_enum == ENGINE_ASYNC_CE_GK20A)) && + g->ops.ce2.isr_stall){ + g->ops.ce2.isr_stall(g, + g->fifo.engine_info[active_engine_id].inst_id, + g->fifo.engine_info[active_engine_id].pri_base); + } + } + } if (mc_intr_0 & mc_intr_pfifo_pending_f()) gk20a_fifo_isr(g); if (mc_intr_0 & mc_intr_pmu_pending_f()) @@ -133,6 +151,9 @@ irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) irqreturn_t mc_gp10b_intr_thread_nonstall(struct gk20a *g) { u32 mc_intr_1; + u32 engine_id_idx; + u32 active_engine_id = 0; + u32 engine_enum = ENGINE_INVAL_GK20A; gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); @@ -142,13 +163,27 @@ irqreturn_t mc_gp10b_intr_thread_nonstall(struct gk20a *g) if (mc_intr_1 & mc_intr_pfifo_pending_f()) gk20a_fifo_nonstall_isr(g); - if (mc_intr_1 & g->fifo.engine_info[ENGINE_GR_GK20A].intr_mask) - gk20a_gr_nonstall_isr(g); - if (mc_intr_1 & g->fifo.engine_info[ENGINE_CE2_GK20A].intr_mask - && g->ops.ce2.isr_nonstall) - g->ops.ce2.isr_nonstall(g); - + for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; engine_id_idx++) { + active_engine_id = g->fifo.active_engines_list[engine_id_idx]; + + if (mc_intr_1 & g->fifo.engine_info[active_engine_id].intr_mask) { + engine_enum = g->fifo.engine_info[active_engine_id].engine_enum; + /* GR Engine */ + if (engine_enum == ENGINE_GR_GK20A) { + gk20a_gr_nonstall_isr(g); + } + + /* CE Engine */ + if (((engine_enum == ENGINE_GRCE_GK20A) || + (engine_enum == ENGINE_ASYNC_CE_GK20A)) && + g->ops.ce2.isr_nonstall) { + g->ops.ce2.isr_nonstall(g, + g->fifo.engine_info[active_engine_id].inst_id, + g->fifo.engine_info[active_engine_id].pri_base); + } + } + } gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING), g->ops.mc.intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]); diff --git a/drivers/gpu/nvgpu/gp10b/therm_gp10b.c b/drivers/gpu/nvgpu/gp10b/therm_gp10b.c index 5763b3b1..63efc945 100644 --- a/drivers/gpu/nvgpu/gp10b/therm_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/therm_gp10b.c @@ -82,13 +82,16 @@ static int gp10b_update_therm_gate_ctrl(struct gk20a *g) { u32 gate_ctrl; u32 engine_id; + u32 active_engine_id = 0; + struct fifo_gk20a *f = &g->fifo; - for (engine_id = 0; engine_id < ENGINE_INVAL_GK20A; engine_id++) { - gate_ctrl = gk20a_readl(g, therm_gate_ctrl_r(engine_id)); + for (engine_id = 0; engine_id < f->num_engines; engine_id++) { + active_engine_id = f->active_engines_list[engine_id]; + gate_ctrl = gk20a_readl(g, therm_gate_ctrl_r(active_engine_id)); gate_ctrl = set_field(gate_ctrl, therm_gate_ctrl_eng_delay_before_m(), therm_gate_ctrl_eng_delay_before_f(4)); - gk20a_writel(g, therm_gate_ctrl_r(engine_id), gate_ctrl); + gk20a_writel(g, therm_gate_ctrl_r(active_engine_id), gate_ctrl); } return 0; -- cgit v1.2.2