summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp_hdcp.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_hdcp.c135
1 files changed, 72 insertions, 63 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
index 9db43bd81ce2..cc312596fb77 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -19,6 +19,7 @@
#include "intel_dp_hdcp.h"
#include "intel_hdcp.h"
#include "intel_hdcp_regs.h"
+#include "intel_hdcp_shim.h"
static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
{
@@ -39,7 +40,9 @@ static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
static void intel_dp_hdcp_wait_for_cp_irq(struct intel_connector *connector,
int timeout)
{
- struct intel_hdcp *hdcp = &connector->hdcp;
+ struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+ struct intel_dp *dp = &dig_port->dp;
+ struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
long ret;
#define C (hdcp->cp_irq_count_cached != atomic_read(&hdcp->cp_irq_count))
@@ -55,7 +58,7 @@ static
int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
u8 *an)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
u8 aksv[DRM_HDCP_KSV_LEN] = {};
ssize_t dpcd_ret;
@@ -63,7 +66,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
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(&i915->drm,
+ drm_dbg_kms(display->drm,
"Failed to write An over DP/AUX (%zd)\n",
dpcd_ret);
return dpcd_ret >= 0 ? -EIO : dpcd_ret;
@@ -79,7 +82,7 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
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(&i915->drm,
+ drm_dbg_kms(display->drm,
"Failed to write Aksv over DP/AUX (%zd)\n",
dpcd_ret);
return dpcd_ret >= 0 ? -EIO : dpcd_ret;
@@ -90,13 +93,13 @@ int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
u8 *bksv)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
DRM_HDCP_KSV_LEN);
if (ret != DRM_HDCP_KSV_LEN) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read Bksv from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@@ -106,7 +109,7 @@ static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
u8 *bstatus)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
/*
@@ -117,7 +120,7 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
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(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@@ -126,7 +129,7 @@ static int intel_dp_hdcp_read_bstatus(struct intel_digital_port *dig_port,
static
int intel_dp_hdcp_read_bcaps(struct drm_dp_aux *aux,
- struct drm_i915_private *i915,
+ struct intel_display *display,
u8 *bcaps)
{
ssize_t ret;
@@ -134,7 +137,7 @@ int intel_dp_hdcp_read_bcaps(struct drm_dp_aux *aux,
ret = drm_dp_dpcd_read(aux, DP_AUX_HDCP_BCAPS,
bcaps, 1);
if (ret != 1) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read bcaps from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@@ -146,11 +149,11 @@ static
int intel_dp_hdcp_repeater_present(struct intel_digital_port *dig_port,
bool *repeater_present)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bcaps;
- ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, i915, &bcaps);
+ ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, display, &bcaps);
if (ret)
return ret;
@@ -162,13 +165,14 @@ static
int intel_dp_hdcp_read_ri_prime(struct intel_digital_port *dig_port,
u8 *ri_prime)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_RI_PRIME,
ri_prime, DRM_HDCP_RI_LEN);
if (ret != DRM_HDCP_RI_LEN) {
- drm_dbg_kms(&i915->drm, "Read Ri' from DP/AUX failed (%zd)\n",
+ drm_dbg_kms(display->drm,
+ "Read Ri' from DP/AUX failed (%zd)\n",
ret);
return ret >= 0 ? -EIO : ret;
}
@@ -179,14 +183,14 @@ static
int intel_dp_hdcp_read_ksv_ready(struct intel_digital_port *dig_port,
bool *ksv_ready)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bstatus;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
&bstatus, 1);
if (ret != 1) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@@ -198,7 +202,7 @@ static
int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
int num_downstream, u8 *ksv_fifo)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
int i;
@@ -210,7 +214,7 @@ int intel_dp_hdcp_read_ksv_fifo(struct intel_digital_port *dig_port,
ksv_fifo + i * DRM_HDCP_KSV_LEN,
len);
if (ret != len) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read ksv[%d] from DP/AUX failed (%zd)\n",
i, ret);
return ret >= 0 ? -EIO : ret;
@@ -223,7 +227,7 @@ static
int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
int i, u32 *part)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
if (i >= DRM_HDCP_V_PRIME_NUM_PARTS)
@@ -233,7 +237,7 @@ int intel_dp_hdcp_read_v_prime_part(struct intel_digital_port *dig_port,
DP_AUX_HDCP_V_PRIME(i), part,
DRM_HDCP_V_PRIME_PART_LEN);
if (ret != DRM_HDCP_V_PRIME_PART_LEN) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read v'[%d] from DP/AUX failed (%zd)\n", i, ret);
return ret >= 0 ? -EIO : ret;
}
@@ -253,14 +257,14 @@ static
bool intel_dp_hdcp_check_link(struct intel_digital_port *dig_port,
struct intel_connector *connector)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bstatus;
ret = drm_dp_dpcd_read(&dig_port->dp.aux, DP_AUX_HDCP_BSTATUS,
&bstatus, 1);
if (ret != 1) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return false;
}
@@ -272,11 +276,11 @@ static
int intel_dp_hdcp_get_capability(struct intel_digital_port *dig_port,
bool *hdcp_capable)
{
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ struct intel_display *display = to_intel_display(dig_port);
ssize_t ret;
u8 bcaps;
- ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, i915, &bcaps);
+ ret = intel_dp_hdcp_read_bcaps(&dig_port->dp.aux, display, &bcaps);
if (ret)
return ret;
@@ -339,7 +343,7 @@ static int
intel_dp_hdcp2_read_rx_status(struct intel_connector *connector,
u8 *rx_status)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct drm_dp_aux *aux = &dig_port->dp.aux;
ssize_t ret;
@@ -348,7 +352,7 @@ intel_dp_hdcp2_read_rx_status(struct intel_connector *connector,
DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
HDCP_2_2_DP_RXSTATUS_LEN);
if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"Read bstatus from DP/AUX failed (%zd)\n", ret);
return ret >= 0 ? -EIO : ret;
}
@@ -394,7 +398,7 @@ static ssize_t
intel_dp_hdcp2_wait_for_msg(struct intel_connector *connector,
const struct hdcp2_dp_msg_data *hdcp2_msg_data)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
struct intel_dp *dp = &dig_port->dp;
struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
@@ -427,7 +431,7 @@ intel_dp_hdcp2_wait_for_msg(struct intel_connector *connector,
}
if (ret)
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"msg_id %d, ret %d, timeout(mSec): %d\n",
hdcp2_msg_data->msg_id, ret, timeout);
@@ -511,8 +515,8 @@ static
int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
u8 msg_id, void *buf, size_t size)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct drm_dp_aux *aux = &dig_port->dp.aux;
struct intel_dp *dp = &dig_port->dp;
struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
@@ -565,7 +569,7 @@ int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
ret = drm_dp_dpcd_read(aux, offset,
(void *)byte, len);
if (ret < 0) {
- drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
+ drm_dbg_kms(display->drm, "msg_id %d, ret %zd\n",
msg_id, ret);
return ret;
}
@@ -578,7 +582,8 @@ int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
if (hdcp2_msg_data->msg_read_timeout > 0) {
msg_expired = ktime_after(ktime_get_raw(), msg_end);
if (msg_expired) {
- drm_dbg_kms(&i915->drm, "msg_id %d, entire msg read timeout(mSec): %d\n",
+ drm_dbg_kms(display->drm,
+ "msg_id %d, entire msg read timeout(mSec): %d\n",
msg_id, hdcp2_msg_data->msg_read_timeout);
return -ETIMEDOUT;
}
@@ -675,8 +680,15 @@ static
int intel_dp_hdcp2_get_capability(struct intel_connector *connector,
bool *capable)
{
- struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_dp_aux *aux = &dig_port->dp.aux;
+ struct intel_digital_port *dig_port;
+ struct drm_dp_aux *aux;
+
+ *capable = false;
+ if (!intel_attached_encoder(connector))
+ return -EINVAL;
+
+ dig_port = intel_attached_dig_port(connector);
+ aux = &dig_port->dp.aux;
return _intel_dp_hdcp2_get_capability(aux, capable);
}
@@ -686,22 +698,23 @@ int intel_dp_hdcp_get_remote_capability(struct intel_connector *connector,
bool *hdcp_capable,
bool *hdcp2_capable)
{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
- struct drm_dp_aux *aux = &connector->port->aux;
+ struct intel_display *display = to_intel_display(connector);
+ struct drm_dp_aux *aux;
u8 bcaps;
int ret;
*hdcp_capable = false;
*hdcp2_capable = false;
- if (!intel_encoder_is_mst(connector->encoder))
+ if (!connector->mst.dp)
return -EINVAL;
+ aux = &connector->mst.port->aux;
ret = _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
if (ret)
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"HDCP2 DPCD capability read failed err: %d\n", ret);
- ret = intel_dp_hdcp_read_bcaps(aux, i915, &bcaps);
+ ret = intel_dp_hdcp_read_bcaps(aux, display, &bcaps);
if (ret)
return ret;
@@ -734,8 +747,8 @@ static int
intel_dp_mst_toggle_hdcp_stream_select(struct intel_connector *connector,
bool enable)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
int ret;
@@ -743,7 +756,7 @@ intel_dp_mst_toggle_hdcp_stream_select(struct intel_connector *connector,
hdcp->stream_transcoder, enable,
TRANS_DDI_HDCP_SELECT);
if (ret)
- drm_err(&i915->drm, "%s HDCP stream select failed (%d)\n",
+ drm_err(display->drm, "%s HDCP stream select failed (%d)\n",
enable ? "Enable" : "Disable", ret);
return ret;
}
@@ -752,8 +765,8 @@ static int
intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector,
bool enable)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = hdcp->stream_transcoder;
@@ -769,13 +782,11 @@ intel_dp_mst_hdcp_stream_encryption(struct intel_connector *connector,
return -EINVAL;
/* Wait for encryption confirmation */
- if (intel_de_wait_for_register(i915,
- HDCP_STATUS(i915, cpu_transcoder, port),
- stream_enc_status,
- enable ? stream_enc_status : 0,
- HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
- drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
- transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled");
+ if (intel_de_wait(display, HDCP_STATUS(display, cpu_transcoder, port),
+ stream_enc_status, enable ? stream_enc_status : 0,
+ HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
+ drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
+ transcoder_name(cpu_transcoder), str_enabled_disabled(enable));
return -ETIMEDOUT;
}
@@ -786,17 +797,17 @@ static int
intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
bool enable)
{
+ struct intel_display *display = to_intel_display(connector);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
- struct hdcp_port_data *data = &dig_port->hdcp_port_data;
+ struct hdcp_port_data *data = &dig_port->hdcp.port_data;
struct intel_hdcp *hdcp = &connector->hdcp;
enum transcoder cpu_transcoder = hdcp->stream_transcoder;
enum pipe pipe = (enum pipe)cpu_transcoder;
enum port port = dig_port->base.port;
int ret;
- drm_WARN_ON(&i915->drm, enable &&
- !!(intel_de_read(i915, HDCP2_AUTH_STREAM(i915, cpu_transcoder, port))
+ drm_WARN_ON(display->drm, enable &&
+ !!(intel_de_read(display, HDCP2_AUTH_STREAM(display, cpu_transcoder, port))
& AUTH_STREAM_TYPE) != data->streams[0].stream_type);
ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable);
@@ -804,13 +815,12 @@ intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector,
return ret;
/* Wait for encryption confirmation */
- if (intel_de_wait_for_register(i915,
- HDCP2_STREAM_STATUS(i915, cpu_transcoder, pipe),
- STREAM_ENCRYPTION_STATUS,
- enable ? STREAM_ENCRYPTION_STATUS : 0,
- HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
- drm_err(&i915->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
- transcoder_name(cpu_transcoder), enable ? "enabled" : "disabled");
+ if (intel_de_wait(display, HDCP2_STREAM_STATUS(display, cpu_transcoder, pipe),
+ STREAM_ENCRYPTION_STATUS,
+ enable ? STREAM_ENCRYPTION_STATUS : 0,
+ HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) {
+ drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n",
+ transcoder_name(cpu_transcoder), str_enabled_disabled(enable));
return -ETIMEDOUT;
}
@@ -865,16 +875,15 @@ static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
int intel_dp_hdcp_init(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector)
{
- struct drm_device *dev = intel_connector->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_display *display = to_intel_display(dig_port);
struct intel_encoder *intel_encoder = &dig_port->base;
enum port port = intel_encoder->port;
struct intel_dp *intel_dp = &dig_port->dp;
- if (!is_hdcp_supported(dev_priv, port))
+ if (!is_hdcp_supported(display, port))
return 0;
- if (intel_connector->mst_port)
+ if (intel_connector->mst.dp)
return intel_hdcp_init(intel_connector, dig_port,
&intel_dp_mst_hdcp_shim);
else if (!intel_dp_is_edp(intel_dp))