From 2a98d20263ef4355e2d2c38b29350afc39a75f7c Mon Sep 17 00:00:00 2001 From: Ramesh Mylavarapu Date: Tue, 4 Jan 2022 23:20:36 +0530 Subject: [PATCH] nvgpu: ga10b: gsp: implement runlist submit apis - implemented device info cmd to send device info to the gsp for runlist submission. Currently GSP scheduler support only GR engine '0' instance. - implemented runlist submit cmd. GSP firmware will submit the corresponding runlist by writing into submit registers. This command is direct replacement of hw_submit ga10b hal for GR engine. NVGPU-6790 Signed-off-by: Ramesh Mylavarapu Change-Id: I5dc573a6ad698fe20b49a3466a8e50b94cae74df Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2608923 Tested-by: mobile promotions Reviewed-by: mobile promotions --- arch/nvgpu-common.yaml | 2 + drivers/gpu/nvgpu/Makefile | 3 +- drivers/gpu/nvgpu/Makefile.shared.configs | 2 +- drivers/gpu/nvgpu/Makefile.sources | 3 +- .../nvgpu/common/gsp_scheduler/gsp_runlist.c | 171 ++++++++++++++++++ .../nvgpu/common/gsp_scheduler/gsp_runlist.h | 100 ++++++++++ .../common/gsp_scheduler/gsp_scheduler.c | 6 + .../nvgpu/common/gsp_scheduler/ipc/gsp_cmd.h | 7 + .../gpu/nvgpu/hal/fifo/runlist_fifo_ga10b.h | 3 +- .../nvgpu/hal/fifo/runlist_fifo_ga10b_fusa.c | 8 + drivers/gpu/nvgpu/hal/init/hal_ga10b.c | 1 + .../gpu/nvgpu/include/nvgpu/gops/runlist.h | 3 +- drivers/gpu/nvgpu/include/nvgpu/gsp.h | 3 + 13 files changed, 307 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.c create mode 100644 drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.h diff --git a/arch/nvgpu-common.yaml b/arch/nvgpu-common.yaml index 29471cbc0..66d20fa15 100644 --- a/arch/nvgpu-common.yaml +++ b/arch/nvgpu-common.yaml @@ -332,6 +332,8 @@ gsp_sched: common/gsp_scheduler/ipc/gsp_msg.h, common/gsp_scheduler/gsp_scheduler.c, common/gsp_scheduler/gsp_scheduler.h, + common/gsp_scheduler/gsp_runlist.c, + common/gsp_scheduler/gsp_runlist.h, include/nvgpu/gsp_sched.h ] gsp_test: diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index eaa2aabb5..8dc0cadca 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -427,7 +427,8 @@ nvgpu-$(CONFIG_NVGPU_GSP_SCHEDULER) += \ common/gsp_scheduler/ipc/gsp_queue.o \ common/gsp_scheduler/ipc/gsp_cmd.o \ common/gsp_scheduler/ipc/gsp_msg.o \ - common/gsp_scheduler/gsp_scheduler.o + common/gsp_scheduler/gsp_scheduler.o \ + common/gsp_scheduler/gsp_runlist.o endif ifeq ($(CONFIG_NVGPU_GSP_STRESS_TEST),y) diff --git a/drivers/gpu/nvgpu/Makefile.shared.configs b/drivers/gpu/nvgpu/Makefile.shared.configs index 9fe1a50fb..e4268f37e 100644 --- a/drivers/gpu/nvgpu/Makefile.shared.configs +++ b/drivers/gpu/nvgpu/Makefile.shared.configs @@ -1,5 +1,5 @@ # -# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index e99b1a457..4418a52eb 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -185,7 +185,8 @@ srcs += common/gsp/gsp_init.c \ common/gsp_scheduler/ipc/gsp_queue.c \ common/gsp_scheduler/ipc/gsp_cmd.c \ common/gsp_scheduler/ipc/gsp_msg.c \ - common/gsp_scheduler/gsp_scheduler.c + common/gsp_scheduler/gsp_scheduler.c \ + common/gsp_scheduler/gsp_runlist.c endif ifeq ($(CONFIG_NVGPU_GSP_STRESS_TEST),1) diff --git a/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.c b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.c new file mode 100644 index 000000000..838453bff --- /dev/null +++ b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "gsp_runlist.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "ipc/gsp_cmd.h" +#include "ipc/gsp_msg.h" + +static void gsp_handle_cmd_ack(struct gk20a *g, struct nv_flcn_msg_gsp *msg, + void *param, u32 status) +{ + bool *command_ack = param; + + nvgpu_log_fn(g, " "); + + switch (msg->hdr.unit_id) { + case NV_GSP_UNIT_NULL: + nvgpu_info(g, "Reply to NV_GSP_UNIT_NULL"); + *command_ack = true; + break; + case NV_GSP_UNIT_SUBMIT_RUNLIST: + nvgpu_info(g, "Reply to NV_GSP_UNIT_RUNLIST_INFO"); + *command_ack = true; + break; + case NV_GSP_UNIT_DEVICES_INFO: + nvgpu_info(g, "Reply to NV_GSP_UNIT_DEVICES_INFO"); + *command_ack = true; + break; + default: + nvgpu_err(g, "Un-handled response from GSP"); + *command_ack = false; + break; + } +} + +static void gsp_get_runlist_info(struct gk20a *g, + struct nvgpu_gsp_runlist_info *rl_info, struct nvgpu_runlist *runlist) +{ + u64 runlist_iova; + u32 aperture, num_entries; + + runlist_iova = nvgpu_mem_get_addr(g, &runlist->domain->mem_hw->mem); + + num_entries = runlist->domain->mem_hw->count; + + aperture = g->ops.runlist.get_runlist_aperture(g, runlist); + + rl_info->runlist_base_lo = u64_lo32(runlist_iova); + rl_info->runlist_base_hi = u64_hi32(runlist_iova); + rl_info->aperture = aperture; + rl_info->num_entries = num_entries; + rl_info->runlist_id = runlist->id; +} + +int nvgpu_gsp_runlist_submit(struct gk20a *g, struct nvgpu_runlist *runlist) +{ + struct nv_flcn_cmd_gsp cmd; + bool command_ack = false; + int err = 0; + size_t tmp_size; + + nvgpu_log_fn(g, " "); + + (void) memset(&cmd, 0, sizeof(struct nv_flcn_cmd_gsp)); + cmd.hdr.unit_id = NV_GSP_UNIT_SUBMIT_RUNLIST; + tmp_size = GSP_CMD_HDR_SIZE + sizeof(struct nvgpu_gsp_runlist_info); + nvgpu_assert(tmp_size <= U64(U8_MAX)); + cmd.hdr.size = (u8)tmp_size; + + /* copy domain info into cmd buffer */ + gsp_get_runlist_info(g, &cmd.cmd.runlist, runlist); + + err = nvgpu_gsp_cmd_post(g, &cmd, GSP_NV_CMDQ_LOG_ID, + gsp_handle_cmd_ack, &command_ack, U32_MAX); + if (err != 0) { + nvgpu_err(g, "command post failed"); + goto exit; + } + + err = nvgpu_gsp_wait_message_cond(g, nvgpu_get_poll_timeout(g), + &command_ack, U8(true)); + if (err != 0) { + nvgpu_err(g, "command ack receive failed"); + } + +exit: + return err; +} + +static void gsp_get_device_info(struct gk20a *g, + struct nvgpu_gsp_device_info *dev_info) +{ + const struct nvgpu_device *device; + + /* Only GRAPHICS 0-instance is supported by GSP scheduler. + * In future, more devices can be looped through and send it to the GSP. + */ + device = nvgpu_device_get(g, NVGPU_DEVTYPE_GRAPHICS, 0); + + /* copy domain info into cmd buffer */ + dev_info->device_id = NVGPU_DEVTYPE_GRAPHICS; + dev_info->is_engine = true; + dev_info->engine_type = device->type; + dev_info->engine_id = device->engine_id; + dev_info->instance_id = device->inst_id; + dev_info->rl_engine_id = device->rleng_id; + dev_info->dev_pri_base = device->pri_base; + dev_info->runlist_pri_base = device->rl_pri_base; +} + +int nvgpu_gsp_send_devices_info(struct gk20a *g) +{ + struct nv_flcn_cmd_gsp cmd; + bool command_ack = false; + int err = 0; + size_t tmp_size; + + nvgpu_log_fn(g, " "); + + (void) memset(&cmd, 0, sizeof(struct nv_flcn_cmd_gsp)); + cmd.hdr.unit_id = NV_GSP_UNIT_DEVICES_INFO; + tmp_size = GSP_CMD_HDR_SIZE + sizeof(struct nvgpu_gsp_device_info); + nvgpu_assert(tmp_size <= U64(U8_MAX)); + cmd.hdr.size = tmp_size; + + /* copy domain info into cmd buffer */ + gsp_get_device_info(g, &cmd.cmd.device); + + err = nvgpu_gsp_cmd_post(g, &cmd, GSP_NV_CMDQ_LOG_ID, + gsp_handle_cmd_ack, &command_ack, U32_MAX); + if (err != 0) { + nvgpu_err(g, "command post failed"); + goto exit; + } + + err = nvgpu_gsp_wait_message_cond(g, nvgpu_get_poll_timeout(g), + &command_ack, U8(true)); + if (err != 0) { + nvgpu_err(g, "command ack receive failed"); + } + +exit: + return err; +} diff --git a/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.h b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.h new file mode 100644 index 000000000..be9614e4d --- /dev/null +++ b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_runlist.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef NVGPU_GSP_RUNLIST +#define NVGPU_GSP_RUNLIST + +#include + +#define NVGPU_GSP_MAX_DEVTYPE 1U + +struct nvgpu_gsp_device_info { + /* + * Device index + */ + u8 device_id; + /* + * TRUE when the device is a Host-driven method engine. FALSE otherwise. + */ + bool is_engine; + /* + * The device's DEV_RUNLIST_PRI_BASE is the offset into BAR0 for the device's + * NV_RUNLIST PRI space. + */ + u32 runlist_pri_base; + /* + * Engine description, like graphics, or copy engine. + */ + u32 engine_type; + /* + * The unique per-device ID that host uses to identify any given engine. + */ + u32 engine_id; + /* + * Specifies instance of a device, allowing SW to distinguish between + * multiple copies of a device present on the chip. + */ + u32 instance_id; + /* + * Device's runlist-based engine ID. + */ + u32 rl_engine_id; + /* + * The device's DEV_PRI_BASE is the offset into BAR0 for accessing the + * register space for the target device. + */ + u32 dev_pri_base; +}; + +struct nvgpu_gsp_runlist_info { + /* + * Device id to which this runlist belongs to + */ + u8 device_id; + /* + * Domain id to which this runlist need to mapped to + */ + u8 domain_id; + /* + * Indicates how many runlist entries are in the newly submitted runlist + */ + u32 num_entries; + /* + * Indicates how many runlist aperture + */ + u32 aperture; + /* + * ID contains the identifier of the runlist. + */ + u32 runlist_id; + /* + *NV_RUNLIST_SUBMIT_BASE_L0 in-memory location of runlist. + */ + u32 runlist_base_lo; + /* + *NV_RUNLIST_SUBMIT_BASE_Hi in-memory location of runlist. + */ + u32 runlist_base_hi; +}; + +int nvgpu_gsp_send_devices_info(struct gk20a *g); +#endif // NVGPU_GSP_RUNLIST diff --git a/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c index fc5bad85e..a33b055d4 100644 --- a/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c +++ b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c @@ -31,6 +31,7 @@ #include "gsp_scheduler.h" #include "ipc/gsp_seq.h" #include "ipc/gsp_queue.h" +#include "gsp_runlist.h" static void gsp_sched_get_file_names(struct gk20a *g, struct gsp_fw *gsp_ucode) { @@ -205,6 +206,11 @@ int nvgpu_gsp_sched_bootstrap_ns(struct gk20a *g) goto de_init; } + status = nvgpu_gsp_send_devices_info(g); + if (status != 0) { + nvgpu_err(g, "gsp send device info failed"); + } + return status; de_init: nvgpu_gsp_sched_sw_deinit(g); diff --git a/drivers/gpu/nvgpu/common/gsp_scheduler/ipc/gsp_cmd.h b/drivers/gpu/nvgpu/common/gsp_scheduler/ipc/gsp_cmd.h index e145ec6c4..b44eaf2ec 100644 --- a/drivers/gpu/nvgpu/common/gsp_scheduler/ipc/gsp_cmd.h +++ b/drivers/gpu/nvgpu/common/gsp_scheduler/ipc/gsp_cmd.h @@ -24,6 +24,7 @@ #define NVGPU_GSP_CMD_IF_H #include +#include "../gsp_runlist.h" #include "gsp_seq.h" struct gk20a; @@ -35,6 +36,8 @@ struct gk20a; #define NV_GSP_UNIT_REWIND NV_FLCN_UNIT_ID_REWIND #define NV_GSP_UNIT_NULL 0x01U #define NV_GSP_UNIT_INIT 0x02U +#define NV_GSP_UNIT_DEVICES_INFO 0x03U +#define NV_GSP_UNIT_SUBMIT_RUNLIST 0x04U #define NV_GSP_UNIT_END 0x0AU #define GSP_MSG_HDR_SIZE U32(sizeof(struct gsp_hdr)) @@ -49,6 +52,10 @@ struct gsp_hdr { struct nv_flcn_cmd_gsp { struct gsp_hdr hdr; + union { + struct nvgpu_gsp_device_info device; + struct nvgpu_gsp_runlist_info runlist; + } cmd; }; u8 gsp_unit_id_is_valid(u8 id); diff --git a/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b.h b/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b.h index 3a23deca2..7020facfa 100644 --- a/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b.h +++ b/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b.h @@ -1,7 +1,7 @@ /* * GA10B runlist * - * Copyright (c) 2020-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,6 +36,7 @@ void ga10b_runlist_hw_submit(struct gk20a *g, struct nvgpu_runlist *runlist); int ga10b_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist); void ga10b_runlist_write_state(struct gk20a *g, u32 runlists_mask, u32 runlist_state); +u32 ga10b_get_runlist_aperture(struct gk20a *g, struct nvgpu_runlist *runlist); #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING int ga10b_fifo_reschedule_preempt_next(struct nvgpu_channel *ch, bool wait_preempt); diff --git a/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b_fusa.c b/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b_fusa.c index f2722f601..610646df8 100644 --- a/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fifo/runlist_fifo_ga10b_fusa.c @@ -101,6 +101,14 @@ int ga10b_runlist_wait_pending(struct gk20a *g, struct nvgpu_runlist *runlist) return ret; } +u32 ga10b_get_runlist_aperture(struct gk20a *g, struct nvgpu_runlist *runlist) +{ + return nvgpu_aperture_mask(g, &runlist->domain->mem_hw->mem, + runlist_submit_base_lo_target_sys_mem_noncoherent_f(), + runlist_submit_base_lo_target_sys_mem_coherent_f(), + runlist_submit_base_lo_target_vid_mem_f()); +} + void ga10b_runlist_write_state(struct gk20a *g, u32 runlists_mask, u32 runlist_state) { diff --git a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c index fc8ade2e1..af8b79c4c 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_ga10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_ga10b.c @@ -1140,6 +1140,7 @@ static const struct gops_runlist ga10b_ops_runlist = { .wait_pending = ga10b_runlist_wait_pending, .write_state = ga10b_runlist_write_state, .get_runlist_id = ga10b_runlist_get_runlist_id, + .get_runlist_aperture = ga10b_get_runlist_aperture, .get_engine_id_from_rleng_id = ga10b_runlist_get_engine_id_from_rleng_id, .get_chram_bar0_offset = ga10b_runlist_get_chram_bar0_offset, .get_pbdma_info = ga10b_runlist_get_pbdma_info, diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h b/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h index 9ad4e9b86..6ab1d580b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -102,6 +102,7 @@ struct gops_runlist { void (*init_enginfo)(struct gk20a *g, struct nvgpu_fifo *f); u32 (*get_tsg_max_timeslice)(void); u32 (*get_runlist_id)(struct gk20a *g, u32 runlist_pri_base); + u32 (*get_runlist_aperture)(struct gk20a *g, struct nvgpu_runlist *runlist); u32 (*get_engine_id_from_rleng_id)(struct gk20a *g, u32 rleng_id, u32 runlist_pri_base); u32 (*get_chram_bar0_offset)(struct gk20a *g, u32 runlist_pri_base); diff --git a/drivers/gpu/nvgpu/include/nvgpu/gsp.h b/drivers/gpu/nvgpu/include/nvgpu/gsp.h index 562151bd2..19d1c5fe4 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gsp.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gsp.h @@ -25,6 +25,8 @@ #include #include struct gk20a; +struct nvgpu_gsp; +struct nvgpu_runlist; struct gsp_fw { /* gsp ucode name */ @@ -65,4 +67,5 @@ void nvgpu_gsp_isr(struct gk20a *g); void nvgpu_gsp_isr_support(struct gk20a *g, struct nvgpu_gsp *gsp, bool enable); int nvgpu_gsp_wait_for_priv_lockdown_release(struct nvgpu_gsp *gsp, signed int timeoutms); +int nvgpu_gsp_runlist_submit(struct gk20a *g, struct nvgpu_runlist *runlist); #endif /* NVGPU_GSP */