void intel_dp_test_reset(struct intel_dp *intel_dp)
{ /* * Clearing compliance test variables to allow capturing * of values for next automated test request.
*/
memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
}
/* Adjust link config limits based on compliance test requests. */ void intel_dp_test_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits)
{ struct intel_display *display = to_intel_display(intel_dp);
/* For DP Compliance we override the computed bpp for the pipe */ if (intel_dp->compliance.test_data.bpc != 0) { int bpp = 3 * intel_dp->compliance.test_data.bpc;
drm_dbg_kms(display->drm, "Setting pipe_bpp to %d\n", bpp);
}
/* Use values requested by Compliance Test Request */ if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { int index;
/* Validate the compliance test data since max values * might have changed due to link train fallback.
*/ if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
intel_dp->compliance.test_lane_count)) {
index = intel_dp_rate_index(intel_dp->common_rates,
intel_dp->num_common_rates,
intel_dp->compliance.test_link_rate); if (index >= 0) {
limits->min_rate = intel_dp->compliance.test_link_rate;
limits->max_rate = intel_dp->compliance.test_link_rate;
}
limits->min_lane_count = intel_dp->compliance.test_lane_count;
limits->max_lane_count = intel_dp->compliance.test_lane_count;
}
}
}
/* Compliance test status bits */ #define INTEL_DP_RESOLUTION_PREFERRED 1 #define INTEL_DP_RESOLUTION_STANDARD 2 #define INTEL_DP_RESOLUTION_FAILSAFE 3
static u8 intel_dp_autotest_link_training(struct intel_dp *intel_dp)
{ struct intel_display *display = to_intel_display(intel_dp); int status = 0; int test_link_rate;
u8 test_lane_count, test_link_bw; /* (DP CTS 1.2) * 4.3.1.11
*/ /* Read the TEST_LANE_COUNT and TEST_LINK_RTAE fields (DP CTS 3.1.4) */
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LANE_COUNT,
&test_lane_count);
/* Read the TEST_PATTERN (DP CTS 3.1.5) */
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_PATTERN,
&test_pattern); if (status <= 0) {
drm_dbg_kms(display->drm, "Test pattern read failed\n"); return DP_TEST_NAK;
} if (test_pattern != DP_COLOR_RAMP) return DP_TEST_NAK;
status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_H_WIDTH_HI,
&h_width, 2); if (status <= 0) {
drm_dbg_kms(display->drm, "H Width read failed\n"); return DP_TEST_NAK;
}
status = drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_V_HEIGHT_HI,
&v_height, 2); if (status <= 0) {
drm_dbg_kms(display->drm, "V Height read failed\n"); return DP_TEST_NAK;
}
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_MISC0,
&test_misc); if (status <= 0) {
drm_dbg_kms(display->drm, "TEST MISC read failed\n"); return DP_TEST_NAK;
} if ((test_misc & DP_TEST_COLOR_FORMAT_MASK) != DP_COLOR_FORMAT_RGB) return DP_TEST_NAK; if (test_misc & DP_TEST_DYNAMIC_RANGE_CEA) return DP_TEST_NAK; switch (test_misc & DP_TEST_BIT_DEPTH_MASK) { case DP_TEST_BIT_DEPTH_6:
intel_dp->compliance.test_data.bpc = 6; break; case DP_TEST_BIT_DEPTH_8:
intel_dp->compliance.test_data.bpc = 8; break; default: return DP_TEST_NAK;
}
intel_dp->compliance.test_data.video_pattern = test_pattern;
intel_dp->compliance.test_data.hdisplay = be16_to_cpu(h_width);
intel_dp->compliance.test_data.vdisplay = be16_to_cpu(v_height); /* Set test active flag here so userspace doesn't interrupt things */
intel_dp->compliance.test_active = true;
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
link_status) < 0) {
drm_dbg_kms(display->drm, "failed to get link status\n"); return;
}
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_REQUEST, &request); if (status <= 0) {
drm_dbg_kms(display->drm, "Could not read test request from sink\n"); goto update_status;
}
switch (request) { case DP_TEST_LINK_TRAINING:
drm_dbg_kms(display->drm, "LINK_TRAINING test requested\n");
response = intel_dp_autotest_link_training(intel_dp); break; case DP_TEST_LINK_VIDEO_PATTERN:
drm_dbg_kms(display->drm, "TEST_PATTERN test requested\n");
response = intel_dp_autotest_video_pattern(intel_dp); break; case DP_TEST_LINK_EDID_READ:
drm_dbg_kms(display->drm, "EDID test requested\n");
response = intel_dp_autotest_edid(intel_dp); break; case DP_TEST_LINK_PHY_TEST_PATTERN:
drm_dbg_kms(display->drm, "PHY_PATTERN test requested\n");
response = intel_dp_autotest_phy_pattern(intel_dp); break; default:
drm_dbg_kms(display->drm, "Invalid test request '%02x'\n",
request); break;
}
if (response & DP_TEST_ACK)
intel_dp->compliance.test_type = request;
update_status:
status = drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, response); if (status <= 0)
drm_dbg_kms(display->drm, "Could not write test response to sink\n");
}
/* test on the MST master transcoder */ if (DISPLAY_VER(display) >= 12 &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
!intel_dp_mst_is_master_trans(crtc_state)) continue;
switch (intel_dp->compliance.test_type) { case DP_TEST_LINK_TRAINING:
drm_dbg_kms(display->drm, "Link Training Compliance Test requested\n"); /* Send a Hotplug Uevent to userspace to start modeset */
drm_kms_helper_hotplug_event(display->drm); break; case DP_TEST_LINK_PHY_TEST_PATTERN:
drm_dbg_kms(display->drm, "PHY test pattern Compliance Test requested\n"); /* * Schedule long hpd to do the test * * FIXME get rid of the ad-hoc phy test modeset code * and properly incorporate it into the normal modeset.
*/
reprobe_needed = true;
}
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort) continue;
encoder = to_intel_encoder(connector->encoder); if (encoder && encoder->type == INTEL_OUTPUT_DP_MST) continue;
if (encoder && connector->status == connector_status_connected) {
intel_dp = enc_to_intel_dp(encoder);
status = kstrtoint(input_buffer, 10, &val); if (status < 0) break;
drm_dbg_kms(display->drm, "Got %d for test active\n", val); /* To prevent erroneous activation of the compliance * testing code, only accept an actual value of 1 here
*/ if (val == 1)
intel_dp->compliance.test_active = true; else
intel_dp->compliance.test_active = false;
}
}
drm_connector_list_iter_end(&conn_iter);
kfree(input_buffer); if (status < 0) return status;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.