diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 57 | ||||
| -rw-r--r-- | kernel/gsp_phys_gpu.c | 21 | ||||
| -rw-r--r-- | kernel/gsp_phys_gpu.h | 4 |
3 files changed, 82 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 17fdcee..b8de6c3 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -263,6 +263,8 @@ bool gsp_phys_boot_requested(void) * runs with VALID=1, so the SKED schedule leg has no valid context. */ #define GSP_PHYS_RMCALL_CTRL_SET_TIMESLICE 0xa06c0103u +#define GSP_PHYS_RMCALL_CTRL_TSG_PREEMPT 0xa06c0105u +#define GSP_PHYS_RMCALL_CTRL_PERF_BOOST_SET_2X 0x20800a9au #define GSP_PHYS_RMCALL_CTRL_GR_SET_CTXSW_PREEMPTION_MODE 0x20801210u #define GSP_PHYS_RMCALL_CTRL_DEVICE_SCHED 0x00802009u /* @@ -13205,6 +13207,61 @@ static int gsp_phys_rmcall_user_lane_lane_enable(void __iomem *bar0) pr_info("vgsp-boot: rm-call: mode 35 lane enable #1063 device sched: enable=%u hDevice=0x%x status=0x%x rpc_result=0x%x ret=%d\n", le32_to_cpu(ds.enable), boot_stage.rmcall_device, status, rpc_result, ret); + if (ret) + return ret; + + /* + * R2 #1073/#1075/#1077 lane tail (gsp_phys_rmcall_gr_lane_tail; + * default 0): the real client explicitly PREEMPTS its own TSG with + * bWait=1 right after the lane-enable controls, then disables device + * scheduling and posts a perf-boost control. The preempt makes the + * RM drive a clean context save/switch-out at ctx-creation time, so + * the first dispatch performs a normal load. Without it our context + * sits loaded from the ladder and the task activation ends in a + * confused save/unload instead of execution. + */ + if (!gsp_phys_rmcall_gr_lane_tail_value()) + return ret; + { + u32 pre[2] = { 1u, 0u }; /* bWait=1, bManualTimeout=0 */ + + rpc_result = 0; + status = 0; + ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_tsg, + GSP_PHYS_RMCALL_CTRL_TSG_PREEMPT, + pre, sizeof(pre), sizeof(pre), NULL, 0, + &rpc_result, &status, + "TSG PREEMPT bWait=1 (mode 35 lane tail, R2 #1073)"); + pr_info("vgsp-boot: rm-call: mode 35 lane tail #1073 TSG PREEMPT: bWait=%u hTsg=0x%x status=0x%x rpc_result=0x%x ret=%d\n", + pre[0], boot_stage.rmcall_tsg, status, rpc_result, ret); + if (ret) + return ret; + } + memset(&ds, 0, sizeof(ds)); + ds.enable = cpu_to_le32(0); + ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_device, + GSP_PHYS_RMCALL_CTRL_DEVICE_SCHED, + &ds, sizeof(ds), 16, NULL, 0, &rpc_result, &status, + "NV01 device sched disable (mode 35 lane tail, R2 #1075)"); + pr_info("vgsp-boot: rm-call: mode 35 lane tail #1075 device sched: enable=%u hDevice=0x%x status=0x%x rpc_result=0x%x ret=%d\n", + le32_to_cpu(ds.enable), boot_stage.rmcall_device, + status, rpc_result, ret); + if (ret) + return ret; + { + u32 pb[2] = { 0x10u, 0u }; + + rpc_result = 0; + status = 0; + ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_subdevice, + GSP_PHYS_RMCALL_CTRL_PERF_BOOST_SET_2X, + pb, sizeof(pb), sizeof(pb), NULL, 0, + &rpc_result, &status, + "PERF_BOOST_SET_2X 0x10 (mode 35 lane tail, R2 #1077)"); + pr_info("vgsp-boot: rm-call: mode 35 lane tail #1077 PERF_BOOST_SET_2X: v=0x%x hSubdevice=0x%x status=0x%x rpc_result=0x%x ret=%d\n", + pb[0], boot_stage.rmcall_subdevice, status, + rpc_result, ret); + } return ret; } diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c index 2f8a127..a394425 100644 --- a/kernel/gsp_phys_gpu.c +++ b/kernel/gsp_phys_gpu.c @@ -796,6 +796,27 @@ unsigned int gsp_phys_rmcall_gr_lmem_tpc_size_value(void) EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_lmem_tpc_size_value); /* + * m76 lane tail (gsp_phys_rmcall_gr_lane_tail; default 0). When set, the + * mode-35 lane enable also sends the R2 capture's tail after #1063: TSG + * PREEMPT (bWait=1, #1073), device-sched disable (#1075) and the + * PERF_BOOST_SET_2X control (#1077). The real client preempts its own TSG at + * context creation so the first dispatch performs a clean context load; our + * lane's context otherwise sits loaded from the ladder and task activation + * ends in a save/unload instead of execution. + */ +static int gsp_phys_rmcall_gr_lane_tail_param; +module_param_named(gsp_phys_rmcall_gr_lane_tail, + gsp_phys_rmcall_gr_lane_tail_param, int, 0644); +MODULE_PARM_DESC(gsp_phys_rmcall_gr_lane_tail, + "Send the R2 #1073/#1075/#1077 lane tail after the mode-35 lane enable (default 0)"); + +int gsp_phys_rmcall_gr_lane_tail_value(void) +{ + return gsp_phys_rmcall_gr_lane_tail_param; +} +EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_lane_tail_value); + +/* * m74 R1/F2 ordering (gsp_phys_rmcall_gr_r1_first; default 0). 1 = send the * VA-only booking promote (R1) before F2's mapped-MAIN promote so the * one-shot context-image initializer (0x52a94f8, pEngCtx+0x135) sees the diff --git a/kernel/gsp_phys_gpu.h b/kernel/gsp_phys_gpu.h index ebed0cb..3a590ea 100644 --- a/kernel/gsp_phys_gpu.h +++ b/kernel/gsp_phys_gpu.h @@ -354,6 +354,10 @@ int gsp_phys_rmcall_gr_inst_sys_value(void); * ordering; default 0 = legacy R1-after-F2). */ int gsp_phys_rmcall_gr_r1_first_value(void); +/* m76: send the R2 #1073/#1075/#1077 lane tail after the mode-35 lane + * enable (TSG preempt bWait, device-sched off, perf boost; default 0). */ +int gsp_phys_rmcall_gr_lane_tail_value(void); + /* * Ladder VAS ownership selector (gsp_phys_rmcall_vas_shared; default 0). * 0 = FERMI_VASPACE_A is allocated IS_EXTERNALLY_OWNED (historical ladder |
