media: rockchip: hdmirx: auto identification of hdcp1.4 and hdcp2.3

Signed-off-by: Chen Shunqing <csq@rock-chips.com>
Change-Id: Ic7f39acfa903085144c380c9a4415e2cf64380d8
This commit is contained in:
Chen Shunqing
2022-08-19 09:01:48 +00:00
committed by Tao Huang
parent 93eeaf98c4
commit a50fb57df2
2 changed files with 64 additions and 88 deletions

View File

@@ -219,9 +219,8 @@ struct rk_hdmirx_dev {
bool initialized;
bool freq_qos_add;
bool get_timing;
u8 hdcp_enable;
u8 hdcp_support;
bool cec_enable;
u8 hdcp_enable;
u32 num_clks;
u32 edid_blocks_written;
u32 hpd_trigger_level;
@@ -1048,7 +1047,6 @@ static void hdmirx_register_hdcp(struct device *dev,
.hpd_config = hdmirx_hpd_config,
.tx_5v_power = tx_5v_power_present,
.enable = hdcp_enable,
.hdcp_support = hdmirx_dev->hdcp_support,
.dev = hdmirx_dev->dev,
};
@@ -1299,6 +1297,8 @@ static void hdmirx_format_change(struct rk_hdmirx_dev *hdmirx_dev)
}
hdmirx_dev->get_timing = true;
if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_start)
hdmirx_dev->hdcp->hdcp_start(hdmirx_dev->hdcp);
v4l2_dbg(1, debug, v4l2_dev, "%s: queue res_chg_event\n", __func__);
v4l2_event_queue(&stream->vdev, &ev_src_chg);
}
@@ -1422,10 +1422,6 @@ static void hdmirx_dma_config(struct rk_hdmirx_dev *hdmirx_dev)
static void hdmirx_submodule_init(struct rk_hdmirx_dev *hdmirx_dev)
{
/* Note: if not config HDCP2_CONFIG, there will be some errors; */
hdmirx_update_bits(hdmirx_dev, HDCP2_CONFIG,
HDCP2_SWITCH_OVR_EN,
HDCP2_SWITCH_OVR_EN);
hdmirx_scdc_init(hdmirx_dev);
hdmirx_controller_init(hdmirx_dev);
}
@@ -2022,9 +2018,11 @@ static void process_signal_change(struct rk_hdmirx_dev *hdmirx_dev)
HDMIRX_AXI_ERROR_INT_EN, 0);
hdmirx_reset_dma(hdmirx_dev);
hdmirx_dev->get_timing = false;
if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_stop)
hdmirx_dev->hdcp->hdcp_stop(hdmirx_dev->hdcp);
schedule_delayed_work_on(hdmirx_dev->bound_cpu,
&hdmirx_dev->delayed_work_res_change,
msecs_to_jiffies(50));
msecs_to_jiffies(800));
}
static void avpunit_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev,
@@ -2435,8 +2433,6 @@ static void hdmirx_plugin(struct rk_hdmirx_dev *hdmirx_dev)
hdmirx_dma_config(hdmirx_dev);
hdmirx_interrupts_setup(hdmirx_dev, true);
hdmirx_audio_handle_plugged_change(hdmirx_dev, 1);
if (hdmirx_dev->hdcp && hdmirx_dev->hdcp->hdcp_start)
hdmirx_dev->hdcp->hdcp_start(hdmirx_dev->hdcp);
}
static void hdmirx_plugout(struct rk_hdmirx_dev *hdmirx_dev)
@@ -2946,18 +2942,11 @@ static int hdmirx_parse_dt(struct rk_hdmirx_dev *hdmirx_dev)
dev_warn(dev, "failed to get hpd-trigger-level, set high as default\n");
}
if (of_property_read_bool(np, "hdcp1x-enable")) {
hdmirx_dev->hdcp_support |= HDCP_1X_ENABLE;
if (of_property_read_bool(np, "hdcp1x-enable"))
hdmirx_dev->hdcp_enable = HDCP_1X_ENABLE;
}
if (of_property_read_bool(np, "hdcp2x-enable")) {
hdmirx_dev->hdcp_support |= HDCP_2X_ENABLE;
if (of_property_read_bool(np, "hdcp2x-enable"))
hdmirx_dev->hdcp_enable = HDCP_2X_ENABLE;
}
if (of_property_read_bool(np, "hdcp1x-default-enable")) {
hdmirx_dev->hdcp_support |= HDCP_1X_ENABLE;
hdmirx_dev->hdcp_enable = HDCP_1X_ENABLE;
}
if (of_property_read_bool(np, "cec-enable"))
hdmirx_dev->cec_enable = true;

View File

@@ -81,6 +81,7 @@ static int rk_hdmirx_hdcp_load_key(struct rk_hdmirx_hdcp *hdcp)
{
int ret;
hdcp->status = HDMIRX_HDCP_DISABLED;
if (!hdcp->keys_is_load) {
ret = hdcp_load_keys_cb(hdcp);
if (ret)
@@ -95,10 +96,8 @@ static int rk_hdmirx_hdcp_load_key(struct rk_hdmirx_hdcp *hdcp)
hdmirx_hdcp_update_bits(hdcp, HDCP2_CONFIG,
HDCP2_CONNECTED |
HDCP2_SWITCH_OVR_VALUE |
HDCP2_SWITCH_OVR_EN,
HDCP2_CONNECTED |
HDCP2_SWITCH_OVR_EN);
HDCP2_SWITCH_OVR_VALUE,
HDCP2_CONNECTED);
return 0;
}
@@ -113,6 +112,9 @@ static int rk_hdmirx_hdcp1x_start(struct rk_hdmirx_hdcp *hdcp)
static int rk_hdmirx_hdcp1x_stop(struct rk_hdmirx_hdcp *hdcp)
{
if (hdcp->status == HDMIRX_HDCP_DISABLED)
return 0;
hdmirx_hdcp_update_bits(hdcp, GLOBAL_SWENABLE, HDCP_ENABLE, 0);
hdcp->status = HDMIRX_HDCP_DISABLED;
@@ -129,8 +131,8 @@ static int rk_hdmirx_hdcp2x_start(struct rk_hdmirx_hdcp *hdcp)
{
hdmirx_hdcp_update_bits(hdcp, HDCP2_CONFIG,
HDCP2_SWITCH_OVR_VALUE |
HDCP2_SWITCH_LCK,
HDCP2_SWITCH_OVR_VALUE |
HDCP2_SWITCH_LCK |
HDCP2_SWITCH_OVR_EN,
HDCP2_SWITCH_LCK);
if (hdcp->tx_5v_power(hdcp->hdmirx))
hdmirx_hdcp_write(hdcp, HDCP2_ESM_P0_GPIO_IN, 0x2);
@@ -141,13 +143,12 @@ static int rk_hdmirx_hdcp2x_start(struct rk_hdmirx_hdcp *hdcp)
static int rk_hdmirx_hdcp2x_stop(struct rk_hdmirx_hdcp *hdcp)
{
rk_hdmirx_hdcp2_hpd_config(hdcp, false);
hdmirx_hdcp_write(hdcp, HDCP2_ESM_P0_GPIO_IN, 0x0);
hdmirx_hdcp_update_bits(hdcp, HDCP2_CONFIG,
HDCP2_SWITCH_OVR_VALUE |
HDCP2_SWITCH_LCK, 0);
msleep(300);
rk_hdmirx_hdcp2_hpd_config(hdcp, true);
HDCP2_SWITCH_LCK |
HDCP2_SWITCH_OVR_EN,
HDCP2_SWITCH_OVR_EN);
return 0;
}
@@ -169,13 +170,15 @@ static void rk_hdmirx_hdcp2_connect_ctrl(struct rk_hdmirx_hdcp *hdcp, bool en)
static int rk_hdmirx_hdcp_start(struct rk_hdmirx_hdcp *hdcp)
{
if ((hdcp->hdcp_support & HDCP_2X_ENABLE) &&
hdcp->enable == HDCP_2X_ENABLE) {
if (hdcp->enable == HDCP_2X_ENABLE) {
rk_hdmirx_hdcp1x_start(hdcp);
rk_hdmirx_hdcp2x_start(hdcp);
return 0;
}
if ((hdcp->hdcp_support & HDCP_1X_ENABLE) &&
hdcp->enable == HDCP_1X_ENABLE)
hdmirx_hdcp_update_bits(hdcp, HDCP2_CONFIG,
HDCP2_SWITCH_OVR_EN,
HDCP2_SWITCH_OVR_EN);
if (hdcp->enable == HDCP_1X_ENABLE)
rk_hdmirx_hdcp1x_start(hdcp);
return 0;
@@ -183,18 +186,13 @@ static int rk_hdmirx_hdcp_start(struct rk_hdmirx_hdcp *hdcp)
static int rk_hdmirx_hdcp_stop(struct rk_hdmirx_hdcp *hdcp)
{
if ((hdcp->hdcp_support & HDCP_2X_ENABLE) &&
hdcp->enable == HDCP_2X_ENABLE) {
rk_hdmirx_hdcp2x_stop(hdcp);
dev_dbg(hdcp->dev, "hdcp2 stop\n");
}
if (!hdcp->enable)
return 0;
if ((hdcp->hdcp_support & HDCP_1X_ENABLE) &&
hdcp->enable == HDCP_1X_ENABLE) {
rk_hdmirx_hdcp1x_stop(hdcp);
dev_dbg(hdcp->dev, "hdcp1x stop\n");
}
hdcp->enable = 0;
if (hdcp->enable == HDCP_2X_ENABLE)
rk_hdmirx_hdcp2x_stop(hdcp);
rk_hdmirx_hdcp1x_stop(hdcp);
dev_dbg(hdcp->dev, "hdcp stop\n");
return 0;
}
@@ -215,7 +213,7 @@ static ssize_t enable_store(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
int enable, hdcp_support;
int enable;
struct rk_hdmirx_hdcp *hdcp = g_hdmirx_hdcp;
if (!hdcp)
@@ -224,31 +222,23 @@ static ssize_t enable_store(struct device *device,
if (kstrtoint(buf, 10, &enable))
return -EINVAL;
if (hdcp->hdcp_support & HDCP_2X_ENABLE)
hdcp_support = HDCP_2X_ENABLE;
else if (hdcp->hdcp_support & HDCP_1X_ENABLE)
hdcp_support = HDCP_1X_ENABLE;
else
hdcp_support = 0;
if (enable > hdcp_support)
if (enable > hdcp->hdcp_support)
return count;
if (hdcp->enable != enable) {
rk_hdmirx_hdcp2_hpd_config(hdcp, false);
if (enable == HDCP_2X_ENABLE) {
if (hdcp->enable == HDCP_1X_ENABLE)
rk_hdmirx_hdcp1x_stop(hdcp);
rk_hdmirx_hdcp1x_start(hdcp);
rk_hdmirx_hdcp2x_start(hdcp);
} else if (enable == HDCP_1X_ENABLE) {
if (hdcp->enable == HDCP_2X_ENABLE)
rk_hdmirx_hdcp2x_stop(hdcp);
rk_hdmirx_hdcp1x_start(hdcp);
} else {
if (hdcp->enable == HDCP_2X_ENABLE)
rk_hdmirx_hdcp2x_stop(hdcp);
if (hdcp->enable == HDCP_1X_ENABLE)
rk_hdmirx_hdcp1x_stop(hdcp);
rk_hdmirx_hdcp_stop(hdcp);
}
msleep(300);
rk_hdmirx_hdcp2_hpd_config(hdcp, true);
hdcp->enable = enable;
}
@@ -263,31 +253,27 @@ static ssize_t status_show(struct device *device,
int status = HDMIRX_HDCP_DISABLED;
struct rk_hdmirx_hdcp *hdcp = g_hdmirx_hdcp;
u32 val;
int n;
int dectypt, n = 0;
if (!hdcp)
return 0;
if (!hdcp->enable)
return snprintf(buf, PAGE_SIZE, "HDCP Disable\n");
if (hdcp->enable == HDCP_2X_ENABLE) {
val = hdmirx_hdcp_read(hdcp, HDCP2_STATUS);
n = snprintf(buf, PAGE_SIZE, "HDCP2:\n%s\n",
(val & BIT(0)) ? "Dectypted" : "No dectypted");
val = hdmirx_hdcp_read(hdcp, HDCP2_ESM_P0_GPIO_OUT);
if (val & BIT(0))
n += snprintf(buf + n, PAGE_SIZE - n, "Capable\n");
if (val & BIT(1))
n += snprintf(buf + n, PAGE_SIZE - n, "Not capable\n");
if (val & BIT(2))
n += snprintf(buf + n, PAGE_SIZE - n, "Authenticated success\n");
if (val & BIT(3))
n += snprintf(buf + n, PAGE_SIZE - n, "Authenticated failed\n");
if (val & BIT(4))
n += snprintf(buf + n, PAGE_SIZE - n, "Link Error\n");
if (val & BIT(7))
n += snprintf(buf + n, PAGE_SIZE - n, "AKE Init or SKE done\n");
return n;
dectypt = hdmirx_hdcp_read(hdcp, HDCP2_STATUS) & BIT(0);
if (dectypt) {
val = hdmirx_hdcp_read(hdcp, HDCP2_ESM_P0_GPIO_OUT);
if (val & BIT(2))
n += snprintf(buf + n, PAGE_SIZE - n,
"HDCP2.3: Authenticated success\n");
else
n += snprintf(buf + n, PAGE_SIZE - n,
"HDCP2.3: Authenticated failed\n");
return n;
}
n += snprintf(buf, PAGE_SIZE, "HDCP2.3: No dectypted\n");
}
status = hdcp->status;
@@ -302,16 +288,17 @@ static ssize_t status_show(struct device *device,
else
status = HDMIRX_HDCP_AUTH_FAIL;
}
if (status == HDMIRX_HDCP_DISABLED)
return snprintf(buf, PAGE_SIZE, "hdcp disable\n");
else if (status == HDMIRX_HDCP_AUTH_START)
return snprintf(buf, PAGE_SIZE, "hdcp_auth_start\n");
if (status == HDMIRX_HDCP_AUTH_START)
n += snprintf(buf + n, PAGE_SIZE, "HDCP1.4: Authenticated start\n");
else if (status == HDMIRX_HDCP_AUTH_SUCCESS)
return snprintf(buf, PAGE_SIZE, "hdcp_auth_success\n");
n += snprintf(buf + n, PAGE_SIZE, "HDCP1.4: Authenticated success\n");
else if (status == HDMIRX_HDCP_AUTH_FAIL)
return snprintf(buf, PAGE_SIZE, "hdcp_auth_fail\n");
n += snprintf(buf + n, PAGE_SIZE, "HDCP1.4: Authenticated failed\n");
else
return snprintf(buf, PAGE_SIZE, "unknown status\n");
n += snprintf(buf + n, PAGE_SIZE, "HDCP1.4: Unknown status\n");
return n;
}
static DEVICE_ATTR_RO(status);
@@ -345,7 +332,7 @@ struct rk_hdmirx_hdcp *rk_hdmirx_hdcp_register(struct rk_hdmirx_hdcp *hdcp_data)
hdcp->tx_5v_power = hdcp_data->tx_5v_power;
hdcp->hpd_config = hdcp_data->hpd_config;
hdcp->enable = hdcp_data->enable;
hdcp->hdcp_support = hdcp_data->hdcp_support;
hdcp->hdcp_support = hdcp_data->enable;
hdcp->dev = hdcp_data->dev;
g_hdmirx_hdcp = hdcp;
hdcp->mdev.minor = MISC_DYNAMIC_MINOR;