}
static
-int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
- bool *repeater_present)
+int intel_dp_hdcp_read_bcaps(struct intel_digital_port *intel_dig_port,
+ u8 *bcaps)
{
ssize_t ret;
- u8 bcaps;
+
ret = drm_dp_dpcd_read(&intel_dig_port->dp.aux, DP_AUX_HDCP_BCAPS,
- &bcaps, 1);
+ bcaps, 1);
if (ret != 1) {
DRM_ERROR("Read bcaps from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
+
+ return 0;
+}
+
+static
+int intel_dp_hdcp_repeater_present(struct intel_digital_port *intel_dig_port,
+ bool *repeater_present)
+{
+ ssize_t ret;
+ u8 bcaps;
+
+ ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+ if (ret)
+ return ret;
+
*repeater_present = bcaps & DP_BCAPS_REPEATER_PRESENT;
return 0;
}
return !(bstatus & (DP_BSTATUS_LINK_FAILURE | DP_BSTATUS_REAUTH_REQ));
}
+static
+int intel_dp_hdcp_capable(struct intel_digital_port *intel_dig_port,
+ bool *hdcp_capable)
+{
+ ssize_t ret;
+ u8 bcaps;
+
+ ret = intel_dp_hdcp_read_bcaps(intel_dig_port, &bcaps);
+ if (ret)
+ return ret;
+
+ *hdcp_capable = bcaps & DP_BCAPS_HDCP_CAPABLE;
+ return 0;
+}
+
static const struct intel_hdcp_shim intel_dp_hdcp_shim = {
.write_an_aksv = intel_dp_hdcp_write_an_aksv,
.read_bksv = intel_dp_hdcp_read_bksv,
.read_v_prime_part = intel_dp_hdcp_read_v_prime_part,
.toggle_signalling = intel_dp_hdcp_toggle_signalling,
.check_link = intel_dp_hdcp_check_link,
+ .hdcp_capable = intel_dp_hdcp_capable,
};
static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
u32 reg;
u8 shim[DRM_HDCP_RI_LEN];
} ri;
- bool repeater_present;
+ bool repeater_present, hdcp_capable;
dev_priv = intel_dig_port->base.base.dev->dev_private;
port = intel_dig_port->base.port;
+ /*
+ * Detects whether the display is HDCP capable. Although we check for
+ * valid Bksv below, the HDCP over DP spec requires that we check
+ * whether the display supports HDCP before we write An. For HDMI
+ * displays, this is not necessary.
+ */
+ if (shim->hdcp_capable) {
+ ret = shim->hdcp_capable(intel_dig_port, &hdcp_capable);
+ if (ret)
+ return ret;
+ if (!hdcp_capable) {
+ DRM_ERROR("Panel is not HDCP capable\n");
+ return -EINVAL;
+ }
+ }
+
/* Initialize An with 2 random values and acquire it */
for (i = 0; i < 2; i++)
I915_WRITE(PORT_HDCP_ANINIT(port), get_random_u32());