2022-11-15 07:06:03

by Hsin-Yi Wang

[permalink] [raw]
Subject: [PATCH v5 1/3] drm_bridge: register content protect property

Some bridges are able to update HDCP status from userspace request if
they support HDCP.

HDCP property is the same as other connector properties that needs to be
created after the connecter is initialized and before the connector is
registered.

If there exists a bridge that supports HDCP, add the property to the
bridge connector.

Signed-off-by: Hsin-Yi Wang <[email protected]>
Reviewed-by: Sean Paul <[email protected]>
Reported-by: kernel test robot <[email protected]>
---
v4->v5: fix compile warning when CONFIG_DRM_DISPLAY_HELPER=m
---
drivers/gpu/drm/drm_bridge_connector.c | 8 ++++++++
include/drm/drm_bridge.h | 4 ++++
2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c
index 1c7d936523df..16d038c2982f 100644
--- a/drivers/gpu/drm/drm_bridge_connector.c
+++ b/drivers/gpu/drm/drm_bridge_connector.c
@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/slab.h>

+#include <drm/display/drm_hdcp_helper.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
@@ -333,6 +334,7 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
struct i2c_adapter *ddc = NULL;
struct drm_bridge *bridge, *panel_bridge = NULL;
int connector_type;
+ bool support_hdcp = false;

bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL);
if (!bridge_connector)
@@ -376,6 +378,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,

if (drm_bridge_is_panel(bridge))
panel_bridge = bridge;
+
+ if (bridge->support_hdcp)
+ support_hdcp = true;
}

if (connector_type == DRM_MODE_CONNECTOR_Unknown) {
@@ -398,6 +403,9 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
if (panel_bridge)
drm_panel_bridge_set_orientation(connector, panel_bridge);

+ if (support_hdcp && IS_REACHABLE(CONFIG_DRM_DISPLAY_HDCP_HELPER))
+ drm_connector_attach_content_protection_property(connector, true);
+
return connector;
}
EXPORT_SYMBOL_GPL(drm_bridge_connector_init);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 6b65b0dfb4fb..1d2ab70f3436 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -768,6 +768,10 @@ struct drm_bridge {
* modes.
*/
bool interlace_allowed;
+ /**
+ * @support_hdcp: Indicate that the bridge supports HDCP.
+ */
+ bool support_hdcp;
/**
* @ddc: Associated I2C adapter for DDC access, if any.
*/
--
2.38.1.431.g37b22c650d-goog



2022-11-15 07:11:56

by Hsin-Yi Wang

[permalink] [raw]
Subject: [PATCH v5 2/3] drm/bridge: anx7625: register content protect property

Set support_hdcp so the connector can register content protect proterty
when it's initializing.

Signed-off-by: Hsin-Yi Wang <[email protected]>
Reviewed-by: Sean Paul <[email protected]>
---
v4->v5: no change
---
drivers/gpu/drm/bridge/analogix/anx7625.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index b0ff1ecb80a5..0636ac59c739 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -2680,6 +2680,7 @@ static int anx7625_i2c_probe(struct i2c_client *client,
platform->bridge.type = platform->pdata.panel_bridge ?
DRM_MODE_CONNECTOR_eDP :
DRM_MODE_CONNECTOR_DisplayPort;
+ platform->bridge.support_hdcp = true;

drm_bridge_add(&platform->bridge);

--
2.38.1.431.g37b22c650d-goog


2022-11-15 07:13:29

by Hsin-Yi Wang

[permalink] [raw]
Subject: [PATCH v5 3/3] drm/bridge: it6505: handle HDCP request

it6505 supports HDCP 1.3, but current implementation lacks the update of
HDCP status through drm_hdcp_update_content_protection(). it6505 default
enables the HDCP. If user set it to undesired then the driver will stop
HDCP.

Signed-off-by: Hsin-Yi Wang <[email protected]>
Reviewed-by: allen chen <[email protected]>
---
v4->v5: no change
---
drivers/gpu/drm/bridge/ite-it6505.c | 55 +++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
index 21a9b8422bda..be08b42de4ea 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -423,6 +423,7 @@ struct it6505 {
struct extcon_dev *extcon;
struct work_struct extcon_wq;
int extcon_state;
+ struct drm_connector *connector;
enum drm_connector_status connector_status;
enum link_train_status link_state;
struct work_struct link_works;
@@ -2399,6 +2400,14 @@ static void it6505_irq_hdcp_done(struct it6505 *it6505)

DRM_DEV_DEBUG_DRIVER(dev, "hdcp done interrupt");
it6505->hdcp_status = HDCP_AUTH_DONE;
+ if (it6505->connector) {
+ struct drm_device *drm_dev = it6505->connector->dev;
+
+ drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL);
+ drm_hdcp_update_content_protection(it6505->connector,
+ DRM_MODE_CONTENT_PROTECTION_ENABLED);
+ drm_modeset_unlock(&drm_dev->mode_config.connection_mutex);
+ }
it6505_show_hdcp_info(it6505);
}

@@ -2931,6 +2940,7 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,
if (WARN_ON(!connector))
return;

+ it6505->connector = connector;
conn_state = drm_atomic_get_new_connector_state(state, connector);

if (WARN_ON(!conn_state))
@@ -2974,6 +2984,7 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,

DRM_DEV_DEBUG_DRIVER(dev, "start");

+ it6505->connector = NULL;
if (it6505->powered) {
it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
DP_SET_POWER_D3);
@@ -3028,6 +3039,48 @@ static struct edid *it6505_bridge_get_edid(struct drm_bridge *bridge,
return edid;
}

+static int it6505_connector_atomic_check(struct it6505 *it6505,
+ struct drm_connector_state *state)
+{
+ struct device *dev = &it6505->client->dev;
+ int cp = state->content_protection;
+
+ DRM_DEV_DEBUG_DRIVER(dev, "hdcp connector state:%d, curr hdcp state:%d",
+ cp, it6505->hdcp_status);
+
+ if (!it6505->hdcp_desired) {
+ DRM_DEV_DEBUG_DRIVER(dev, "sink not support hdcp");
+ return 0;
+ }
+
+ if (it6505->hdcp_status == HDCP_AUTH_GOING)
+ return -EINVAL;
+
+ if (cp == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+ if (it6505->hdcp_status == HDCP_AUTH_DONE)
+ it6505_stop_hdcp(it6505);
+ } else if (cp == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+ if (it6505->hdcp_status == HDCP_AUTH_IDLE &&
+ it6505->link_state == LINK_OK)
+ it6505_start_hdcp(it6505);
+ } else {
+ DRM_DEV_DEBUG_DRIVER(dev, "invalid to set hdcp enabled");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int it6505_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ struct it6505 *it6505 = bridge_to_it6505(bridge);
+
+ return it6505_connector_atomic_check(it6505, conn_state);
+}
+
static const struct drm_bridge_funcs it6505_bridge_funcs = {
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -3035,6 +3088,7 @@ static const struct drm_bridge_funcs it6505_bridge_funcs = {
.attach = it6505_bridge_attach,
.detach = it6505_bridge_detach,
.mode_valid = it6505_bridge_mode_valid,
+ .atomic_check = it6505_bridge_atomic_check,
.atomic_enable = it6505_bridge_atomic_enable,
.atomic_disable = it6505_bridge_atomic_disable,
.atomic_pre_enable = it6505_bridge_atomic_pre_enable,
@@ -3354,6 +3408,7 @@ static int it6505_i2c_probe(struct i2c_client *client,
it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
DRM_BRIDGE_OP_HPD;
+ it6505->bridge.support_hdcp = true;
drm_bridge_add(&it6505->bridge);

return 0;
--
2.38.1.431.g37b22c650d-goog


2022-11-21 20:59:55

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v5 1/3] drm_bridge: register content protect property

Hi Hsin-Yi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on linus/master v6.1-rc6 next-20221121]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Hsin-Yi-Wang/drm_bridge-register-content-protect-property/20221115-143025
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20221115062835.3785083-1-hsinyi%40chromium.org
patch subject: [PATCH v5 1/3] drm_bridge: register content protect property
config: csky-randconfig-r031-20221121
compiler: csky-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/0eace8a112ea24be1b8f5a9fe390576e74947c93
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Hsin-Yi-Wang/drm_bridge-register-content-protect-property/20221115-143025
git checkout 0eace8a112ea24be1b8f5a9fe390576e74947c93
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=csky SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

csky-linux-ld: drivers/gpu/drm/drm_bridge_connector.o: in function `drm_bridge_connector_init':
drivers/gpu/drm/drm_bridge_connector.c:407: undefined reference to `drm_connector_attach_content_protection_property'
>> csky-linux-ld: drivers/gpu/drm/drm_bridge_connector.c:341: undefined reference to `drm_connector_attach_content_protection_property'

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.10 kB)
config (157.94 kB)
Download all attachments