diff options
| -rw-r--r-- | drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde_hdcp.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde_hdcp_1x.c | 8 | ||||
| -rw-r--r-- | drivers/misc/hdcp.c | 5 | ||||
| -rw-r--r-- | include/linux/hdcp_qseecom.h | 3 |
6 files changed, 52 insertions, 13 deletions
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c index 48bddbf0e871..ca60c869d613 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c @@ -591,6 +591,22 @@ static void sde_hdmi_tx_hdcp_cb(void *ptr, enum sde_hdcp_states status) queue_delayed_work(hdmi->workq, &hdmi_ctrl->hdcp_cb_work, HZ/4); } +static void sde_hdmi_tx_set_avmute(void *ptr) +{ + struct sde_hdmi *hdmi_ctrl = (struct sde_hdmi *)ptr; + struct hdmi *hdmi; + + if (!hdmi_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return; + } + + pr_err("setting avmute to true\n"); + + hdmi = hdmi_ctrl->ctrl.ctrl; + sde_hdmi_config_avmute(hdmi, true); +} + void sde_hdmi_hdcp_off(struct sde_hdmi *hdmi_ctrl) { @@ -645,10 +661,6 @@ static void sde_hdmi_tx_hdcp_cb_work(struct work_struct *work) hdmi_ctrl->auth_state = false; - if (sde_hdmi_tx_is_encryption_set(hdmi_ctrl) || - !sde_hdmi_tx_is_stream_shareable(hdmi_ctrl)) - rc = sde_hdmi_config_avmute(hdmi, true); - if (sde_hdmi_tx_is_panel_on(hdmi_ctrl)) { pr_debug("%s: Reauthenticating\n", __func__); if (hdmi_ctrl->hdcp_ops && hdmi_ctrl->hdcp_data) { @@ -666,7 +678,7 @@ static void sde_hdmi_tx_hdcp_cb_work(struct work_struct *work) } break; - case HDCP_STATE_AUTH_FAIL_NOREAUTH: + case HDCP_STATE_AUTH_FAIL_NOREAUTH: if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present) { if (hdmi_ctrl->auth_state && !hdmi_ctrl->hdcp22_present) hdcp1_set_enc(false); @@ -2472,6 +2484,7 @@ static int _sde_hdmi_init_hdcp(struct sde_hdmi *hdmi_ctrl) hdcp_init_data.mutex = &hdmi_ctrl->hdcp_mutex; hdcp_init_data.workq = hdmi->workq; hdcp_init_data.notify_status = sde_hdmi_tx_hdcp_cb; + hdcp_init_data.avmute_sink = sde_hdmi_tx_set_avmute; hdcp_init_data.cb_data = (void *)hdmi_ctrl; hdcp_init_data.hdmi_tx_ver = hdmi_ctrl->hdmi_tx_major_version; hdcp_init_data.sec_access = true; diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c index a4f47756ad9b..fbb8bd1a3ca4 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -321,11 +321,27 @@ int min_enc_lvl) SDE_HDCP_DEBUG("enc level changed %d\n", min_enc_lvl); + /* notify the client first about the new level */ + if (enc_notify && ctrl->init_data.notify_status) + ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl); + cdata.context = ctrl->lib_ctx; sde_hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata); +} - if (enc_notify && ctrl->init_data.notify_status) - ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl); +static void sde_hdmi_hdcp2p2_mute_sink(void *client_ctx) +{ + struct sde_hdmi_hdcp2p2_ctrl *ctrl = + (struct sde_hdmi_hdcp2p2_ctrl *)client_ctx; + + if (!ctrl) { + SDE_ERROR("invalid input\n"); + return; + } + + /* call into client to send avmute to the sink */ + if (ctrl->init_data.avmute_sink) + ctrl->init_data.avmute_sink(ctrl->init_data.cb_data); } static void sde_hdmi_hdcp2p2_auth_failed(struct sde_hdmi_hdcp2p2_ctrl *ctrl) @@ -930,6 +946,7 @@ void *sde_hdmi_hdcp2p2_init(struct sde_hdcp_init_data *init_data) .wakeup = sde_hdmi_hdcp2p2_wakeup, .notify_lvl_change = sde_hdmi_hdcp2p2_min_level_change, .srm_cb = sde_hdmi_hdcp2p2_srm_cb, + .mute_sink = sde_hdmi_hdcp2p2_mute_sink, }; static struct hdcp_txmtr_ops txmtr_ops; diff --git a/drivers/gpu/drm/msm/sde_hdcp.h b/drivers/gpu/drm/msm/sde_hdcp.h index 415e8467c99f..90c0d1cef26b 100644 --- a/drivers/gpu/drm/msm/sde_hdcp.h +++ b/drivers/gpu/drm/msm/sde_hdcp.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -59,6 +59,7 @@ struct sde_hdcp_init_data { struct workqueue_struct *workq; void *cb_data; void (*notify_status)(void *cb_data, enum sde_hdcp_states status); + void (*avmute_sink)(void *cb_data); struct sde_hdmi_tx_ddc_ctrl *ddc_ctrl; u8 sink_rx_status; u16 *version; diff --git a/drivers/gpu/drm/msm/sde_hdcp_1x.c b/drivers/gpu/drm/msm/sde_hdcp_1x.c index 6c69cd58c0ed..ddbe54f6280f 100644 --- a/drivers/gpu/drm/msm/sde_hdcp_1x.c +++ b/drivers/gpu/drm/msm/sde_hdcp_1x.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1359,6 +1359,9 @@ static void sde_hdcp_1x_notify_topology(void) static void sde_hdcp_1x_update_auth_status(struct sde_hdcp_1x *hdcp) { + if (sde_hdcp_1x_state(HDCP_STATE_AUTH_FAIL)) + hdcp->init_data.avmute_sink(hdcp->init_data.cb_data); + if (sde_hdcp_1x_state(HDCP_STATE_AUTHENTICATED)) { sde_hdcp_1x_cache_topology(hdcp); sde_hdcp_1x_notify_topology(); @@ -1853,7 +1856,8 @@ void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data) if (!init_data || !init_data->core_io || !init_data->qfprom_io || !init_data->mutex || !init_data->notify_status || - !init_data->workq || !init_data->cb_data) { + !init_data->workq || !init_data->cb_data || + !init_data->avmute_sink) { pr_err("invalid input\n"); goto error; } diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c index 09c7c1eeca7a..8dd9ba018f3b 100644 --- a/drivers/misc/hdcp.c +++ b/drivers/misc/hdcp.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2078,6 +2078,9 @@ static void hdcp_lib_clean(struct hdcp_lib_handle *handle) handle->authenticated = false; + /* AV mute the sink first to avoid artifacts */ + handle->client_ops->mute_sink(handle->client_ctx); + hdcp_lib_txmtr_deinit(handle); if (!handle->legacy_app) hdcp_lib_session_deinit(handle); diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h index 11c2af725bb1..1ff11e4e33db 100644 --- a/include/linux/hdcp_qseecom.h +++ b/include/linux/hdcp_qseecom.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -133,6 +133,7 @@ struct hdcp_client_ops { int (*wakeup)(struct hdmi_hdcp_wakeup_data *data); void (*notify_lvl_change)(void *client_ctx, int min_lvl); void (*srm_cb)(void *client_ctx); + void (*mute_sink)(void *client_ctx); }; enum hdcp_device_type { |
