diff options
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 7011f77..ec6ca20 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -1959,6 +1959,103 @@ static void gsp_rm_handle_display_get_ip_version(struct gsp_emu_context *ctx, } /* + * NV0073 display-common heads + one static HDMI connector + * (0x730102 / 0x730287 / 0x7302ad / 0x730107 / 0x73028b / 0x730250 / + * 0x731140) + * + * nvidia-modeset's nvkms-rm.c ProbeHeadCountAndWindowAssignment asks the + * display-common object for the head count (NV0073_CTRL_CMD_SYSTEM_ + * GET_NUM_HEADS = 0x730102) and a zero reply makes it log "No heads found on + * board!" and fail -- which kills Xorg's ScreenInit and every Vulkan + * vkCreateDevice (measured: the emulated device replies all-zero through the + * generic path, so nvkms never opens). The kernel driver already sees 1 head + * (DISPLAY_GET_STATIC_INFO reports numHeads=1); report the same 1 head here, + * a single-head mask for GET_ALL_HEAD_MASK (0x730287), and a fully-flexible + * window assignment for windows 0/1 (0xFF = FLEXIBLE; windows above the head + * count stay 0 = not present). + * + * The next wall after the heads (measured r643): nvRmAllocDisplays fails on + * NoValidDisplays() - nvkms requires at least one valid display. Report one + * static TMDS/HDMI connector on display id 0: GET_SUPPORTED (0x730107) + * displayMask=1|DDC=1, SPECIFIC_OR_GET_INFO (0x73028b) SOR / + * SOR_SINGLE_TMDS_A (TMDS avoids the whole DP-AUX lib), SPECIFIC_ + * GET_CONNECTOR_DATA (0x730250) one HDMI_A entry, DFP_GET_INFO (0x731140) + * TMDS flags. Still a headless setup: no connect state or EDID is claimed + * (those are modeset-time queries). + */ +static void gsp_rm_handle_display_heads(struct gsp_emu_context *ctx, u32 cmd, + u32 req_size, + u32 *out_status, u8 *out_params, + u32 *out_params_size) +{ + u32 one = 1; + u32 sz = req_size ? req_size : 72; + u32 v; + + memset(out_params, 0, sz); + switch (cmd) { + case 0x730102: /* SYSTEM_GET_NUM_HEADS: {subDev, flags, numHeads} */ + if (sz >= 12) + memcpy(out_params + 8, &one, 4); + break; + case 0x730287: /* SPECIFIC_GET_ALL_HEAD_MASK: {subDev, headMask} */ + if (sz >= 8) + memcpy(out_params + 4, &one, 4); + break; + case 0x7302ad: /* SPECIFIC_GET_VALID_HEAD_WINDOW_ASSIGNMENT: + * {subDev, windowHeadMask[32]} - windows 0 and 1 + * flexible (0xFF), the rest absent (0). */ + if (sz >= 36) { + out_params[4] = 0xff; + out_params[5] = 0xff; + } + break; + case 0x730107: /* SYSTEM_GET_SUPPORTED: {subDev, displayMask, + * displayMaskDDC} - display id 0 supported + DDC. */ + if (sz >= 12) { + memcpy(out_params + 4, &one, 4); + memcpy(out_params + 8, &one, 4); + } + break; + case 0x73028b: /* SPECIFIC_OR_GET_INFO: {subDev, displayId, index, + * type, protocol, ditherType, ditherAlgo, location, + * rootPortId, dcbIndex, vbiosAddress, bIsLitByVbios, + * bIsDispDynamic} */ + if (sz >= 52) { + v = 2; /* NV0073_CTRL_SPECIFIC_OR_TYPE_SOR */ + memcpy(out_params + 12, &v, 4); + v = 1; /* SOR_SINGLE_TMDS_A (no DP aux) */ + memcpy(out_params + 16, &v, 4); + /* location=0 (chip), remaining out-fields stay 0: + * not lit by vbios, not dynamic. */ + } + break; + case 0x730250: /* SPECIFIC_GET_CONNECTOR_DATA: {subDev, + * displayId, flags, DDCPartners, count, + * data[4]{index,type,location}, platform} */ + if (sz >= 72) { + v = 1; /* CONNECTOR_DATA_FLAGS_PRESENT_YES */ + memcpy(out_params + 8, &v, 4); + v = 1; /* count */ + memcpy(out_params + 16, &v, 4); + /* data[0].index = 0 */ + v = 0x61; /* CONNECTOR_DATA_TYPE_HDMI_A */ + memcpy(out_params + 24, &v, 4); + /* data[0].location = 0 */ + } + break; + case 0x731140: /* DFP_GET_INFO: {subDev, displayId, flags, + * UHBRSupportedByDfp} - flags signal bits = TMDS(0) */ + break; /* zeros are the TMDS signal value */ + } + *out_params_size = sz; + *out_status = 0; + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: DISPLAY shim cmd=0x%x -> 1 head / 1 HDMI connector (size %u)", + cmd, sz); +} + +/* * CE_GET_FAULT_METHOD_BUFFER_SIZE (0x20802a08) * * kchangrpInit allocates one fault method buffer per runqueue of this @@ -3680,6 +3777,18 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size); break; + case 0x730102: /* NV0073_CTRL_CMD_SYSTEM_GET_NUM_HEADS */ + case 0x730287: /* NV0073_CTRL_CMD_SPECIFIC_GET_ALL_HEAD_MASK */ + case 0x7302ad: /* NV0073_CTRL_CMD_SPECIFIC_GET_VALID_HEAD_WINDOW_ASSIGNMENT */ + case 0x730107: /* NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED */ + case 0x73028b: /* NV0073_CTRL_CMD_SPECIFIC_OR_GET_INFO */ + case 0x730250: /* NV0073_CTRL_CMD_SPECIFIC_GET_CONNECTOR_DATA */ + case 0x731140: /* NV0073_CTRL_CMD_DFP_GET_INFO */ + gsp_rm_handle_display_heads(ctx, req.cmd, req.paramsSize, + &out_status, + reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size); + break; + case TU104_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE: gsp_rm_handle_ce_get_fault_method_buffer_size(ctx, sequence, &out_status, |
