summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-26 03:21:37 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-26 03:21:37 -0400
commitd8f1069384dbfb1d8e453e71614a9baaf3438f5c (patch)
tree3c005687500e0784462e07004eee4561b8ff586f
parentb84c6dee395dfad6d17b454f83f760053375f791 (diff)
downloadopen-iov-d8f1069384dbfb1d8e453e71614a9baaf3438f5c.tar.gz
open-iov-d8f1069384dbfb1d8e453e71614a9baaf3438f5c.zip
gsp_rm: advertise two GRCEs on TU104 (host reports 3 async CEs of 5); CE1 shares GR's runlist/PBDMA
-rw-r--r--kernel/gsp_rm_emulation.c16
-rw-r--r--kernel/gsp_rm_tu104.h22
2 files changed, 22 insertions, 16 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 52cf645..7300a8f 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -1577,13 +1577,15 @@ static void gsp_rm_handle_ce_physical_caps(struct gsp_emu_context *ctx,
out_params[4] = TU104_CE_CAPS0;
out_params[5] = TU104_CE_CAPS1;
- /* The GR-synchronous CEs (GRCE) are the first ones: the client
- * picks the last GRCE as its compute companion ("ceForCompute",
- * rm_device.c) and every non-GRCE CE becomes an async CE. With
- * no GRCE at all the client's context-creation walk ends with an
- * empty secondary-engine record and the engine RM alloc is issued
+ /* The GR-synchronous CEs (GRCE) are the ones sharing the GR
+ * PBDMA. The client picks the last GRCE as its compute
+ * companion ("ceForCompute", rm_device.c) and every non-GRCE
+ * CE becomes an async CE. Measured on the same silicon: two
+ * GRCEs (host ASYNC_ENGINE_COUNT=3 of 5); with fewer the
+ * client's context-creation walk ends with an empty
+ * secondary-engine record and the engine RM alloc is issued
* with class 0. */
- if (idx == TU104_GRCE_IDX)
+ if (TU104_IS_GRCE(idx))
out_params[4] |= TU104_CE_CAPS0_GRCE;
} else {
*out_status = 0x56; /* NV_ERR_NOT_SUPPORTED */
@@ -1617,7 +1619,7 @@ static void gsp_rm_handle_ce_all_caps(struct gsp_emu_context *ctx,
for (i = 0; i < TU104_NUM_CES; i++) {
out_params[i * 2 + 0] = TU104_CE_CAPS0;
out_params[i * 2 + 1] = TU104_CE_CAPS1;
- if (i == TU104_GRCE_IDX)
+ if (TU104_IS_GRCE(i))
out_params[i * 2 + 0] |= TU104_CE_CAPS0_GRCE;
present |= 1ULL << i;
}
diff --git a/kernel/gsp_rm_tu104.h b/kernel/gsp_rm_tu104.h
index 593dfb3..ac90e38 100644
--- a/kernel/gsp_rm_tu104.h
+++ b/kernel/gsp_rm_tu104.h
@@ -287,7 +287,7 @@ static const struct tu104_fifo_device_entry tu104_engine_table[] = {
.numPbdmas = 1,
.engineName = "GRAPHICS",
},
- /* [1] CE0 - the GR-synchronous CE (GRCE); shares the GR PBDMA */
+ /* [1] CE0 - GR-synchronous CE (GRCE 0); shares the GR PBDMA */
{
.engineData = {
[EI_ENG_DESC] = TU104_ENG_CE0,
@@ -312,13 +312,13 @@ static const struct tu104_fifo_device_entry tu104_engine_table[] = {
.numPbdmas = 1,
.engineName = "CE0",
},
- /* [2] CE1 */
+ /* [2] CE1 - GR-synchronous CE (GRCE 1); shares GR's runlist/PBDMA like CE0 */
{
.engineData = {
[EI_ENG_DESC] = TU104_ENG_CE1,
[EI_FIFO_TAG] = TU104_TAG_CE1,
[EI_RM_ENGINE_TYPE] = TU104_RM_ENGINE_CE1,
- [EI_RUNLIST] = 1,
+ [EI_RUNLIST] = 0,
[EI_MMU_FAULT_ID] = TU104_FAULT_ID_CE1,
[EI_RC_MASK] = TU104_RC_CE1,
[EI_RESET] = 2,
@@ -332,8 +332,8 @@ static const struct tu104_fifo_device_entry tu104_engine_table[] = {
[EI_CHRAM_PRI_BASE] = 0,
[EI_KERNEL_RM_MAX] = 0,
},
- .pbdmaIds = {1, 0},
- .pbdmaFaultIds = {TU104_PBDMA_FAULT_ID_BASE + 1, 0},
+ .pbdmaIds = {0, 0},
+ .pbdmaFaultIds = {TU104_PBDMA_FAULT_ID_BASE + 0, 0},
.numPbdmas = 1,
.engineName = "CE1",
},
@@ -756,10 +756,14 @@ static const struct tu104_internal_device_info tu104_internal_device_table[] = {
/* ENGINE_TYPE_COPY0 = 0x9, COPY(i) = COPY0 + i (cl2080_notification.h) */
#define TU104_ENGINE_TYPE_COPY0 0x00000009
#define TU104_NUM_CES 5
-/* The GR-synchronous CE (GRCE): the one sharing the GR PBDMA. Clients pick
- * it as their compute companion (ceForCompute); the driver accepts a CE on
- * the GR runqueue only when it shares GR's PBDMA ids. */
-#define TU104_GRCE_IDX 0
+/* The GR-synchronous CEs (GRCEs): the client picks the last GRCE as its
+ * compute companion ("ceForCompute") and every non-GRCE CE becomes an
+ * asynchronous CE. Measured on the same silicon: the host TU104 advertises
+ * ASYNC_ENGINE_COUNT=3 out of 5 CEs, i.e. exactly two GRCEs (CE0, CE1).
+ * With only one GRCE the client's context walk ends with an empty
+ * secondary-engine record and the engine RM alloc is issued with class 0. */
+#define TU104_GRCE_MASK ((1u << 0) | (1u << 1))
+#define TU104_IS_GRCE(idx) (!!(TU104_GRCE_MASK & (1u << (idx))))
#define TU104_CTRL_INTERNAL_GMMU_GET_STATIC_INFO 0x20800a59
#define TU104_CTRL_STATIC_KGR_GET_GLOBAL_SM_ORDER 0x20800a22
#define TU104_CTRL_STATIC_KGR_GET_INFO 0x20800a2a