summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_rm_emulation.c62
-rw-r--r--kernel/gsp_rm_tu104.h3
2 files changed, 65 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index ff65275..d6aef9e 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -2031,6 +2031,60 @@ static void gsp_rm_handle_fb_get_info_v2(struct gsp_emu_context *ctx,
}
/*
+ * CLK legacy domain queries (0x20809001 / 0x20809009 / 0x20809064)
+ *
+ * libcuda's clock-domain helper (libcuda+0xe8c410) walks these three queries
+ * before it will report clock/ECC/perf data. It requires:
+ * - 0x20809009: bits 32 and 34 set in the 8-byte reply (domain presence);
+ * - 0x20809064: non-zero domain entries at reply offsets 12, 20, 28, 36;
+ * - 0x20809001: a selector mask overlapping those entries.
+ * With the generic zero reply the helper returns CUDA_ERROR_NOT_FOUND, which
+ * makes the dependent device-attribute queries (ECC_ENABLED = attr 36,
+ * TOTAL_CONSTANT_MEMORY = attr 13) abort device initialization with
+ * cudaErrorInitializationError. Populate only the fields the checks read;
+ * clock rates stay zero (no fabricated frequencies).
+ */
+static void gsp_rm_handle_clk_domain_info(struct gsp_emu_context *ctx, u32 cmd,
+ u32 req_size,
+ u32 *out_status,
+ u8 *out_params,
+ u32 *out_params_size)
+{
+ u32 n = req_size ? req_size : 8;
+ u32 one = 1;
+
+ if (n > 4096)
+ n = 4096;
+ memset(out_params, 0, n);
+
+ if (cmd == TU104_CTRL_CLK_DOMAIN_MASK) {
+ u64 mask = (1ULL << 32) | (1ULL << 34);
+
+ if (n >= sizeof(mask))
+ memcpy(out_params, &mask, sizeof(mask));
+ } else if (cmd == TU104_CTRL_CLK_DOMAIN_DATA) {
+ if (n >= 16)
+ memcpy(out_params + 12, &one, sizeof(one));
+ if (n >= 24)
+ memcpy(out_params + 20, &one, sizeof(one));
+ if (n >= 32)
+ memcpy(out_params + 28, &one, sizeof(one));
+ if (n >= 40)
+ memcpy(out_params + 36, &one, sizeof(one));
+ } else { /* TU104_CTRL_CLK_DOMAIN_SEL */
+ if (n >= sizeof(one))
+ memcpy(out_params, &one, sizeof(one));
+ }
+
+ *out_params_size = n;
+ *out_status = 0;
+
+ if (gsp_sema_dbg)
+ nv_vgpu_info(ctx->vgpu, "GSPRM: CLK domain info cmd=0x%x size=%u",
+ cmd, n);
+}
+
+/*
* BUS_GET_INFO_V2 (0x20801823)
*
* Same flat index/data list pattern as FB_GET_INFO_V2. UVM's
@@ -2641,6 +2695,14 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size);
break;
+ case TU104_CTRL_CLK_DOMAIN_MASK:
+ case TU104_CTRL_CLK_DOMAIN_DATA:
+ case TU104_CTRL_CLK_DOMAIN_SEL:
+ gsp_rm_handle_clk_domain_info(ctx, req.cmd, req.paramsSize,
+ &out_status,
+ reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size);
+ break;
+
case TU104_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO:
gsp_rm_handle_display_get_static_info(ctx, sequence,
&out_status,
diff --git a/kernel/gsp_rm_tu104.h b/kernel/gsp_rm_tu104.h
index 7cd5a4b..b5ee4d7 100644
--- a/kernel/gsp_rm_tu104.h
+++ b/kernel/gsp_rm_tu104.h
@@ -728,6 +728,9 @@ static const struct tu104_internal_device_info tu104_internal_device_table[] = {
#define TU104_CTRL_FIFO_GET_DEVICE_INFO_TABLE 0x20801112
#define TU104_CTRL_INTERNAL_INTR_GET_KERNEL_TABLE 0x20800a5c
#define TU104_CTRL_GPU_GET_CONSTRUCTED_FALCON_INFO 0x208001b0
+#define TU104_CTRL_CLK_DOMAIN_MASK 0x20809009
+#define TU104_CTRL_CLK_DOMAIN_DATA 0x20809064
+#define TU104_CTRL_CLK_DOMAIN_SEL 0x20809001
#define TU104_CTRL_INTERNAL_FIFO_GET_NUM_CHANNELS 0x20800a61
#define TU104_CTRL_BUS_GET_PCI_BAR_INFO 0x20801803
#define TU104_CTRL_INTERNAL_DISPLAY_GET_STATIC_INFO 0x20800a01