#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
msecs_to_jiffies(timeout));
if (!ret)
drm_dbg_kms(connector->base.dev, "Timedout at waiting for CP_IRQ\n");
}
/* Output An first, that's easy */
dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AN,
an, DRM_HDCP_AN_LEN); if (dpcd_ret != DRM_HDCP_AN_LEN) {
drm_dbg_kms(display->drm, "Failed to write An over DP/AUX (%zd)\n",
dpcd_ret); return dpcd_ret >= 0 ? -EIO : dpcd_ret;
}
/* * Since Aksv is Oh-So-Secret, we can't access it in software. So we * send an empty buffer of the correct length through the DP helpers. On * the other side, in the transfer hook, we'll generate a flag based on * the destination address which will tickle the hardware to output the * Aksv on our behalf after the header is sent.
*/
dpcd_ret = drm_dp_dpcd_write(&dig_port->dp.aux, DP_AUX_HDCP_AKSV,
aksv, DRM_HDCP_KSV_LEN); if (dpcd_ret != DRM_HDCP_KSV_LEN) {
drm_dbg_kms(display->drm, "Failed to write Aksv over DP/AUX (%zd)\n",
dpcd_ret); return dpcd_ret >= 0 ? -EIO : dpcd_ret;
} return 0;
}
/* * For some reason the HDMI and DP HDCP specs call this register * definition by different names. In the HDMI spec, it's called BSTATUS, * but in DP it's called BINFO.
*/
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BINFO,
bstatus, DRM_HDCP_BSTATUS_LEN); if (ret != DRM_HDCP_BSTATUS_LEN) {
drm_dbg_kms(display->drm, "Read bstatus from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret;
} return 0;
}
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
&bstatus, 1); if (ret != 1) {
drm_dbg_kms(display->drm, "Read bstatus from DP/AUX failed (%zd)\n", ret); return ret >= 0 ? -EIO : ret;
}
*ksv_ready = bstatus & DP_BSTATUS_READY; return 0;
}
static int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port, int num_downstream, u8 *ksv_fifo)
{ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret; int i;
/* KSV list is read via 15 byte window (3 entries @ 5 bytes each) */ for (i = 0; i < num_downstream; i += 3) {
size_t len = min(num_downstream - i, 3) * DRM_HDCP_KSV_LEN;
ret = drm_dp_dpcd_read(&dig_port->dp.aux,
DP_AUX_HDCP_KSV_FIFO,
ksv_fifo + i * DRM_HDCP_KSV_LEN,
len); if (ret != len) {
drm_dbg_kms(display->drm, "Read ksv[%d] from DP/AUX failed (%zd)\n",
i, ret); return ret >= 0 ? -EIO : ret;
}
} return 0;
}
static int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port, int i, u32 *part)
{ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
if (i >= DRM_HDCP_V_PRIME_NUM_PARTS) return -EINVAL;
ret = drm_dp_dpcd_read(&dig_port->dp.aux,
DP_AUX_HDCP_V_PRIME(i), part,
DRM_HDCP_V_PRIME_PART_LEN); if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
drm_dbg_kms(display->drm, "Read v'[%d] from DP/AUX failed (%zd)\n", i, ret); return ret >= 0 ? -EIO : ret;
} return 0;
}
static int intel_dp_hdcp_toggle_signalling(struct intel_digital_port *dig_port, enum transcoder cpu_transcoder, bool enable)
{ /* Not used for single stream DisplayPort setups */ return 0;
}
/* * There is no way to detect the CERT, LPRIME and STREAM_READY * availability. So Wait for timeout and read the msg.
*/ if (!hdcp2_msg_data->msg_detectable) {
mdelay(timeout);
ret = 0;
} else { /* * As we want to check the msg availability at timeout, Ignoring * the timeout at wait for CP_IRQ.
*/
intel_dp_hdcp_wait_for_cp_irq(connector, timeout);
ret = hdcp2_detect_msg_availability(connector, msg_id,
&msg_ready); if (!msg_ready)
ret = -ETIMEDOUT;
}
if (ret)
drm_dbg_kms(display->drm, "msg_id %d, ret %d, timeout(mSec): %d\n",
hdcp2_msg_data->msg_id, ret, timeout);
return ret;
}
staticconststruct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id)
{ int i;
for (i = 0; i < ARRAY_SIZE(hdcp2_dp_msg_data); i++) if (hdcp2_dp_msg_data[i].msg_id == msg_id) return &hdcp2_dp_msg_data[i];
static int intel_dp_hdcp2_config_stream_type(struct intel_connector *connector, bool is_repeater, u8 content_type)
{ int ret; struct hdcp2_dp_errata_stream_type stream_type_msg;
if (is_repeater) return 0;
/* * Errata for DP: As Stream type is used for encryption, Receiver * should be communicated with stream type for the decryption of the * content. * Repeater will be communicated with stream type as a part of it's * auth later in time.
*/
stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
stream_type_msg.stream_type = content_type;
ret = intel_dp_hdcp2_write_msg(connector, &stream_type_msg, sizeof(stream_type_msg));
return ret < 0 ? ret : 0;
}
static int intel_dp_hdcp2_check_link(struct intel_digital_port *dig_port, struct intel_connector *connector)
{
u8 rx_status; int ret;
ret = intel_dp_hdcp2_read_rx_status(connector,
&rx_status); if (ret) return ret;
if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rx_status))
ret = HDCP_REAUTH_REQUEST; elseif (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rx_status))
ret = HDCP_LINK_INTEGRITY_FAILURE; elseif (HDCP_2_2_DP_RXSTATUS_READY(rx_status))
ret = HDCP_TOPOLOGY_CHANGE;
return ret;
}
static int _intel_dp_hdcp2_get_capability(struct drm_dp_aux *aux, bool *capable)
{
u8 rx_caps[3]; int ret, i;
*capable = false;
/* * Some HDCP monitors act really shady by not giving the correct hdcp * capability on the first rx_caps read and usually take an extra read * to give the capability. We read rx_caps three times before we * declare a monitor not capable of HDCP 2.2.
*/ for (i = 0; i < 3; i++) {
ret = drm_dp_dpcd_read(aux,
DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
rx_caps, HDCP_2_2_RXCAPS_LEN); if (ret != HDCP_2_2_RXCAPS_LEN) return ret >= 0 ? -EIO : ret;
static int intel_dp_mst_hdcp2_check_link(struct intel_digital_port *dig_port, struct intel_connector *connector)
{ struct intel_hdcp *hdcp = &connector->hdcp; int ret;
/* * We do need to do the Link Check only for the connector involved with * HDCP port authentication and encryption. * We can re-use the hdcp->is_repeater flag to know that the connector * involved with HDCP port authentication and encryption.
*/ if (hdcp->is_repeater) {
ret = intel_dp_hdcp2_check_link(dig_port, connector); if (ret) return ret;
}
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.